微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 第51节:利用ADC0832采集电压信号进行滤波处理

第51节:利用ADC0832采集电压信号进行滤波处理

时间:11-22 来源:互联网 点击:

unsigned long ulTempFilterV=0; //参与换算的中间变量

unsigned long ulBackupFilterV=5000; //备份最新采样数据的中间变量

unsigned char ucSamplingCnt=0; //记录连续N次采样的计数器

unsigned long ulV=0; //未经滤波处理的实时电压值

unsigned long ulFilterV=0; //经过滤波后的实时电压值

//根据原理图得出的共阴数码管字模表

code unsigned char dig_table[]=

{

0x3f, //0 序号0

0x06, //1 序号1

0x5b, //2 序号2

0x4f, //3 序号3

0x66, //4 序号4

0x6d, //5 序号5

0x7d, //6 序号6

0x07, //7 序号7

0x7f, //8 序号8

0x6f, //9 序号9

0x00, //无 序号10

0x40, //- 序号11

0x73, //P 序号12

};

void main()

{

initial_myself();

delay_long(100);

initial_peripheral();

while(1)

{

ad_sampling_service(); //AD采样与处理的服务程序

display_service(); //显示的窗口菜单服务程序

}

}

void ad_sampling_service(void) //AD采样与处理的服务程序

{

unsigned char i;

ucAD=0; //AD值

ucCheckAD=0; //用来做校验对比的AD值

/* 片选信号置为低电平 */

adc0832_cs_dr = 0;

/* 第一个脉冲,开始位 */

adc0832_data_sr_dr = 1;

adc0832_clk_dr = 0;

delay_short(1);

adc0832_clk_dr = 1;

/* 第二个脉冲,选择通道 */

adc0832_data_sr_dr = 1;

adc0832_clk_dr = 0;

adc0832_clk_dr = 1;

/* 第三个脉冲,选择通道 */

adc0832_data_sr_dr = 0;

adc0832_clk_dr = 0;

adc0832_clk_dr = 1;

/* 数据线输出高电平 */

adc0832_data_sr_dr = 1;

delay_short(2);

/* 第一个下降沿 */

adc0832_clk_dr = 1;

adc0832_clk_dr = 0;

delay_short(1);

/* AD值开始送出 */

for (i = 0; i < 8; i++)

{

ucAD <= 1;

adc0832_clk_dr = 1;

adc0832_clk_dr = 0;

if (adc0832_data_sr_dr==1)

{

ucAD |= 0x01;

}

}

/* 用于校验的AD值开始送出 */

for (i = 0; i < 8; i++)

{

ucCheckAD >>= 1;

if (adc0832_data_sr_dr==1)

{

ucCheckAD |= 0x80;

}

adc0832_clk_dr = 1;

adc0832_clk_dr = 0;

}

/* 片选信号置为高电平 */

adc0832_cs_dr = 1;

if(ucCheckAD==ucAD) //检验相等

{

ulTemp=0; //把char类型数据赋值给long类型数据之前,必须先清零

ulTemp=ucAD; //把char类型数据赋值给long类型数据,参与乘除法运算的数据,为了避免运算结果溢出,我都用long类型

/* 注释一:

* 因为保留3为小数点,这里的5000代表5.000V。ulTemp/255代表分辨率.

* 有些书上说8位AD最高分辩可达到256级(0xff+1),我认为这种说法是错误的。

* 8位AD最高分辩应该是255级(0xff),所以这里除以255,而不是256.

*/

ulTemp=5000*ulTemp/255; //进行电压换算

ulV=ulTemp; //得到未经滤波处理的实时电压值

ucWd1Part1Update=1; //局部更新显示未经滤波处理的电压

/* 注释二:

* 以下连续判断N次一致性的滤波法,为了避免末尾小数点的数据偶尔跳动。

* 这种滤波方法的原理跟我在按键扫描中的去抖动原理是一模一样的,被我频繁

* 地应用在大量的工控项目中。

* 具体原理:当某个采样变量发生变化时,有两种可能,一种可能是外界的一个瞬间干扰。

* 另一种可能是变量确实发生变化。为了有效去除干扰,当发现变量有变化时,

* 我会连续采集N次,如果连续N次都是一致的结果,我才认为不是干扰。如果中间

* 只要出现一次不一致,我会马上把计数器清零,这一步是精华,很关键。

*

*/

if(ulTempFilterV!=ulTemp) //发现变量有变化

{

ucSamplingCnt++; //计数器累加

if(ucSamplingCnt>const_N) //如果连续N次都是一致的,则认为不是干扰。确实有数据需要更新显示。这里的const_N取值是8

{

ucSamplingCnt=0;

ulTempFilterV=ulTemp; //及时保存更新了的数据,方便下一次有新数据对比做准备

ulFilterV=ulTempFilterV; //得到经过滤波处理的实时电压值

ucWd1Part2Update=1; //局部更新显示经过滤波处理的电压

}

}

else

{

ucSamplingCnt=0; //只要出现一次不一致,我会马上把计数器清零,这一步是精华,很关键。

}

}

}

void display_service(void) //显示的窗口菜单服务程序

{

if(ucWd1Part1Update==1)//未经滤波处理的实时电压更新显示

{

ucWd1Part1Update=0;

ucTemp8=ulV%10000/1000; //显示电压值个位

ucTemp7=ulV%1000/100; //显示电压值小数点后第1位

ucTemp6=ulV%100/10; //显示电压值小数点后第2位

ucTemp5=ulV%10; //显示电压值小数点后第3位

ucDigShow8=ucTemp8; //数码管显示实际内容

ucDigShow7=ucTemp7;

ucDigShow6=ucTemp6;

ucDigShow5=ucTemp5;

}

if(ucWd1Part2Update==1)//经过滤波处理后的实时电压更新显示

{

ucWd1Part2Update=0;

ucTemp4=ulFilterV%10000/1000; //显示电压值个位

ucTemp3

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top