c语言平均值滤波程序,下位机_平均值滤波之-鬼斧神工算法(平均值滤波之经典形式改进)...

cb60a1361c3bed9d16beb6d428eb6a29.png

EN  : 调用使能位

bType :采样值类型,'W'=整型、'F'=浮点型、'D'(或其它)=长整型,参数类型:字节

wHi : 采样值高位字(采样值为整型是,实参必须为0),参数类型,2字节

wLo : 采样值低位字,参数类型,2字节

rDie : 滤波死区,参数类型:浮点数

rMaxErr : 最大允许偏差,参数类型:浮点数

rLen :滤波队列长度,参数类型:浮点数

出/入口参数:

rSum :累加和,参数类型:浮点数

rAve :滤波输出平均值,参数类型:浮点数

命令行:CALL   AveFilter, 'W', 0, SMW28, 640.0, 32000.0, 4.0, VD0, VD4

注意:本程序采样值是参数类型可适应的,用 wHi/wLo 的组合来适应整型、长整型、浮点型的参数类型输入,避免使用多个相同的子程序来适应不同类型的输入参数。由 bType 来指定输入的参数类型。

40bbff525065b16fd4eb31700f11052d.png

防脉冲干扰移动平均值法数字滤波器的C语言算法及其实现

在许多的数据采集系统中,现场的强电设备较多,不可避免地会产生尖脉冲干扰,这种干扰一般持续时间短,峰值大,对这样的数据进行数字滤波处理时,仅仅采用算术平均或移动平均滤波时,尽管对脉冲干扰进行了1/n的处理,但,其剩余值仍然较大。      这种场合最好的策略是:将被认为是受干扰的信号数据去掉,这就是防脉冲干扰平均值滤波法的原理。 防脉冲干扰平均值滤波法的算法是:对连续的n个数据进行排序,去掉其中最大和最小的2个数据,将剩余数据示平均值。

在一般8051单片机的应用中为了加快数据处理速度,n可以取值6。 而对于具有较快速度的处理器,则n值可以适当取大一些。但最好是 n=2^k+2, k为整数,因为这样在求平均值average=SUM/(n-2)=SUM/2^k时,可以写成average=SUM>>k,用移位的方法,可以加快处理速度。        上述算法显然还存在一个不足之处,就是每采集一个数据就要进行一次排序,这样会大量占用系统宝贵的时间。这可以通过存储当前数据中的最大值和最小值来改进。具体做法是:系统中用两个变量来存储当前n个数据的最大值和最小值在这个数组中的偏移量(也就是数组下标,存储数组下标而直接不存储数据本身是因为:在一般的系统中,n不会超无符号短整形的表示范围,因此用一个char形变量就可以存储了而如果直接存储数据本身,则许多情况下要用int形变量,甚至更长的类型)。这样只要在当前输入的数据将要覆盖的数据正好是当前的最大值或最小值时才在下个数组中查找最大值或最小值,而其他情况下则只要将输入的数据与最大值和最小值比较就可以修改下最大值和最小值了,而且不用进行数据排序。

这个算法很简单,下面是对应的C语言代码实现,可以很方便的应用的具体的51单片机或其他处理器上,只须做少量的修改。

#include"stdio.h"#define dtype unsigned int // 采集数据的数据类型#define uint8 char

#define LEN  6   //移动算术平均的个数+2=SHIFT<<2+2#define SHIFT 2   //2^SHIFT

uint8 pdata;    //移动指针uint8 pmax,pmin;   //记录数据表中最大值和最小值的位置,在一般的数据采集系统中,数据的长度>=8,因此用指针记录而不是直接记录最大值和最小值dtype datas[LEN];

dtype szlb(dtype _data){  /****************************//* 在调用此子程序前必须对 pdata,datas[]数组,  pmax,pmin进行初始化  *//****************************/

uint8 i; dtype average=0;  //清零,用来计算平均值 pdata=(pdata+1)%LEN; //指针下标在0到LEN-1上滑动 datas[pdata]=_data;  //采样所得数据存入数据表中 for(i=0;i

/*******去除被认为是脉冲的数据******/ if(_data>datas[pmax])      pmax=pdata;   //得到最大值的指针 else if(_datadatas[pmax])          pmax=i; } else if(pdata==pmin)//如果当前输入值将存入当前最大值的位置时 {      //由以上方法将不可行,必须从其他位置中查找极值     for(i=0;i

return (average>>SHIFT);    //求算术平均值}

/******以下是在VC++6.0环境下运行的测试程序**/

/***通过手动输入来模拟数据采集过程****/

void main(){ uint8 i; dtype _data; pdata=0; pmax=0; pmin=0; for(i=0;i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
均值滤波是一种简单的数字信号处理算法,其原理是将一段时间内的采样值取均值作为最终的输出值,从而减少噪声干扰。 下面是一个使用定时中断进行AD采样和均值滤波C语言程序: ```c #include <reg52.h> #include <intrins.h> #define MAX_SAMPLES 16 // 最大采样数 #define SAMPLE_RATE 1000 // 采样率 unsigned int samples[MAX_SAMPLES]; // 采样值数组 unsigned char sampleIndex = 0; // 当前采样值索引 unsigned int averageValue = 0; // 均值 void timer0Init() // 定时器0初始化函数 { TMOD |= 0x01; // 定时器0工作在模式1(16位定时器)下 TH0 = (65536 - (11059200 / 12 / SAMPLE_RATE)) / 256; // 计算定时器初值 TL0 = (65536 - (11059200 / 12 / SAMPLE_RATE)) % 256; ET0 = 1; // 允许定时器0中断 TR0 = 1; // 启动定时器0 EA = 1; // 允许中断 } void adcInit() // AD转换初始化函数 { ADC_CONTR = 0x80; // 打开ADC ADC_RES = 0; // 清零ADC结果寄存器 P1ASF = 0x01; // 将P1.0设为模拟输入口 } void main() { timer0Init(); adcInit(); while(1) { // 等待定时器0中断 } } void timer0Handler() interrupt 1 // 定时器0中断处理函数 { TH0 = (65536 - (11059200 / 12 / SAMPLE_RATE)) / 256; // 重新设置定时器初值 TL0 = (65536 - (11059200 / 12 / SAMPLE_RATE)) % 256; ADC_CONTR = 0x90; // 启动AD转换 while(ADC_CONTR & 0x10); // 等待AD转换完成 samples[sampleIndex++] = ADC_RES; // 将采样值存入数组 if(sampleIndex >= MAX_SAMPLES) // 如果采样值数组已满 { sampleIndex = 0; // 重置采样值索引 averageValue = 0; // 重置均值 for(int i = 0; i < MAX_SAMPLES; i++) // 计算均值 { averageValue += samples[i]; } averageValue /= MAX_SAMPLES; } } ``` 在以上程序中,我们使用定时器0的中断来触发AD采样和均值计算。定时器0的工作方式为模式1(16位定时器),定时器初值根据采样率计算得出。每当定时器0中断时,我们启动AD转换并等待转换完成,将采样值存入数组。当采样值数组已满时,我们重新计算均值并将采样值索引和均值重置。 需要注意的是,以上程序中的计算均值部分可以使用移位运算来优化,以提高程序效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值