初中生
最后登录1970-1-1
在线时间 小时
注册时间2021-3-24
|
本帖最后由 mzg_ehu 于 2021-5-1 20:35 编辑
- #ifndef __DHT11_H_
- #define __DHT11_H_
- #include "stm32f1xx.h"
- #include "main.h"
- #define DHT11_HIGH GPIO_PIN_SET
- #define DHT11_LOW GPIO_PIN_RESET
- #define Bit_RESET 0
- #define Bit_SET 1
- /*---------------------------------------*/
- //#define DHT11_PORT GPIOA
- //#define DHT11_PIN GPIO_PIN_12
- //#define DHT11_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
- #define DHT11_DATA_IN() HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)
- #define DHT11_DATA_OUT(value) HAL_GPIO_WritePin(DHT11_GPIO_Port,DHT11_Pin,value)
- typedef struct
- {
- uint8_t humi_int; //湿度的整数部分
- uint8_t humi_deci; //湿度的小数部分
- uint8_t temp_int; //温度的整数部分
- uint8_t temp_deci; //温度的小数部分
- uint8_t check_sum; //校验和
- }DHT11_Data_TypeDef;
- void DHT11_GPIO_Config(void);
- uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);
- #endif //__DHT11_H_
- dht11.c
- #include "dht11.h "
- #include "delay.h"
- #include "main.h"
- void DHT11_GPIO_Config(void)
- {
- /*定义一个GPIO_InitTypeDef类型的结构体*/
- GPIO_InitTypeDef GPIO_InitStruct;
- /*开启DHT11相关的GPIO外设时钟*/
- DHT11_GPIO_CLK_ENABLE();
- /*选择要控制的GPIO引脚*/
- GPIO_InitStruct.Pin = DHT11_Pin;
- /*设置引脚的输出类型为推挽输出*/
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- /*设置引脚为上拉模式*/
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- /*设置引脚速率为高速 */
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- /*调用库函数,使用上面配置的GPIO_InitStructure初始化GPIO*/
- HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
-
- }
- static void DHT11_Mode_IPU(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- /*选择要控制的DHT11_PORT引脚*/
- GPIO_InitStruct.Pin = DHT11_Pin;
- /*设置引脚模式为浮空输入模式*/
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-
- /* 设置引脚不上拉也不下拉 */
- GPIO_InitStruct.Pull = GPIO_NOPULL;
-
- /*设置引脚速率为高速 */
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-
- /*调用库函数,初始化DHT11_PORT*/
- HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
- }
- static void DHT11_Mode_Out_PP(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStruct;
- /*选择要控制的DHT11_PORT引脚*/
- GPIO_InitStruct.Pin = DHT11_Pin;
- /*设置引脚的输出类型为推挽输出*/
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-
- GPIO_InitStruct.Pull = GPIO_PULLUP;
-
- /*设置引脚速率为高速 */
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
-
- /*调用库函数,初始化DHT11_PORT*/
- HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
- }
- static uint8_t Read_Byte(void)
- {
- uint8_t i, temp=0;
- for(i=0;i<8;i++)
- {
- /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/
- while(DHT11_DATA_IN()==Bit_RESET);
- /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
- *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时
- */
- delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可
- if(DHT11_DATA_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */
- {
- /* 等待数据1的高电平结束 */
- while(DHT11_DATA_IN()==Bit_SET);
- temp|=(uint8_t)(0x01<<(7-i)); //把第7-i位置1,MSB先行
- }
- else // x us后为低电平表示数据“0”
- {
- temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
- }
- }
- return temp;
- }
- /*
- * 一次完整的数据传输为40bit,高位先出
- * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和
- */
- uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
- {
- uint16_t count;
- /*输出模式*/
- DHT11_Mode_Out_PP();
- /*主机拉低*/
- DHT11_DATA_OUT(DHT11_LOW);
- /*延时18ms*/
- delay_ms(18);
- /*总线拉高 主机延时30us*/
- DHT11_DATA_OUT(DHT11_HIGH);
- delay_us(30); //延时30us
- /*主机设为输入 判断从机响应信号*/
- DHT11_Mode_IPU();
- /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/
- if(DHT11_DATA_IN()==Bit_RESET)
- {
- count=0;
- /*轮询直到从机发出 的80us 低电平 响应信号结束*/
- while(DHT11_DATA_IN()==Bit_RESET)
- {
- count++;
- if(count>1000) return 0;
- delay_us(10);
- }
-
- count=0;
- /*轮询直到从机发出的 80us 高电平 标置信号结束*/
- while(DHT11_DATA_IN()==Bit_SET)
- {
- count++;
- if(count>1000) return 0;
- delay_us(10);
- }
- /*开始接收数据*/
- DHT11_Data->humi_int= Read_Byte();
- DHT11_Data->humi_deci= Read_Byte();
- DHT11_Data->temp_int= Read_Byte();
- DHT11_Data->temp_deci= Read_Byte();
- DHT11_Data->check_sum= Read_Byte();
- /*读取结束,引脚改为输出模式*/
- DHT11_Mode_Out_PP();
- /*主机拉高*/
- DHT11_DATA_OUT(DHT11_HIGH);
- /*检查读取的数据是否正确*/
- if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
- return 1;
- else
- return 0;
- }
- else
- {
- return 0;
- }
- }
- main.c
- #include "main.h"
- #include "i2c.h"
- #include "gpio.h"
- #include "delay.h"
- #include "dht11.h"
- #include "stdio.h"
- void SystemClock_Config(void);
- /* USER CODE BEGIN PFP */
- /* USER CODE END PFP */
- /* Private user code ---------------------------------------------------------*/
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- /**
- * [url=home.php?mod=space&uid=41770]@brief[/url] The application entry point.
- * @retval int
- */
- int main(void)
- {
- char dispBuff[100];
-
- DHT11_Data_TypeDef DHT11_Data;
-
- HAL_Init();
- SystemClock_Config();
- MX_GPIO_Init();
- MX_I2C1_Init();
- OLED_Init();
- OLED_CLS();
- delay_init(84);
- DHT11_GPIO_Config();
-
- while(1)
- {
-
-
- if (Read_DHT11 (&DHT11_Data) == SUCCESS)
- {
- sprintf(dispBuff,"T : %d.%d ",DHT11_Data.temp_int, DHT11_Data.temp_deci);
- OLED_ShowStr(0,0,(uint8_t *) dispBuff,2);
- delay_ms(10);
- sprintf(dispBuff,"H : %d.%d%% ",DHT11_Data.humi_int, DHT11_Data.humi_deci);
- OLED_ShowStr(0,4,(uint8_t *) dispBuff,2);
- delay_ms(10);
- }
- else
- {
- // OLED_CLS();
- // OLED_ShowStr(0,6,(uint8_t *)" Read DHT11 ERROR",2);
- }
- }
- }
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
- {
- Error_Handler();
- }
- }
- /* USER CODE BEGIN 4 */
- /* USER CODE END 4 */
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- __disable_irq();
- while (1)
- {
- }
- /* USER CODE END Error_Handler_Debug */
- }
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
|
|