野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 22561|回复: 1

dht11 温度显示正常,湿度一直是95的问题

[复制链接]
发表于 2021-5-1 20:33:49 | 显示全部楼层 |阅读模式
本帖最后由 mzg_ehu 于 2021-5-1 20:35 编辑
  1. #ifndef __DHT11_H_
  2. #define __DHT11_H_

  3. #include "stm32f1xx.h"
  4. #include "main.h"

  5. #define DHT11_HIGH  GPIO_PIN_SET
  6. #define DHT11_LOW   GPIO_PIN_RESET


  7. #define Bit_RESET   0
  8. #define Bit_SET     1
  9. /*---------------------------------------*/
  10. //#define DHT11_PORT                  GPIOA
  11. //#define DHT11_PIN                   GPIO_PIN_12            
  12. //#define DHT11_GPIO_CLK_ENABLE()     __GPIOA_CLK_ENABLE()

  13. #define  DHT11_DATA_IN()                  HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)
  14. #define  DHT11_DATA_OUT(value)            HAL_GPIO_WritePin(DHT11_GPIO_Port,DHT11_Pin,value)

  15. typedef struct
  16. {
  17.         uint8_t  humi_int;                //湿度的整数部分
  18.         uint8_t  humi_deci;                 //湿度的小数部分
  19.         uint8_t  temp_int;                 //温度的整数部分
  20.         uint8_t  temp_deci;                 //温度的小数部分
  21.         uint8_t  check_sum;                 //校验和
  22. }DHT11_Data_TypeDef;

  23. void DHT11_GPIO_Config(void);

  24. uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);


  25. #endif //__DHT11_H_


  26. dht11.c
  27. #include "dht11.h "
  28. #include "delay.h"
  29. #include "main.h"

  30. void DHT11_GPIO_Config(void)
  31. {
  32.         /*定义一个GPIO_InitTypeDef类型的结构体*/
  33.         GPIO_InitTypeDef  GPIO_InitStruct;

  34.         /*开启DHT11相关的GPIO外设时钟*/
  35.         DHT11_GPIO_CLK_ENABLE();
  36.                 /*选择要控制的GPIO引脚*/                                                                                                                           
  37.         GPIO_InitStruct.Pin = DHT11_Pin;        

  38.         /*设置引脚的输出类型为推挽输出*/
  39.         GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;  

  40.         /*设置引脚为上拉模式*/
  41.         GPIO_InitStruct.Pull  = GPIO_PULLUP;

  42.         /*设置引脚速率为高速 */   
  43.         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  44.         /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
  45.         HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);        
  46.         
  47. }

  48. static void DHT11_Mode_IPU(void)
  49. {
  50.                   GPIO_InitTypeDef  GPIO_InitStruct;

  51.            /*选择要控制的DHT11_PORT引脚*/        
  52.           GPIO_InitStruct.Pin = DHT11_Pin;        

  53.            /*设置引脚模式为浮空输入模式*/
  54.           GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  
  55.    
  56.            /* 设置引脚不上拉也不下拉 */
  57.           GPIO_InitStruct.Pull = GPIO_NOPULL;
  58.   
  59.            /*设置引脚速率为高速 */   
  60.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  61.   
  62.            /*调用库函数,初始化DHT11_PORT*/
  63.           HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);         
  64. }

  65. static void DHT11_Mode_Out_PP(void)
  66. {
  67.          
  68.                   GPIO_InitTypeDef  GPIO_InitStruct;

  69.            /*选择要控制的DHT11_PORT引脚*/        
  70.           GPIO_InitStruct.Pin = DHT11_Pin;        

  71.           /*设置引脚的输出类型为推挽输出*/
  72.           GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  
  73.   
  74.           GPIO_InitStruct.Pull = GPIO_PULLUP;
  75.   
  76.            /*设置引脚速率为高速 */   
  77.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  78.   
  79.            /*调用库函数,初始化DHT11_PORT*/
  80.           HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);         
  81. }
  82. static uint8_t Read_Byte(void)
  83. {
  84.         uint8_t i, temp=0;

  85.         for(i=0;i<8;i++)   
  86.         {         
  87.                 /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/  
  88.                 while(DHT11_DATA_IN()==Bit_RESET);

  89.                 /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
  90.                  *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
  91.                  */
  92.                 delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可                     

  93.                 if(DHT11_DATA_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */
  94.                 {
  95.                         /* 等待数据1的高电平结束 */
  96.                         while(DHT11_DATA_IN()==Bit_SET);

  97.                         temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行
  98.                 }
  99.                 else         // x us后为低电平表示数据“0”
  100.                 {                           
  101.                         temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
  102.                 }
  103.         }
  104.         return temp;
  105. }
  106. /*
  107. * 一次完整的数据传输为40bit,高位先出
  108. * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
  109. */
  110. uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
  111. {  
  112.   uint16_t count;
  113.         /*输出模式*/
  114.         DHT11_Mode_Out_PP();
  115.         /*主机拉低*/
  116.         DHT11_DATA_OUT(DHT11_LOW);
  117.         /*延时18ms*/
  118.         delay_ms(18);

  119.         /*总线拉高 主机延时30us*/
  120.         DHT11_DATA_OUT(DHT11_HIGH);

  121.         delay_us(30);   //延时30us

  122.         /*主机设为输入 判断从机响应信号*/
  123.         DHT11_Mode_IPU();

  124.         /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
  125.         if(DHT11_DATA_IN()==Bit_RESET)     
  126.         {
  127.     count=0;
  128.                 /*轮询直到从机发出 的80us 低电平 响应信号结束*/  
  129.                 while(DHT11_DATA_IN()==Bit_RESET)
  130.     {
  131.       count++;
  132.       if(count>1000)  return 0;
  133.       delay_us(10);
  134.     }   
  135.    
  136.     count=0;
  137.                 /*轮询直到从机发出的 80us 高电平 标置信号结束*/
  138.                 while(DHT11_DATA_IN()==Bit_SET)
  139.     {
  140.       count++;
  141.       if(count>1000)  return 0;
  142.       delay_us(10);
  143.     }  
  144.                 /*开始接收数据*/   
  145.                 DHT11_Data->humi_int= Read_Byte();

  146.                 DHT11_Data->humi_deci= Read_Byte();

  147.                 DHT11_Data->temp_int= Read_Byte();

  148.                 DHT11_Data->temp_deci= Read_Byte();

  149.                 DHT11_Data->check_sum= Read_Byte();

  150.                 /*读取结束,引脚改为输出模式*/
  151.                 DHT11_Mode_Out_PP();
  152.                 /*主机拉高*/
  153.                 DHT11_DATA_OUT(DHT11_HIGH);

  154.                 /*检查读取的数据是否正确*/
  155.                 if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
  156.                         return 1;
  157.                 else
  158.                         return 0;
  159.         }
  160.         else
  161.         {               
  162.                 return 0;
  163.         }   
  164. }

  165. main.c

  166. #include "main.h"
  167. #include "i2c.h"
  168. #include "gpio.h"
  169. #include "delay.h"
  170. #include "dht11.h"
  171. #include "stdio.h"

  172. void SystemClock_Config(void);
  173. /* USER CODE BEGIN PFP */

  174. /* USER CODE END PFP */

  175. /* Private user code ---------------------------------------------------------*/
  176. /* USER CODE BEGIN 0 */

  177. /* USER CODE END 0 */

  178. /**
  179.   * [url=home.php?mod=space&uid=41770]@brief[/url]  The application entry point.
  180.   * @retval int
  181.   */
  182. int main(void)
  183. {

  184.         char dispBuff[100];
  185.         
  186.         DHT11_Data_TypeDef DHT11_Data;

  187.   HAL_Init();

  188.   SystemClock_Config();

  189.   MX_GPIO_Init();
  190.   MX_I2C1_Init();

  191.         OLED_Init();
  192.         OLED_CLS();
  193.         delay_init(84);
  194.         DHT11_GPIO_Config();
  195.         
  196.         while(1)
  197.         {
  198.                
  199.                
  200.                 if (Read_DHT11 (&DHT11_Data) == SUCCESS)
  201.                 {
  202.                         sprintf(dispBuff,"T : %d.%d ",DHT11_Data.temp_int, DHT11_Data.temp_deci);
  203.                         OLED_ShowStr(0,0,(uint8_t *) dispBuff,2);
  204.                         delay_ms(10);
  205.                         sprintf(dispBuff,"H : %d.%d%% ",DHT11_Data.humi_int, DHT11_Data.humi_deci);
  206.                         OLED_ShowStr(0,4,(uint8_t *) dispBuff,2);
  207.                         delay_ms(10);
  208.                 }
  209.                 else
  210.                 {
  211. //                        OLED_CLS();
  212. //                        OLED_ShowStr(0,6,(uint8_t *)" Read DHT11 ERROR",2);
  213.                 }

  214.         }

  215. }

  216. /**
  217.   * @brief System Clock Configuration
  218.   * @retval None
  219.   */
  220. void SystemClock_Config(void)
  221. {
  222.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  223.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  224.   /** Initializes the RCC Oscillators according to the specified parameters
  225.   * in the RCC_OscInitTypeDef structure.
  226.   */
  227.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  228.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  229.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  230.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  231.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  232.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  233.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  234.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  235.   {
  236.     Error_Handler();
  237.   }
  238.   /** Initializes the CPU, AHB and APB buses clocks
  239.   */
  240.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  241.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  242.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  243.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  244.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  245.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  246.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  247.   {
  248.     Error_Handler();
  249.   }
  250. }

  251. /* USER CODE BEGIN 4 */

  252. /* USER CODE END 4 */

  253. /**
  254.   * @brief  This function is executed in case of error occurrence.
  255.   * @retval None
  256.   */
  257. void Error_Handler(void)
  258. {
  259.   /* USER CODE BEGIN Error_Handler_Debug */
  260.   /* User can add his own implementation to report the HAL error return state */
  261.   __disable_irq();
  262.   while (1)
  263.   {
  264.   }
  265.   /* USER CODE END Error_Handler_Debug */
  266. }

  267. #ifdef  USE_FULL_ASSERT
  268. /**
  269.   * @brief  Reports the name of the source file and the source line number
  270.   *         where the assert_param error has occurred.
  271.   * @param  file: pointer to the source file name
  272.   * @param  line: assert_param error line source number
  273.   * @retval None
  274.   */
  275. void assert_failed(uint8_t *file, uint32_t line)
  276. {
  277.   /* USER CODE BEGIN 6 */
  278.   /* User can add his own implementation to report the file name and line number,
  279.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  280.   /* USER CODE END 6 */
  281. }
  282. #endif /* USE_FULL_ASSERT */

  283. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

复制代码


回复

使用道具 举报

发表于 2021-10-19 09:22:44 | 显示全部楼层
那这个要重点比对下湿度部分的程序才行
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-27 11:26 , Processed in 0.031413 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表