DS18B20温度传感器闪烁中断问题测试

九层妖塔 起于垒土

在这里插入图片描述


0.0测试背景

测试背景1:用DS18B20温度传感器测试温度时,显示装置无论选择数码管还是LCD等,显示装置均会出现闪烁的现象。
测试背景2:据说DS18B20对时序要求严格,那么在对DS18B20进行时序操作时是否需要关闭中断?


0.1测试环境

测试环境:
DS18B20:
在这里插入图片描述
MCU:STC15F2K60S2 ,晶振频率11.0592Mhz,波特率:9600bps

0.2观察方法

定时器动态扫描数码管显示:数码管处理函数放在死循环中,不控制数据刷新频率,即死循环每执行一次数码管处理函数就执行一次。
通过串口上位机显示数据波形,波特率:9600bps。串口发送函数1ms执行一次,即串口对温度数据的采样频率为1khz。



实验1、不关闭中断

 即在对DS18B20进行单总线数据通信时,不关闭所有中断。


实验1.1温度读取函数放在死循环中轮询执行

 即将温度读取函数rd_temperature放在死循环中,不控制读取频率。
实验现象:
 数码管亮度显示稳定,但是频繁出现奇异数据,由于奇异数据的频繁出现导致数码管出现闪动。
 串口数据:

 串口数据波形:
 注意左侧坐标,凡是出现肉眼可见的尖峰都可以理解为温度数据的奇异值,即错误数据。由于串口数据是1ms发送一次,横坐标的单位为ms。
在这里插入图片描述
实验结论:
 这是温度数据更新最快的,但是温度数据出现奇异值的概率比较大。


实验1.2控制温度读取函数执行频率400ms

 通过设置标志位,控制温度读取函数rd_temperature的执行频率,参考往届赛题,将温度数据的刷新频率设置为400ms。

实验现象:
 数码管亮度显示比较稳定,没有任何闪烁的出现。奇异值还是会出现,频率不低。
 串口数据波形:
在这里插入图片描述
实验结论:
 对比上一张波形图,可以得出,在相同时间奇异数据的出现频率降低了接近一倍,数码管的显示状态也可以接受。可以通过再减小温度数据的刷新频率,来减少奇异数据的出现,付出得代价是数码管显示温度得灵敏度降低了。



实验2、关闭中断

即在对DS18B20进行单总线数据通信时,关闭所有中断。


实验2.1温度读取函数放在死循环中轮询执行

 即将温度读取函数rd_temperature放在死循环中,不控制读取频率。

实验现象:
 数码管亮度显示不稳定,每个数码管轮流出现较暗的状态,总的来看四个数码管出现较大的闪动。完全没有奇异值的出现。

数码管出现“闪动”现象的原因分析:
  由于每次执行温度读取函数rd_temperature时都暂时关闭了中断,在执行完温度读取函数后再打开。然而,虽然单总线onewire的驱动函数中没有单个比较长时间的延时,但是在温度读取函数rd_temperature`中反复多次调用底层驱动,软件延时时间累计达到了6ms。 戳👉具体详情
又由于在执行温度读取函数时关闭了中断,6ms的时间内没有去刷新数码管,由于锁存器的存在,数码管维持在上一个状态,这就造成了每个数码管点亮的时间长短不一,宏观上也就是每个数码管的亮度不均匀且闪动。

 串口数据波形:
 注意左侧坐标,所有数值都在24.44到24.75之间,大部分在24.50到24.63之间,峰峰值为0.31。完全没有奇异值的出现,数据显示极其稳定。
在这里插入图片描述
实验结论:
 虽然上位机传回的数据极其稳定,没有奇异值。但是由于频繁关闭打开中断,造成数码管显示闪动,无法接受。


实验2.2控制温度读取函数执行频率400ms

 通过设置标志位,控制温度读取函数rd_temperature的执行频率,参考往届赛题,将温度数据的刷新频率设置为500ms。

实验现象:
 数码管亮度显示比较稳定,虽然控制了温度数据的刷新频率为500ms,但总归还是关闭了中断,数码管还是会出现轻微“闪烁”,轮流出现闪动。完全没有奇异值的出现。
 串口数据波形:
 注意左侧坐标,所有数值都在24.27到24.44之间,峰峰值为0.17。完全没有奇异值的出现,数据显示极其稳定。
在这里插入图片描述
实验结论:
 上位机传回的数据极其稳定,没有奇异值。数码管只有轻微闪动,显示效果良好。在接受范围之内。



实验3、不关闭中断+滤波

 即在对DS18B20进行单总线数据通信时,不关闭所有中断。并且对温度读取函数rd_temperature读回来的数据采取软件滤波,来消除奇异数据。


实验3.1温度读取函数放在死循环中轮询执行+限幅滤波

 即将温度读取函数rd_temperature放在死循环中,不控制读取频率。
实验现象:
 数码管亮度显示稳定,偶尔会发轻微闪动。偶尔出现奇异数据,不过奇异数据的峰值得到了较大的限制。
 串口数据波形:
 由于限幅滤波算法中的峰值限制在这儿选的是10,所以奇异数据偶尔出现并且限制在35以下。
在这里插入图片描述
实验结论:
 在不关闭中断的情况下,无论是数码管显示效果还是上位机的波形显示,都得到了较好的控制。
 弊端是,为了限制奇异数据,限幅滤波算法中的峰值限制选的是10,常温25,数据得显示范围被规定在15~35之间。在赛场上用手来升温必然没有问题,可不知道机器阅卷时会怎样。


实验3.2控制温度读取函数执行频率400ms + 限幅滤波

 通过设置标志位,控制温度读取函数rd_temperature的执行频率,参考往届赛题,兼顾数码管显示温度数据得灵敏度,将温度数据的刷新频率设置为400ms。

实验现象:
 数码管亮度显示极其稳定,没有任何闪烁的出现。奇异值在测试时没有出现,可见奇异值出现概率极低,但应该还是存在。

 串口数据波形:
 看不到尖峰脉冲的存在,峰峰值在0.1左右。
在这里插入图片描述
 补:不知道过了多长时间……还是会出现奇异数据,但是出现奇异值的峰值已经很小,出现的概率极低。
在这里插入图片描述

实验结论:
 在不关闭中断的情况下,无论是数码管显示效果还是上位机的波形显示,都得到了更好的控制。
 限幅滤波算法中的峰值限制选的是30,常温25,数据得显示范围被规定在-5~55之间。可测温范围更广。


实验3.3温度读取函数放在死循环中轮询执行+中位值平均滤波

 即将温度读取函数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);
}

DS18B20初始值消除方法更新

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;
}

完整工程0积分下载

滤波算法参考1
滤波算法参考2
  
  
  
  
彩 蛋

  • 15
    点赞
  • 5
    评论
  • 12
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

#法外狂徒张三

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者