当前位置:   article > 正文

STM32F103ZET6——DHT11温湿度传感器(hal库)_3引脚dht11

3引脚dht11

一、CubeMX配置

(1)调试接口配置

        如下图进行调试接口配置,将调试接口设置成SW模式,占用芯片PA13、PA14两个引脚

(2)时钟配置

        如下图分别进行外部高速时钟HSE和时钟树的配置,设置HCLK为72MHz(最高72MHz,也可以配置其他),其配置图如图所示

(3)GPIO配置

        DHT11只有三个引脚VCC——3.3V,GND——GND,数据传输引脚——PA1,这里将PA1设置为输出模式

(4)定时器TIM配置

        这里选择TIM2,设置定时器为内部时钟,由于TIM2的内部时钟CK_INT来自于外设总线APB1提供的定时时钟TIMx_CLK(72MHz),所以经过(72-1)的预分频后刚好是1MHz,也就是1us,后续会在cube中生成的tim.c文件中由程序实现延时函数

(5)USART串口配置

        为了验证程序的可行性,我们利用串口将程序的结果传输到电脑上,这里选择异步模式,串口波特率为115200Bits/s,其USART配置如图所示

(6)

二、程序修改部分

(1)tim.c

  1. /* USER CODE BEGIN 1 */
  2. void delay_us(uint16_t us)
  3. {
  4. uint16_t differ = 0xffff-us-5;
  5. __HAL_TIM_SET_COUNTER(&htim2,differ);
  6. HAL_TIM_Base_Start(&htim2);
  7. while(differ < 0xffff-5)
  8. {
  9. differ = __HAL_TIM_GET_COUNTER(&htim2);
  10. }
  11. HAL_TIM_Base_Stop(&htim2);
  12. }
  13. void Delay_us(uint16_t myus)//基于TIM3定时器的μs延时函数
  14. {
  15. uint16_t differ = 0xffff-myus-5;
  16. HAL_TIM_Base_Start(&htim2);
  17. while(differ < 0xffff-5)
  18. {
  19. differ = __HAL_TIM_GET_COUNTER(&htim2);
  20. }
  21. HAL_TIM_Base_Stop(&htim2);
  22. }
  23. /* USER CODE END 1 */

 (2)tim.h

  1. /* USER CODE BEGIN Includes */
  2. void delay_us(uint16_t us);
  3. void Delay_us(uint16_t myus);
  4. /* USER CODE END Includes */

(3)DHT11驱动文件

dht11.c

  1. #include "dht11.h"
  2. #include "tim.h"
  3. void DHT11_IO_IN(void)
  4. {
  5. GPIO_InitTypeDef GPIO_InitStructure;
  6. GPIO_InitStructure.Pin = GPIO_PIN_1;
  7. GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  8. HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
  9. }
  10. void DHT11_IO_OUT(void)
  11. {
  12. GPIO_InitTypeDef GPIO_InitStructure;
  13. GPIO_InitStructure.Pin = GPIO_PIN_1;
  14. GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  15. GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
  16. HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
  17. }
  18. //复位DHT11
  19. void DHT11_Rst(void)
  20. {
  21. DHT11_IO_OUT(); //设置为输出
  22. DHT11_DQ_OUT_LOW; //拉低DQ
  23. HAL_Delay(20); //拉低至少18ms
  24. DHT11_DQ_OUT_HIGH; //DQ=1
  25. delay_us(30); //主机拉高20~40us
  26. }
  27. //等待DHT11的回应
  28. //返回1:未检测到DHT11的存在
  29. //返回0:存在
  30. uint8_t DHT11_Check(void)
  31. {
  32. uint8_t retry=0;
  33. DHT11_IO_IN(); //设置为输出
  34. while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
  35. {
  36. retry++;
  37. delay_us(1);
  38. };
  39. if(retry>=100)return 1;
  40. else retry=0;
  41. while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
  42. {
  43. retry++;
  44. delay_us(1);
  45. };
  46. if(retry>=100)return 1;
  47. return 0;
  48. }
  49. //从DHT11读取一个位
  50. //返回值:1/0
  51. uint8_t DHT11_Read_Bit(void)
  52. {
  53. uint8_t retry=0;
  54. while(DHT11_DQ_IN&&retry<100)//等待变为低电平
  55. {
  56. retry++;
  57. delay_us(1);
  58. }
  59. retry=0;
  60. while(!DHT11_DQ_IN&&retry<100)//等待变高电平
  61. {
  62. retry++;
  63. delay_us(1);
  64. }
  65. delay_us(40);//等待40us
  66. if(DHT11_DQ_IN)return 1;
  67. else return 0;
  68. }
  69. //从DHT11读取一个字节
  70. //返回值:读到的数据
  71. uint8_t DHT11_Read_Byte(void)
  72. {
  73. uint8_t i,dat;
  74. dat=0;
  75. for (i=0;i<8;i++)
  76. {
  77. dat<<=1;
  78. dat|=DHT11_Read_Bit();
  79. }
  80. return dat;
  81. }
  82. //从DHT11读取一次数据
  83. //temp:温度值(范围:0~50°)
  84. //humi:湿度值(范围:20%~90%)
  85. //返回值:0,正常;1,读取失败
  86. uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi)
  87. {
  88. uint8_t buf[5];
  89. uint8_t i;
  90. DHT11_Rst();
  91. if(DHT11_Check()==0)
  92. {
  93. for(i=0;i<5;i++)//读取40位数据
  94. {
  95. buf[i]=DHT11_Read_Byte();
  96. }
  97. if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
  98. {
  99. *humi=(buf[0]<<8) + buf[1];
  100. *temp=(buf[2]<<8) + buf[3];
  101. }
  102. }else return 1;
  103. return 0;
  104. }
  105. //初始化DHT11的IO口 DQ 同时检测DHT11的存在
  106. //返回1:不存在
  107. //返回0:存在
  108. uint8_t DHT11_Init(void)
  109. {
  110. DHT11_Rst();
  111. return DHT11_Check();
  112. }

dht11.h

  1. #ifndef __DHT11_H__
  2. #define __DHT11_H__
  3. #include "main.h"
  4. #define DHT11_DQ_OUT_HIGH HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET)
  5. #define DHT11_DQ_OUT_LOW HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET)
  6. #define DHT11_DQ_IN HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)
  7. //IO方向设置
  8. void DS18B20_IO_IN(void);
  9. void DS18B20_IO_OUT(void);
  10. uint8_t DHT11_Init(void);//初始化DHT11
  11. uint8_t DHT11_Read_Data(uint16_t *temp,uint16_t *humi);//读取温湿度
  12. uint8_t DHT11_Read_Byte(void);//读出一个字节
  13. uint8_t DHT11_Read_Bit(void);//读出一个位
  14. uint8_t DHT11_Check(void);//检测是否存在DHT11
  15. void DHT11_Rst(void);//复位DHT11
  16. #endif

(4)在main.c中声明

  1. /* USER CODE BEGIN Includes */
  2. #include "stdio.h"
  3. #include "dht11.h"
  4. /* USER CODE END Includes */

串口重定向函数

  1. /* USER CODE BEGIN PV */
  2. int fputc(int ch,FILE *f)
  3. {
  4. HAL_UART_Transmit(&huart1,(uint8_t *) &ch,1,HAL_MAX_DELAY);
  5. return ch;
  6. }
  7. int fgetc(FILE *f)
  8. {
  9. uint8_t ch;
  10. HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
  11. return ch;
  12. }
  13. /* USER CODE END PV */

变量定义

  1. /* USER CODE BEGIN PD */
  2. uint16_t temperature;
  3. uint16_t humidity;
  4. /* USER CODE END PD */

主函数

  1. /* USER CODE BEGIN 2 */
  2. while(DHT11_Init())
  3. {
  4. printf("DHT11 Checked failed!!!\r\n");
  5. HAL_Delay(500);
  6. }
  7. printf("DHT11 Checked Sucess!!!\r\n");
  8. /* USER CODE END 2 */

while中

  1. while (1)
  2. {
  3. /* USER CODE END WHILE */
  4. /* USER CODE BEGIN 3 */
  5. DHT11_Read_Data(&temperature,&humidity);
  6. printf("DHT11 Temperature = %d.%d degree\r\n",temperature>>8,temperature&0xff);
  7. printf("DHT11 Humidity = %d.%d%%\r\n",humidity>>8,humidity&0xff);
  8. HAL_Delay(1000);
  9. }

效果展示

打开Use MicroLIB

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号