CW32数字电压电流表软件教程-实验七:基本数据处理算法(均值滤波)
线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=∑f(x,y)/m,m为该模板中包含当前像素在内的像素总个数。在之前未加滤波函数时,数码管上显示的电压数据是不稳定、跳变的,而加了滤波函数之后,数码管显
均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=∑f(x,y)/m,m为该模板中包含当前像素在内的像素总个数。这本是数字图像处理的一种方法,但也可以用在我们数字电压电流表的ADC采样数据上。我们选取二十次的ADC采样值存储在数组 Volt_Buffer 中,然后去除掉数组中的最大值和最小值后再取平均,得到的值作为结果显示在数码管上,这样可以较大程度获得准确的、不易波动的数据。程序在实验五的基础上略作修改即可,首先是增加和修改变量:
#define ADC_SAMPLE_SIZE (20) //规定采样20个数据用来滤波
uint16_t Volt_Buffer[ADC_SAMPLE_SIZE]; //存储ADC转换值
uint32_t Led_Dis_Time; //计数,300ms改变一次数码管显示值
接下来是均值滤波的主体函数:
uint32_t Mean_Value_Filter(uint16_t *value, uint32_t size) //均值滤波
{
uint32_t sum = 0; //ADC采样数据和
uint16_t max = 0;
uint16_t min = 0xffff; //min初值取最大是为了将第一个数据记录
int i;
for(i = 0; i < size; i++)
{
sum += value[i];
if(value[i] > max)
{
max = value[i];
}
if(value[i] < min)
{
min = value[i];
}
}
sum -= max + min; //去除最大最小值
sum = sum / (size - 2);
return sum;
}
对之前的电压计算函数 Volt_Cal() 修改如下:
void Volt_Cal(void)
{
Cal_Buffer = Mean_Value_Filter(Volt_Buffer,ADC_SAMPLE_SIZE);
Cal_Buffer = (Cal_Buffer * ADC_REF_VALUE >> 12) * (R2 + R1)/R1;
// 四舍五入
if(Cal_Buffer % 10 >= 5)
{
Cal_Buffer = Cal_Buffer / 10 + 1;
}
else
{
Cal_Buffer = Cal_Buffer / 10;
}
}
在主函数的 while 循环里每隔300ms刷新一次:
while(1)
{
if(GetTick() >= (Led_Dis_Time + 300))
{
Led_Dis_Time = GetTick();
Volt_Cal();
Display(Cal_Buffer);
}
}
在之前未加滤波函数时,数码管上显示的电压数据是不稳定、跳变的,而加了滤波函数之后,数码管显示的电压数据可以稳定下来,并且有一定的抗干扰能力。至于电压准确性的问题,在后续章节的数据标定和校准中说明。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)