STM32读取DHT11中时序的问题,通过逻辑分析仪读取信号
生活随笔
收集整理的這篇文章主要介紹了
STM32读取DHT11中时序的问题,通过逻辑分析仪读取信号
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
DHT11.C 代碼
#include "dht11.h"//DHT11初始化函數 //DHT11 DATA---PB3void Dht11_Init(void) {GPIO_InitTypeDef GPIO_InitStruct;//開B組時鐘和AFIO時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE); //初始化IO口//定義結構體變量GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //選定管腳3GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //配置為開漏輸出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //輸出速度為2MHZGPIO_Init( GPIOB, &GPIO_InitStruct);GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);delay_ms(1000); //延時1s越過不穩定狀態 }/** 函數名:DHT11_Mode_IPU* 描述 :使DHT11-DATA引腳變為上拉輸入模式* 輸入 :無* 輸出 :無*/ static void DHT11_Mode_IPU(void) {GPIO_InitTypeDef GPIO_InitStructure;/*選擇要控制的DHT11_PORT引腳*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;/*設置引腳模式為浮空輸入模式*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; /*調用庫函數,初始化DHT11_PORT*/GPIO_Init(GPIOB, &GPIO_InitStructure); }/** 函數名:DHT11_Mode_Out_PP* 描述 :使DHT11-DATA引腳變為推挽輸出模式* 輸入 :無* 輸出 :無*/ static void DHT11_Mode_Out_PP(void) {GPIO_InitTypeDef GPIO_InitStructure;/*選擇要控制的DHT11_PORT引腳*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; /*設置引腳模式為通用推挽輸出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*設置引腳速率為50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/*調用庫函數,初始化DHT11_PORT*/GPIO_Init(GPIOB, &GPIO_InitStructure); }//MCU發送開始信號函數 void Mcu_Send_Start_Sign(void) {DHT11_Mode_Out_PP();GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET); delay_ms(18); //拉低總線18ms以上GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET); //拉高總線等待DHT11響應DHT11_Mode_IPU(); }//等待DHT11響應函數 //返回值 1---響應失敗 0-----響應成功 u8 Dht11_Ack(void) {u16 i = 0;while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1){i++;delay_us(1);if(i>50){return 1; //Dht11響應失敗}}//代碼運行到這里代表DHT11響應成功while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳過DHT11響應時間while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳過DHT11測量時間return 0; //DHT11響應成功 }//讀DHT11測到的數據u8 Read_Dht11_Data(void) {u8 i,data = 0;for(i=0;i<8;i++){while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0);//跳過數據的1bit低電平開始位delay_us(40); // data = data<<1;if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1) //數據1{while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);//跳過數據'1'的剩余高電平時間 // data |= 1;data|=(uint8_t)(0x01<<(7-i));}else{data&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行} } return data; }u8 Mcu_Control_Dht11(u8 *p) {u8 ret;Mcu_Send_Start_Sign(); //發送開始信號ret = Dht11_Ack();if(ret){return 1; //測量失敗}p[0] = Read_Dht11_Data(); //濕度整數數據p[1] = Read_Dht11_Data(); //濕度小數數據p[2] = Read_Dht11_Data(); //溫度整數數據p[3] = Read_Dht11_Data(); //溫度小數數據p[4] = Read_Dht11_Data(); //8bit校驗和if(p[0]+p[1]+p[2]+p[3] != p[4]){return 1; //測量失敗}return 0; //測量成功 }DHT11.H代碼
#ifndef _DHT11_H_ //防止頭文件重定義 #define _DHT11_H_#include "stm32f10x.h" #include "delay.h"static void DHT11_Mode_IPU(void); static void DHT11_Mode_Out_PP(void); void Dht11_Init(void); u8 Mcu_Control_Dht11(u8 *p);#endif開始信號的延時
//MCU發送開始信號函數 void Mcu_Send_Start_Sign(void) {DHT11_Mode_Out_PP();GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET); delay_ms(18); //拉低總線18ms以上GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET); //拉高總線等待DHT11響應DHT11_Mode_IPU(); }
可以看到,主機先要拉低最少18ms,再拉高。通過邏輯分析儀采集的信號可以看到。主機拉低了大約18ms.
后又拉高了29um
這里主機拉高后是由從機拉低的。
從機響應信號
響應1
大約82um
響應2
大約89.5um
讀取數據信號,信號0與信號1.
因此
這里可以根據上面的數據間隔大約在50um左右,因此延時可以在25um到71um之間。
根據每個設備的不同,所產生的信號延時也會不一樣,因此僅供參考。
總結
以上是生活随笔為你收集整理的STM32读取DHT11中时序的问题,通过逻辑分析仪读取信号的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 「YOZO Office」 @2021
- 下一篇: @EnableConfiguration