测试背景1:用DS18B20温度传感器测试温度时,显示装置无论选择数码管还是LCD等,显示装置均会出现闪烁的现象。
测试背景2:据说DS18B20对时序要求严格,那么在对DS18B20进行时序操作时是否需要关闭中断?
测试环境:
DS18B20:
MCU:STC15F2K60S2 ,晶振频率11.0592Mhz,波特率:9600bps
定时器动态扫描数码管显示:数码管处理函数放在死循环中,不控制数据刷新频率,即死循环每执行一次数码管处理函数就执行一次。
通过串口上位机显示数据波形,波特率:9600bps。串口发送函数1ms执行一次,即串口对温度数据的采样频率为1khz。
?即在对DS18B20进行单总线数据通信时,不关闭所有中断。
?即将温度读取函数rd_temperature
放在死循环中,不控制读取频率。
实验现象:
?数码管亮度显示稳定,但是频繁出现奇异数据,由于奇异数据的频繁出现导致数码管出现闪动。
?串口数据:
?串口数据波形:
?注意左侧坐标,凡是出现肉眼可见的尖峰都可以理解为温度数据的奇异值,即错误数据。由于串口数据是1ms发送一次,横坐标的单位为ms。
实验结论:
?这是温度数据更新最快的,但是温度数据出现奇异值的概率比较大。
?通过设置标志位,控制温度读取函数rd_temperature
的执行频率,参考往届赛题,将温度数据的刷新频率设置为400ms。
实验现象:
?数码管亮度显示比较稳定,没有任何闪烁的出现。奇异值还是会出现,频率不低。
?串口数据波形:
实验结论:
?对比上一张波形图,可以得出,在相同时间奇异数据的出现频率降低了接近一倍,数码管的显示状态也可以接受。可以通过再减小温度数据的刷新频率,来减少奇异数据的出现,付出得代价是数码管显示温度得灵敏度降低了。
即在对DS18B20进行单总线数据通信时,关闭所有中断。
?即将温度读取函数rd_temperature
放在死循环中,不控制读取频率。
实验现象:
?数码管亮度显示不稳定,每个数码管轮流出现较暗的状态,总的来看四个数码管出现较大的闪动。完全没有奇异值的出现。
?数码管出现“闪动”现象的原因分析:
??由于每次执行温度读取函数rd_temperature
时都暂时关闭了中断,在执行完温度读取函数后再打开。然而,虽然单总线onewire
的驱动函数中没有单个比较长时间的延时,但是在温度读取函数
rd_temperature`中反复多次调用底层驱动,软件延时时间累计达到了6ms。 戳👉具体详情。
又由于在执行温度读取函数时关闭了中断,6ms的时间内没有去刷新数码管,由于锁存器的存在,数码管维持在上一个状态,这就造成了每个数码管点亮的时间长短不一,宏观上也就是每个数码管的亮度不均匀且闪动。
?串口数据波形:
?注意左侧坐标,所有数值都在24.44到24.75之间,大部分在24.50到24.63之间,峰峰值为0.31。完全没有奇异值的出现,数据显示极其稳定。
实验结论:
?虽然上位机传回的数据极其稳定,没有奇异值。但是由于频繁关闭打开中断,造成数码管显示闪动,无法接受。
?通过设置标志位,控制温度读取函数rd_temperature
的执行频率,参考往届赛题,将温度数据的刷新频率设置为500ms。
实验现象:
?数码管亮度显示比较稳定,虽然控制了温度数据的刷新频率为500ms,但总归还是关闭了中断,数码管还是会出现轻微“闪烁”,轮流出现闪动。完全没有奇异值的出现。
?串口数据波形:
?注意左侧坐标,所有数值都在24.27到24.44之间,峰峰值为0.17。完全没有奇异值的出现,数据显示极其稳定。
实验结论:
?上位机传回的数据极其稳定,没有奇异值。数码管只有轻微闪动,显示效果良好。在接受范围之内。
?即在对DS18B20进行单总线数据通信时,不关闭所有中断。并且对温度读取函数rd_temperature
读回来的数据采取软件滤波,来消除奇异数据。
?即将温度读取函数rd_temperature
放在死循环中,不控制读取频率。
实验现象:
?数码管亮度显示稳定,偶尔会发轻微闪动。偶尔出现奇异数据,不过奇异数据的峰值得到了较大的限制。
?串口数据波形:
?由于限幅滤波算法中的峰值限制在这儿选的是10,所以奇异数据偶尔出现并且限制在35以下。
实验结论:
?在不关闭中断的情况下,无论是数码管显示效果还是上位机的波形显示,都得到了较好的控制。
?弊端是,为了限制奇异数据,限幅滤波算法中的峰值限制选的是10,常温25,数据得显示范围被规定在15~35之间。在赛场上用手来升温必然没有问题,可不知道机器阅卷时会怎样。
?通过设置标志位,控制温度读取函数rd_temperature
的执行频率,参考往届赛题,兼顾数码管显示温度数据得灵敏度,将温度数据的刷新频率设置为400ms。
实验现象:
?数码管亮度显示极其稳定,没有任何闪烁的出现。奇异值在测试时没有出现,可见奇异值出现概率极低,但应该还是存在。
?串口数据波形:
?看不到尖峰脉冲的存在,峰峰值在0.1左右。
?补:不知道过了多长时间……还是会出现奇异数据,但是出现奇异值的峰值已经很小,出现的概率极低。
实验结论:
?在不关闭中断的情况下,无论是数码管显示效果还是上位机的波形显示,都得到了更好的控制。
?限幅滤波算法中的峰值限制选的是30,常温25,数据得显示范围被规定在-5~55之间。可测温范围更广。
?即将温度读取函数rd_temperature
放在死循环中,不控制读取频率。
实验现象:
?即使不控制温度读取函数和数码管的刷新频率,数码管亮度显示极其稳定,无任何闪烁闪动。没有任何奇异数据。
?串口数据波形:
?长时间测试结果依旧。波形稳定。外界温度稳定时,温度在0.07范围内波动。
实验结论:
?在不关闭中断的情况下,无论是数码管显示效果还是上位机的波形显示,都得到了目前最好的控制。
?并且中位值平均滤波不存在限幅滤波算法对温度范围的限制。
?DS18B20对时序要求严格,中断打断了正在进行通过单总线传输的数据,造成了通信误差。
?个人建议:不关闭中断。一是为了数码管显示,二是如果关闭中断,温度读取函数就相当于6ms的延时,会降低按键的灵敏度。
?不关闭中断,并采用中位值平均滤波法。目前已知最好的方法。
?蓝桥杯比赛时,为节约时间可先采用 不关闭中断+控制温度读取函数执行频率。执行频率或者叫做刷新频率控制在400ms或500ms均可。但是这种方法还是有一定概率出现奇异数据,造成数码管偶尔闪动。
?虽然限幅滤波算法简单易记代码量少,但是毕竟评分时是机器阅卷,不知道测试温度环境是多少,所以不推荐使用。
?比赛时如果时间充足,推荐使用 不关闭中断+控制温度读取函数执行频率+中位值平均滤波。
?按键消抖算法三行代码竟是 消抖滤波法。
?DS18B20温度传感器是一阶传感器。和RC回路充放电曲线相同。👇
限幅滤波法
/********************************************************
Amplitude_Filter()-限幅滤波法
优点:能有效克服因偶然因素引起的脉冲干扰
缺点:无法抑制那种周期性的干扰,且平滑度差
说明:
1、形参 取得当前值
2、变量说明
Old_Value:最近一次有效采样的值,该变量为静态局部变量
New_Value:当前采样的值
Return_Value:返回值
3、常量说明
A:两次采样的最大误差值,该值需要使用者根据实际情况设置
入口:Old_Value,上一次有效的采样值,形参赋值
出口:Return_Value,返回值,本次滤波结果
********************************************************/
//#define A 50
float Amplitude_Filter(float Value)
{
float New_Value = 0;
static float Old_Value = 25; //为提高滤波效果,可根据实际测温情况进行赋值
float Return_Value = 0;
New_Value = Value;
if( ((New_Value-Old_Value)>A) || ((Old_Value-New_Value)>A) )
Return_Value=Old_Value;
else
{
Return_Value=New_Value;
Old_Value = New_Value;
}
return(Return_Value);
}
中位值平均滤波法
/********************************************
中位值平均滤波法(又称防脉冲干扰平均滤波法)
说明:采一组队列去掉最大值和最小值,相当于“中位值滤波法”+“算术平均滤波法”。
优点:融合了两种滤波的优点。对于偶然出现的脉冲性干扰,可消
除有其引起的采样值偏差。对周期干扰有良好的抑制作用,
平滑度高,适于高频振荡的系统。
缺点:测量速度慢
*********************************************/
//#define N 12
float Median_Average_Filter(float Value)
{
static unsigned char num = 0;
unsigned char i,j;
float temp=0,sum=0,value=25;
static float xdata value_buf[N]={25.0,25.0,25.0,25.0,25.0,25.0,25.0,25.0,25.0,25.0,25.0,25.0}; //存放采样数据的数组
if(num++ == N) num = 0;
value_buf[num] = Value;
//采样值从小到大排列(冒泡法)
for(j=0;j<N-1;j++) //遍历整个数组
{
for(i=0;i<N-j;i++)
{
if(value_buf[i]>value_buf[i+1])
{
temp = value_buf[i];
value_buf[i] = value_buf[i+1];
value_buf[i+1] = temp;
}
}
}
for(i=1;i<N-1;i++)
sum += value_buf[i];
value = sum/(N-2);
return(value);
}
uchar puc_SEG_Code[8]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
void main(void)
{
Init();
Timer1Init();
UartInit();
temperature = rd_temperature()/16.0;
while(temperature == 85.0)
{
temperature = rd_temperature()/16.0;
}
//最后开中断
ET1 = 1;
EA = 1;
while(1)
{
……
……
void temperature_Proc(void)
{
if(uc_temp_Flag) return;
uc_temp_Flag = 1;
//EA = 0;
temperature = rd_temperature()/16.0;
//temperature = Amplitude_Filter(temperature); //限幅滤波法
temperature = Median_Average_Filter(temperature);//中位值平均滤波法
//EA = 1;
}
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...