×
单片机 > 单片机程序设计 > 详情

STM32学习笔记之DS18B20

发布时间:2020-08-26 发布时间:
|
我买得STM32开发小板儿上的外设实在少,连个数码管都没有,显示都得通过串口在超级终端上完成。我又特别懒,就挑了个比较方便的器件DS18B20来玩儿。

DS18B20应该说是学习嵌入式开发的入门级的器件,也是各种开发板的标准配置。因为它所需附加器件少(最多需要一个几K的电阻),而且操作简单方便(主要是IO口的控制时序),非常适合初学者练手。虽然之前学过8位机,但是却没有用8位机控制过DS18B20,心里一直感觉有些遗憾。现在趁着学32位机的机会好好研究研究它。

第一个要说的时GPIO口的配置问题。读写DS18B20要求GPIO是双向的,51单片机没有问题,但是STM32的GPIO口貌似是单向的,不过即使设置为输出口,也可以通过读取输入寄存器来获取管脚的电平高低,只不过其前提是输出的类型是OD输出,开漏输出。如果输出设置成推挽输出,当GPIO口输出高电平,由于单总线通过场效应管直接被VCC拉高,DS18B20无法将总线拉低。我查看了DS18B20的内部结构,好像DS18B20也是通过场效应管将输出低电平的。这样如果STM32输出高,DS18B20输出地,VCC和GND岂不是直接通过两个低阻的场效应管直接相连!我开始时就是这么干的,幸亏没有发生什么事。

当然将GPIO设置成开漏输出还不行,还要在单总线上接上拉电阻。我用的是4.3K(VCC3.3V)。我看到有的例程不停的变换端口的输入输出属性,有点麻烦,只是省了上拉电阻了。

第二个要说的是STM32的时序。在DS18B20的手册上初始化(复位)时序,读写时序等说得很详细。

       在复位时,低电平的持续时间至少480us,我选的是700us(480和960us的中间值,呵呵)。DS18B20在检测到上升沿之后,首先延时15-60us,在主动将总线拉低60-240us。这两个范围综合一下可以得到,DS18B20的有效举手信号最迟出现在上升沿之后60us,最早结束于上升沿之后75us(最早开始于上升沿之后15us,最迟结束于上升沿之后300us)。所以在60us和75us之间采集举手信号是最保守也是最稳妥的。我选的是65us。有一点要注意DS18B20有可能在上升沿之后300us之前还在忙着主动将总线拉低,所以在这段时间里最好不要开始发送ROM指令。刚开始我没有注意到这一点,但是恰巧,我在检测到举手信号后加了一句串口输出的语句。可能这句话正好为DS18B20结束拉低总线,准备接受指令赢得了时间。后来,我把那句串口输出语句删除了,结果读取的数据全都是高电平了。这就说明,一开始的ROM指令就没有响应,STM32 和DS18B20直接不合拍了,结果STM32读进来一堆毫无意义的高电平。直到我在读取举手指令之后加了个250us的延时,读取结果才又恢复正常了。

     另外一点是,每次读写操作的持续时间不能低于60us。特别是在读的时候,因为DS18B20的输出信号只在下降沿之后15us内有效,这样就很容易忽视60us的总持续时间。我在下降沿之后约13us读取总线电平,然后又延时了50us。这个50us的延时是必需的。没有的话,读入的数据就乱了,这是我实验验证的。

第三个要说的时CRC。

CRC实际算法并不复杂,步骤如下

1、首先判断移位寄存器最低位是否与输入的bit相同,这决定了异或门的输出。
2、如果异或门输出为1,则将移位寄存器右移一位,并将移位寄存器最高位置1即可。
3、如果异或门输出位0,首先将移位寄存器右移一位(隐含最高位清零),并且将相应的位取反。具体是哪几位
则由CRC多项式决定,如CRC=X8+X5+X4+1,则将第2和第3位取反(最低位位第0位)。

第四个要说的是一些小地方,如每个scratchpad读取之前必须加ROM指令。 



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析