[STM8] STM8S208驱动DHT11

[复制链接]
3827|24
 楼主| 冰封小肥牛 发表于 2017-10-3 12:37 | 显示全部楼层 |阅读模式
本帖最后由 冰封小肥牛 于 2017-10-3 12:37 编辑
  1. <div>自己做了一块板子,目的是使用STM8S208驱动DHT11温湿度传感器,但是现在的问题是DHT11复位之后,无法在MCU端口读取到DHT11的低电平响应,检查了很长一段时间也没发现啥问题,所有特来论坛请教</div><div><b>
  2. </b></div><div>
  3. </div><div>#include "DHT11.h"
  4. #include "delay.h"
  5. #include "iostm8s208c8.h"

  6. /*
  7. PB7设置位推挽输出模式
  8. */
  9. void DQ_out()
  10. {
  11.   PB_DDR_bit.DDR7 = 1;
  12.   PB_CR1_bit.C17 = 1;
  13.   PB_CR2_bit.C27 = 0;
  14. }


  15. /*
  16. PB7设置为浮空输入模式
  17. */
  18. void DQ_in()
  19. {
  20.   PB_DDR_bit.DDR7 = 0;
  21.   PB_CR1_bit.C17 = 0;
  22.   PB_CR2_bit.C27 = 0;
  23. }


  24. /*
  25. DHT11起始信号
  26. */
  27. void DHT11_start(void)
  28. {
  29.   DQ_out();                          //PB7设置为输出模式
  30.   PB_ODR_bit.ODR7 = 0;              //拉低PB7
  31.   delay_ms(18);                    //延时18ms
  32.   PB_ODR_bit.ODR7 = 1;            //拉高延时30us
  33.   delay_us(30);
  34.   
  35. }


  36. /*DHT11响应函数
  37. 返回1:接受失败
  38. 返回0:成功
  39. */
  40. u8 DHT11_check()
  41. {
  42.   u8 retry = 0;
  43.   DQ_in();                              //PB7设置为浮空输入模式
  44.   while(PB_IDR_bit.IDR7 && retry<100)   //在此等待DHT11拉低总线电平
  45.   {
  46.     retry++;
  47.     delay_us(1);
  48.   }
  49.   if(retry>=100) return 1;
  50.   else retry = 0;
  51.   while(!PB_IDR_bit.IDR7 && retry<100)  //等待DHT11拉高总线电平
  52.   {
  53.     retry++;
  54.     delay_us(1);
  55.   }
  56.   if(retry>=100) return 1;
  57.   return 0;
  58. }

  59. /*DHT11读取一个位*/
  60. u8 DHT11_read_bit()
  61. {
  62.   u8 retry = 0;
  63.   while(PB_IDR_bit.IDR7 && retry<100)
  64.   {
  65.     retry++;
  66.     delay_us(1);
  67.   }
  68.   retry = 0;
  69.   while(!PB_IDR_bit.IDR7 && retry<100)
  70.   {
  71.     retry++;
  72.     delay_us(1);
  73.   }
  74.   delay_us(40);
  75.   if(PB_IDR_bit.IDR7)return 1;
  76.   else return 0;
  77. }

  78. /*DHT11读取一个字节*/
  79. u8 DHT11_read_byte()
  80. {
  81.   u8 dat = 0;
  82.   u8 i;
  83.   for(i=0;i<8;i++)
  84.   {
  85.     dat<<=1;
  86.     dat |= DHT11_read_bit();
  87.   }
  88.   return dat;
  89. }</div>

CAN.rar

338.23 KB, 下载次数: 7

程序代码,编译环境IAR

一路向北lm 发表于 2017-10-3 14:45 | 显示全部楼层
这代码是楼主自己编写的还是参考人家的修改的?
 楼主| 冰封小肥牛 发表于 2017-10-3 15:42 | 显示全部楼层
一路向北lm 发表于 2017-10-3 14:45
这代码是楼主自己编写的还是参考人家的修改的?

前面的起始函数都是我自己编写的,读取的是参照的
捉虫天师 发表于 2017-10-3 20:24 来自手机 | 显示全部楼层
//复位DHT11 void DHT11_RST() {      TIM4_CR1 = 0x00;                      //关闭定时器    TIM4_CNTR = 0;                        //保证下次的第一个数据位的准确    DATA_SET;                              //ODR设置为1    DATA_OUT();                            //推挽输出模式,此时输出高电平    DATA_CLR;                                //此时处于主机输出模式,总线拉低    TIM2_Delayus(20000);                     //拉低20毫秒     DATA_SET;                                //释放总线     TIM2_Delayus(40);                     //释放总线以后等待40微秒DHT会发出响应信号 }
捉虫天师 发表于 2017-10-3 20:24 来自手机 | 显示全部楼层
//检测DHT11是否响应 uchar DHT11_CHECK() {      if(!DATA_GET)                       //如果顺利拉低,就说明有了响应   {   while((!DATA_GET)&&(outline<100))                    //先是低电平   {   TIM2_Delayus(1);   }   if(outline>90)                                       //起始信号超时退出   return 0;   outline = 0;   while((DATA_GET)&&(outline<100))                    //接着是高电平   {   TIM2_Delayus(1);   }   if(outline<90)   TIM4_CR1 = 0x81;                                    //立刻打开定时器开始计时第一个数据位   else   return 0;   DATA_IN();                                          //引脚设置为外部中断模式   outline = 0;            return 1;                                          //一切成功返回1      }   else   return 0;    }
捉虫天师 发表于 2017-10-3 20:25 来自手机 | 显示全部楼层
#pragma vector = 0x05                               //PA的中断向量位 __interrupt void GPIOA_IRQHandler() {    datatime = TIM4_CNTR;         //获取两次下降沿之间的数据宽度    TIM4_CNTR = 0;                //清零,再次获取下一位    datareg <<= 1;                //高位先出,左移操作    if((datatime>75)&&(datatime<85))           //数据0  我就默认高位开始获取了    datareg &= 0xfe;                            if((datatime>120)&&(datatime<130))         //数据1    datareg |= 0x01;                           if(datanum == 7)    dataall[0] = datareg;                        //获取第一个字节也就是湿度整数位    if(datanum == 23)                            //获取第三个字节也就是温度整数位    dataall[1] = datareg;    if(datanum == 39)                            //获取第五个字节也就是校验(温度+湿度)位    dataall[2] = datareg;    datanum++;                                 //每次读取一位进1    if(datanum >= 40)                          //数据接收完了结束    datanum = 0;     }
捉虫天师 发表于 2017-10-3 20:26 来自手机 | 显示全部楼层
网上找的不知道对不对
yiy 发表于 2017-10-3 22:38 | 显示全部楼层
看看几种IO的模式是不是有错,如果时序没错的情况下。
 楼主| 冰封小肥牛 发表于 2017-10-3 22:41 | 显示全部楼层
yiy 发表于 2017-10-3 22:38
看看几种IO的模式是不是有错,如果时序没错的情况下。

都正确的啊
huangcunxiake 发表于 2017-10-4 11:32 | 显示全部楼层
huangcunxiake 发表于 2017-10-4 11:34 | 显示全部楼层
huangcunxiake 发表于 2017-10-4 11:35 | 显示全部楼层
  1. STM8S [url=home.php?mod=space&uid=72445]@[/url] 16M 定时器定时5ms中断一次

  2. #define _G_DHT11

  3. #include "dht11.h"

  4. unsigned char uc_DHT11Value[SIZE];

  5. //全局变量 得到的温湿度值

  6. unsigned int ui_TempValue = 0;

  7. unsigned int ui_HumiValue = 0;

  8. extern unsigned char uc_20mstimeflag;

  9. /************************************************************* 函数名称:

  10. 函数功能:

  11. 入口参数:

  12. 入口参数的类型和含义:

  13. 出口参数:

  14. 备 注:

  15. *************************************************************/ unsigned char s_ComDHT11(void)

  16. {

  17. unsigned char i,temp,comdata;

  18. for(i = 8;i>0;i--)

  19. {

  20. while(!DHT11_DATA_VALUE);

  21. DHT11_Delay_10us();

  22. DHT11_Delay_10us();

  23. DHT11_Delay_10us();

  24. DHT11_Delay_10us();

  25. temp = 0;

  26. if(DHT11_DATA_VALUE)

  27. {

  28. temp =1;

  29. }

  30. comdata = comdata << 1;

  31. comdata = comdata|temp;

  32. while(DHT11_DATA_VALUE);

  33. }

  34. return comdata;

  35. }

  36. 函数名称:

  37. 函数功能:

  38. 入口参数:

  39. 入口参数的类型和含义:

  40. 出口参数:

  41. 备 注:

  42. *************************************************************/ void g_ReadTempAndHumi(void)

  43. {

  44. DHT11_DATA_OUT;

  45. DHT11_DATA_LOW;

  46. //layTime(40);// 至少18MS的延时,在中断计时里实现

  47. uc_20mstimeflag = 1;

  48. while(uc_20mstimeflag);

  49. DHT11_DATA_HIGH;

  50. DHT11_DATA_IN;

  51. DHT11_Delay_10us();

  52. DHT11_Delay_10us();

  53. DHT11_Delay_10us();

  54. while(!DHT11_DATA_VALUE); //80us的应答信号 DHT11 TO MCU while(DHT11_DATA_VALUE); //80us的通知信号 DHT11 TO MCU uc_DHT11Value[0] = s_ComDHT11();

  55. uc_DHT11Value[1] = s_ComDHT11();

  56. uc_DHT11Value[2] = s_ComDHT11();

  57. uc_DHT11Value[3] = s_ComDHT11();

  58. uc_DHT11Value[4] = s_ComDHT11();

  59. if((uc_DHT11Value[0] + uc_DHT11Value[1] + uc_DHT11Value[2] + uc_DHT11Value[3]) == uc_DHT11Value[4])

  60. {

  61. ui_HumiValue = uc_DHT11Value[0];

  62. ui_TempValue = uc_DHT11Value[2];

  63. }

  64. }

  65. 函数名称:

  66. 函数功能:

  67. 入口参数:

  68. 入口参数的类型和含义:

  69. 出口参数:

  70. 备 注:

  71. *************************************************************/ void DHT11_Delay_10us(void)

  72. {

  73. for(unsigned char uc_10us = 0;uc_10us < 34;uc_10us ++); }

  74. 头文件部分

  75. #ifndef __DHT11_H

  76. #define __DHT11_H

  77. #include "iostm8s105c6.h"

  78. #ifdef __cplusplus

  79. extern "C" {

  80. #endif

  81. #ifndef _G_DHT11

  82. #define DHT11_extern extern

  83. #else

  84. #define DHT11_extern

  85. #endif

  86. /**************宏定义****************/

  87. //#define DATA_DR PA_ODR_ODR6 //OUTPUT

  88. //#define DATA_SR PA_IDR_IDR6 //IN STATE

  89. #define DHT11_DATA_OUT PE_DDR_DDR3 = 1 //输出
 楼主| 冰封小肥牛 发表于 2017-10-4 16:05 | 显示全部楼层

问题已经搞定了,是一个小错误,还是谢谢各位
山东电子小菜鸟 发表于 2017-10-5 09:52 | 显示全部楼层
冰封小肥牛 发表于 2017-10-4 16:05
问题已经搞定了,是一个小错误,还是谢谢各位

 楼主| 冰封小肥牛 发表于 2017-10-5 11:28 | 显示全部楼层
gejigeji521 发表于 2017-10-5 11:49 | 显示全部楼层
就是断点问题?莫非你一直在调试模式搞的?没有全速跑一个看看?
menfiss 发表于 2017-10-5 17:16 来自手机 | 显示全部楼层
dht11需要一秒以上的稳定时间,不知设置没有?
一路向北lm 发表于 2017-10-5 17:27 | 显示全部楼层
冰封小肥牛 发表于 2017-10-3 15:42
前面的起始函数都是我自己编写的,读取的是参照的

原子的,野火都有代码直接用就行了。
 楼主| 冰封小肥牛 发表于 2017-10-9 15:16 | 显示全部楼层
gejigeji521 发表于 2017-10-5 11:49
就是断点问题?莫非你一直在调试模式搞的?没有全速跑一个看看?

是在调试模式,断点位置改了就没问题了,板子是自己设计的,当时没考虑周全没有显示设备
 楼主| 冰封小肥牛 发表于 2017-10-9 15:16 | 显示全部楼层
一路向北lm 发表于 2017-10-5 17:27
原子的,野火都有代码直接用就行了。

我现在是在STM8上,目前DHT11的读写没问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

201

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部