微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 第50节:利用ADC0832采集电压信号,用平均法和区间法进行软件滤

第50节:利用ADC0832采集电压信号,用平均法和区间法进行软件滤

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

标志

unsigned char ucTemp1=0; //中间过渡变量

unsigned char ucTemp2=0; //中间过渡变量

unsigned char ucTemp3=0; //中间过渡变量

unsigned char ucTemp4=0; //中间过渡变量

unsigned char ucTemp5=0; //中间过渡变量

unsigned char ucTemp6=0; //中间过渡变量

unsigned char ucTemp7=0; //中间过渡变量

unsigned char ucTemp8=0; //中间过渡变量

unsigned char ucAD=0; //AD值

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

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

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

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

unsigned char ucSamplingCnt=0; //统计采样的次数 本程序采样8次后求平均值

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; //局部更新显示未经滤波处理的电压

ulTempFilterV=ulTempFilterV+ulTemp; //累加8次后求平均值

ucSamplingCnt++; //统计已经采样累计的次数

if(ucSamplingCnt>=8)

{

/* 注释二:

* 求平均值滤波法,为了得到的数据更加圆滑,去除小毛刺。

* 向右边移动3位相当于除以8。

*/

ulTempFilterV=ulTempFilterV>>3; //求平均值滤波法

/* 注释三:

* 以下区间滤波法,为了避免末尾小数点的数据频繁跳动。

* 这里的20用于区间滤波法的正负偏差,这里的20代表0.020V。

* 意思是只要最近采集到的数据在正负0.020V偏差范围内,就不更新。

*/

if(ulBackupFilterV>=20) //最近备份的上一次数据大于等于0.02V的情况下

{

if(ulTempFilterV<(ulBackupFilterV-20)||ulTempFilterV>(ulBackupFilterV+20)) //在正负0.020V偏差范围外,更新

{

ulBackupFilterV=ulTempFilterV; //备份最新采样的数据,方便下一次对比判断

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

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

}

}

else //最近备份的上一次数据小于0.02V的情况下

{

if(ulTempFilterV>(ulBackupFilterV+20)) //在正0.020V偏差范围外,更新

{

ulBackupFilterV=ulTempFilterV; //备份最新采样的数据,方便下一次对比判断

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

ucWd1Part2Update=1;

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

网站地图

Top