zhong_zhiqi 发表于 2023-7-8 02:05:11

记录并分享通过DS18B20温度传感器实验中发现的两个知识点

在完成官方视频P173的内容后,通过实验发现了视频中示例代码中的两点问题,记录并分享如下,供大家参考讨论。

1- 视频最后阶段,讲师给大家提供了一个间歇采集温度数值的方法:
while(1)
{
                i++;
                if(i%50==0)
                        temp_value=ds18b20_read_temperture()*10;


就是增加一个变量“i”来记录循环的次数,在每隔50次循环时才采集一次温度。思路和方法都是好的,唯独忘记了在while循环里加一个重新给”i“复位归零的过程。讲师设计的”i“是u8类型,数据范围是0~255,按照讲师的示例代码while循环255次后变量”i“的取值就溢出了,此时”i“对应地址里的取值就完全不可控了,因此应该在while循环体最后加上“if(i==255) i=0;”才严谨。

2- 按照讲师示例代码编译后,将HEX文件下载到实验板执行时,不知大家是否发现,温度显示当前室温时,数码管会有规律的闪烁现象。并且讲师显然是没有检查过负温度的执行效果,如果将“temp_value=ds18b20_read_temperture()*10;”直接替换成“temp_value=-1234;”执行后数码管的“负号”会闪烁的非常厉害,可以达到影响观察的程度。

通常造成数码管闪烁的原因就是数码管的扫描频率偏低,低于人眼余辉效应的周期后就会给人闪烁的感觉。通过分析示例代码可以看出最后数码管扫描语句“smg_display(temp_buf,4);”就在while循环中,而整个循环中既包含了取温度值又包含了数码管显示数字的计算,显然这些过程带来的延时累计起来就显得太多了,以致最终产生了闪烁。

那么如何给while循环“减负”呢?我考虑了两个方面:
(1)- 取DS18B20温度值部分拿出去,不要放在while循环中。由于DS18B20默认的12位模式时需要750ms的转换时间,与其他1us的执行语句比起来周期太大了,放在while循环里浪费太多的CPU周期,拖慢CPU的执行效率。因此我的想法就是结合前面学习的时钟中断的内容,把取DS18B20温度值部分放到时钟中断去执行,由时钟中断去定期取一次温度值,CPU平时只要去扫描数码管就好了。

(2)- 取到温度值后是否每次都去计算一遍数码管的显示数组呢?如果相邻两次的温度是一样的,那temp_buf完全不需要重新计算一遍,继续延续原有值,等待下一次取温度值的结果好了。毕竟那一串取模的计算过程也是不小的负担。我的想法是增加一个变量记录前一次温度值,并且取得当前温度值后判断是否与前一次的温度值相同,如果相同就不做任何计算,不同才取重新计算一遍temp_buf的内容。

经过将这两个想法通过代码实现后,重新下载到实验板后发现闪烁感就没有了,而且负温度时的负号也没有强烈的闪烁感了,实验代码大家可以参考附件。

页: [1]
查看完整版本: 记录并分享通过DS18B20温度传感器实验中发现的两个知识点