📄 medina_filter.c
字号:
/***************************
信号采集(ADC)过程中的中值滤波最优算法
主要思想: 对于实时性要求较高的嵌入式系统,中值滤波在进行排序时要耗用很长的时间.
这里把总排序时间分散(分散到每一次循环中)为对某一个元素的插入排序,这样
处理后,在最后一次ADC转换结束后的极短时间内,就能得到中值滤波值
该程序主要就用于LPC21xx
****************************/
#define MEDIAN_LEN 9 //中值滤波的滤波长度,一般取奇数
#define MEDIAN 4 //中值在滤波数组中的位置
int buffer[MEDIAN_LEN]; //中值滤波的数据缓存
int medleng = 0; //一组中值滤波数据中,进入滤波缓存的数据个数
void medina_filter(int xad) //xad - ADC转换值
{
int i,xd;
//中值滤波
if(medleng == 0) //缓存的第1个元素,直接放入,不需要排序
{ buffer[0] = xad; medleng = 1; } //
else
{ //插入排序算法,按从小到大的顺序排列
for(i = 0; i < medleng; i ++)
{
if( buffer[i] > xad) // 轮询到的当前元素>AD值,则交换它们的值
{ xd = xad; xad = buffer[i]; buffer[i] = xd;}
}
buffer[medleng] = xad; //把轮询出的最大的数放入缓存的最后.
medleng++;
}
if(medleng >= MEDIAN_LEN) //ADC采样的数据个数达到中值滤波要求的数据个数
{
xd = buffer[MEDIAN]; //中值
medleng = 0;
/*
对中值滤波后的ADC采样值进行处理
*/
}
}
// ****************************************************************************
// 名称:read_ads8320(void)
// 功能:进行一次AD转换,并读取16位的转换结果
// ****************************************************************************
int read_ads8320(void)// ;进行一次AD转换,约25us
{ uint16 xi,xd;
IO0CLR = CS8320; // CS8320 = 0;
for(xi = 0; xi < 6; xi++) //6个转换脉冲
{
IO0CLR = CLK8320; //CLK8320 = 0;
Delay_us(50); //延时5us
IO0SET = CLK8320; //CLK8320 = 1;//上升沿
Delay_us(50); //延时5us
}
for(xd = 0, xi = 0; xi < 16; xi++) //读取16位转换结果
{
IO0CLR = CLK8320; //CLK8320 = 0;
Delay_us(50); //延时5us
xd = xd << 1; //左移一位,同时bit0位为0
IO0SET = CLK8320; //CLK8320 = 1;//上升沿
if((IO0PIN & DOUT8320) != 0) xd++; //数据线输出1
Delay_us(50);
}
IO0SET = CS8320; // CS8320 = 0;
return(xd);
}
// ****************************************************************************
// 主函数
// ****************************************************************************
void main(void)
{ int adc;
while(1)
{
adc = read_ads8320(); //读取ADC转换的结果
medina_filter(adc);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -