stm32解析dht11传感器1-wire协议

    要做个模块stm32带dht11温湿度传感器的。这个传感器使用的是1-wire协议,也就是数据传输只需要一根线就可以了。这个和ds18b20比较相似,但是比18b20要简单一些。因为他的单线数据都是从dht11发送到主机这边来的,主机不需要给它发数据。

    百度了一下,在网上大部分例程都是用的io加延时拉模拟他的时序实现的通信。我看到延时这样的函数就很不喜欢,因为我单片机加了还要做其他事情。加了延时就注定要牺牲掉做事儿的时间,导致效率低下。于是乎想到1-wire协议也是高低电平变化,通过判断高电平的时间长短来确定是0还是1,这和红外解码也类似。大部分红外解码用的就是pwm捕获功能来解的,那么这个1-wire协议应该也可以。于是就按这个思路做了下实验,果然可以。

   思路呢我是用了两个单片机io口接到dht11的数据线(一个也可以,但是就是程序上麻烦一点,需要变化io口的输入输出状态)。我用了两个io口那就是一个作为输入一个作为输出。这个输出就一个功能,就是给到dht11一个复位信号。这个信号拉低大于18ms再拉高dht11就会温湿度数据输出来,这时候用到的就是单片机的另一个输入口。当然这个输入口一定是要有pwm捕获功能的,我选择的是pa2,是tim15的通道1.

    如上图所示就是stm32cubeMx的配置。这里需要重点关注的就是tim15的配置。这里的psc的值是控制计时器的频率的,我这里设置的48-1是因为我的单片机主频设置的是48mhz,这样定时器就是1us记一次数。counter priod这个值则是控制定时器溢出值,也就是计数器记到这个值以后就会重新从0开始记。这个值一定要大于dht11一个数据周期的最大值。比如dht11的0是低50us+高(26-28us),1是低50us+高80us。所以配置的最小值肯定也不能低于130。我们只要把这个数据周期给检测出来,那么我们就知道接收到的是0还是1了。

   检测思路是这样的:

   我先用单片机的输出口拉低一个20ms的低电平,然后再把输出口输出为高。这时候定时器的计数器清0并打开pwm捕获,这个捕获功能是只能检测上升沿或者下降沿的,我选择检测下降沿。两次下降沿之间的值就是dht11的一个数据周期。判断这个数据周期长短就可以判断出来就收到的是0还是1.看下我串口打印出来的结果:

    一共受到41个数据,第一个数据10us是因为是复位信号,所以不算数据,后面的1-41才是真正的dht11数据。可以看到74-76就可以判断为数据0 ,121就是代表数字1了。然后用在中断里面把这些0和1进行解析就可以的到完整的数据。

这是我的中断处理代码:

还有我的main函数:

  

    

您可能还喜欢...

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注