DHT11.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /************************************************************************
  2. * ---- 居加居 ----
  3. * 文件名: DHT11.c
  4. * 编写人员: Kinve JQ
  5. * 说明:
  6. * 版本: V0.1
  7. * 编写日期: 2018-09-30
  8. * 程序维护:
  9. * 维护记录:
  10. * 2018-09-30.Kinve:1.创建文件
  11. * 免责声明:
  12. * (c) Author Kinve JQ. All rights reserved.
  13. **************************************************************************/
  14. #include "DHT11.h"
  15. #define delay_ms(ms) Timer3_Delay1ms(ms)
  16. #define delay_us(us) Timer3_Delay1us(us) //{u8 i; for(i=0;i<us;i++) {nop;}}
  17. DHT11_Data_TypeDef DHT11_Data;
  18. //全局变量定义区
  19. //***************************************************************************/
  20. // //uchar i;
  21. // uchar U8FLAG,k;
  22. // uchar U8count,U8temp;
  23. // uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
  24. // uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
  25. // uchar U8comdata;
  26. // uint ReceiveHighByte;
  27. // uint ReceiveLowByte;
  28. //***************Global defination for DHT11 end****//
  29. void DHT11_PortIN ( void )
  30. {
  31. #if 0
  32. GPIO_InitTypeDef GPIO_InitStructure;
  33. RCC_APB2PeriphClockCmd ( DHT11_IORCC, ENABLE );
  34. //切换为输入口
  35. GPIO_InitStructure.GPIO_Pin = DHT11_DATA_PIN;
  36. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  37. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38. GPIO_Init ( DHT11_PORT, &GPIO_InitStructure );
  39. #endif
  40. }
  41. void DHT11_PortOUT ( void )
  42. {
  43. #if 0
  44. GPIO_InitTypeDef GPIO_InitStructure;
  45. RCC_APB2PeriphClockCmd ( DHT11_IORCC, ENABLE );
  46. GPIO_InitStructure.GPIO_Pin = ( DHT11_DATA_PIN );
  47. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
  48. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  49. GPIO_Init ( DHT11_PORT, &GPIO_InitStructure );
  50. #endif
  51. }
  52. /*
  53. 1.主机L >18ms
  54. 2.主机H 20-40us
  55. 3.DHT L 80us
  56. 4.DHT H 80us
  57. 5.DHT DATA....
  58. */
  59. static u8 _us = 0;
  60. unsigned char DHT11_Start ( void )
  61. {
  62. //主机开始信号
  63. /*
  64. 低18ms->高30us->等待dht响应(拉低)
  65. */
  66. DHT11_PortOUT();
  67. DHT11_Out = 0;
  68. delay_ms ( 20 ); //触发开始,总线拉低要大于18ms
  69. DHT11_Out = 1; //释放总线
  70. delay_us(30); //拉低 20-40uS 等待DHT11的低电平响应信号
  71. //dht响应
  72. /*
  73. 正确,拉低(80us) ->拉高(80us)->传送数据
  74. */
  75. DHT11_PortIN(); //改为输入
  76. #if 0
  77. //实际6
  78. _us = 0;
  79. while ( DHT11_In ) //低电平的响应信号,20-40uS
  80. {
  81. if ( ++_us > 40 )
  82. {
  83. return 0;
  84. }
  85. delay_us ( 1 );
  86. }
  87. #endif
  88. //实际53
  89. _us = 0;
  90. while ( !DHT11_In ) //低电平的响应信号,80us
  91. {
  92. if ( ++_us > 80 )
  93. {
  94. return 0;
  95. }
  96. delay_us ( 1 );
  97. }
  98. //实际54
  99. _us = 0;
  100. while ( DHT11_In ) //紧接着是80us的高电平数据准备信号
  101. {
  102. if ( ++_us > 80 )
  103. {
  104. return 0;
  105. }
  106. delay_us ( 1 );
  107. }
  108. //拉低后DHT11会拉高总线80us,接着会开始传数据
  109. return 1;
  110. }
  111. /*
  112. 传输数据:
  113. 1.一次8bit
  114. 2.
  115. 开始(50us 低)->
  116. 0: 26-28us 高+ (50us 低) = 80us
  117. 1: 70us 高+ (50us 低) = 120us
  118. 3.判断0/1,
  119. 1. 26-28us < n < 26-28us+50us
  120. 2. 0us < n < 70us
  121. 即,
  122. 延时35-40us,
  123. 高 = 1,是70us的,需要延时40us
  124. 低 = 0,是26-28us的
  125. */
  126. static uint8_t Read_Byte ( void )
  127. {
  128. u8 i, temp = 0xff;
  129. //开始必须是为低的50us 开始信号
  130. if ( !DHT11_In )
  131. {
  132. for ( i = 0; i < 8; i++ )
  133. {
  134. //等待高电平,消耗50us
  135. _us = 0;
  136. while ( !DHT11_In )
  137. {
  138. if ( ++_us > 50 )
  139. {
  140. return temp;
  141. }
  142. delay_us ( 1 );
  143. }
  144. //等待低电平,真实数据的结束
  145. _us = 0;
  146. while ( DHT11_In )
  147. {
  148. if ( ++_us > 80 )
  149. {
  150. return temp;
  151. }
  152. delay_us ( 1 );
  153. }
  154. if ( _us > 37 ) //35-40us后仍为高电平表示数据“1”
  155. {
  156. temp |= ( uint8_t ) ( 0x01 << ( 7 - i ) ); //把第7-i位置1
  157. }
  158. else //40us后为低电平表示数据“0”
  159. {
  160. temp &= ( uint8_t ) ~ ( 0x01 << ( 7 - i ) ); //把第7-i位置0
  161. }
  162. }
  163. }
  164. return temp;
  165. }
  166. uint8_t DHT11_Read_Data ( DHT11_Data_TypeDef *DHT11_Data )
  167. {
  168. uint8_t res;
  169. uint8_t check_sum;
  170. if ( DHT11_Start() ) //判断是否已经响应
  171. {
  172. /*开始接收数据*/
  173. DHT11_Data->humi_int = Read_Byte();
  174. DHT11_Data->humi_deci = Read_Byte();
  175. DHT11_Data->temp_int = Read_Byte();
  176. DHT11_Data->temp_deci = Read_Byte();
  177. DHT11_Data->check_sum = Read_Byte();
  178. check_sum = DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int + DHT11_Data->temp_deci;
  179. /*检查读取的数据是否正确*/
  180. if ( DHT11_Data->check_sum == check_sum )
  181. {
  182. res = SUCCESS;
  183. }
  184. else
  185. {
  186. res = ERROR;
  187. }
  188. }
  189. else
  190. {
  191. res = ERROR;
  192. }
  193. return res;
  194. }
  195. /********************* (C) COPYRIGHT Kinve JQ *******END OF FILE ********/