初學者,我是用正點原子上的dht11代碼改的但是就是不知道問題出在哪?串口一直顯示是檢測不到dht11,要么就是隨機數。單總線怎么配置,我用的是GPIOB5這個端口配的,但是就是不行。/* IO操作函數 */是根據正點原子hal庫改過來的,這樣可以嗎?有大佬指點一下嗎?小弟在這里多謝了。
單片機源程序如下:
- #ifndef __DHT11_H
- #define __DHT11_H
- #include "sys.h"
- /******************************************************************************************/
- /* DHT11 引腳 定義 */
- #define DHT11_DQ_GPIO_PORT GPIOB
- #define DHT11_DQ_GPIO_PIN GPIO_Pin_5
- /******************************************************************************************/
- /* IO操作函數 */
- #define DHT11_DQ_OUT(x) do{x ? \
- GPIO_WriteBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN, Bit_RESET):\
- GPIO_WriteBit(DHT11_DQ_GPIO_PORT,DHT11_DQ_GPIO_PIN,Bit_SET); \
- }while(0) /* 數據端口輸出 */
- #define DHT11_DQ_IN GPIO_ReadInputDataBit(DHT11_DQ_GPIO_PORT, DHT11_DQ_GPIO_PIN) /* 數據端口輸入 */
- uint8_t dht11_init(void); /* 初始化DHT11 */
- uint8_t dht11_check(void); /* 檢測是否存在DHT11 */
- uint8_t dht11_read_data(uint8_t *temp,uint8_t *humi); /* 讀取溫濕度 */
- #endif
- ***********************************************************************
- #include "dht11.h"
- #include "delay.h"
- /**
- * @brief 復位DHT11
- * @param data: 要寫入的數據
- * @retval 無
- */
- static void dht11_reset(void)
- {
- DHT11_DQ_OUT(0); /* 拉低DQ */
- delay_ms(20); /* 拉低至少18ms */
- DHT11_DQ_OUT(1); /* DQ=1 */
- delay_us(30); /* 主機拉高20~40us */
- }
- /**
- * @brief 等待DHT11的回應
- * @param 無
- * @retval 0, DHT11正常
- * 1, DHT11異常/不存在
- */
- uint8_t dht11_check(void)
- {
- uint8_t retry = 0;
- uint8_t rval = 0;
- while (DHT11_DQ_IN && retry < 100) /* DHT11會拉低40~80us */
- {
- retry++;
- delay_us(1);
- }
- if (retry >= 100)
- {
- rval = 1;
- }
- else
- {
- retry = 0;
- while (!DHT11_DQ_IN && retry < 100) /* DHT11拉低后會再次拉高40~80us */
- {
- retry++;
- delay_us(1);
- }
- if (retry >= 100) rval = 1;
- }
- return rval;
- }
- /**
- * @brief 從DHT11讀取一個位
- * @param 無
- * @retval 讀取到的位值: 0 / 1
- */
- uint8_t dht11_read_bit(void)
- {
- uint8_t retry = 0;
- while (DHT11_DQ_IN && retry < 100) /* 等待變為低電平 */
- {
- retry++;
- delay_us(1);
- }
- retry = 0;
- while (!DHT11_DQ_IN && retry < 100) /* 等待變高電平 */
- {
- retry++;
- delay_us(1);
- }
- delay_us(40); /* 等待40us */
- if (DHT11_DQ_IN) /* 根據引腳狀態返回 bit */
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- /**
- * @brief 從DHT11讀取一個字節
- * @param 無
- * @retval 讀到的數據
- */
- static uint8_t dht11_read_byte(void)
- {
- uint8_t i, data = 0;
- for (i = 0; i < 8; i++) /* 循環讀取8位數據 */
- {
- data <<= 1; /* 高位數據先輸出, 先左移一位 */
- data |= dht11_read_bit(); /* 讀取1bit數據 */
- }
- return data;
- }
- /**
- * @brief 從DHT11讀取一次數據
- * @param temp: 溫度值(范圍:0~50°)
- * @param humi: 濕度值(范圍:20%~90%)
- * @retval 0, 正常.
- * 1, 失敗
- */
- uint8_t dht11_read_data(uint8_t *temp, uint8_t *humi)
- {
- uint8_t buf[5];
- uint8_t i;
- dht11_reset();
- if (dht11_check() == 0)
- {
- for (i = 0; i < 5; i++) /* 讀取40位數據 */
- {
- buf[i] = dht11_read_byte();
- }
- if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
- {
- *humi = buf[0];
- *temp = buf[2];
- }
- }
- else
- {
- return 1;
- }
- return 0;
- }
- /**
- * @brief 初始化DHT11的IO口 DQ 同時檢測DHT11的存在
- * @param 無
- * @retval 0, 正常
- * 1, 不存在/不正常
- */
- uint8_t dht11_init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- //DHT11_DQ_GPIO_CLK_ENABLE(); /* 開啟DQ引腳時鐘 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOA時鐘
- GPIO_InitStructure.GPIO_Pin = DHT11_DQ_GPIO_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
- GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;//開漏輸出
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 上拉 */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; /* 高速 */
- GPIO_Init(DHT11_DQ_GPIO_PORT, & GPIO_InitStructure); /* 初始化DHT11_DQ引腳 */
- /* DHT11_DQ引腳模式設置,開漏輸出,上拉, 這樣就不用再設置IO方向了, 開漏輸出的時候(=1), 也可以讀取外部信號的高低電平 */
- dht11_reset();
- return dht11_check();
- }
- **************************************************************************
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "beep.h"
- #include "key.h"
- #include "dht11.h"
- //串口通信實驗 -庫函數版本
- //STM32F4工程模板-庫函數版本
- int main(void)
- {
- u8 t;
- u8 len;
- u16 times=0;
- uint8_t temperature;
- uint8_t humidity;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2
- delay_init(168); //延時初始化
- uart_init(115200); //串口初始化波特率為115200
- LED_Init(); //初始化與LED連接的硬件接口
- //dht11_init();
- while (dht11_init()) /* DHT11初始化 */
- {
- printf("DHT11 Error");
- delay_ms(200);
- delay_ms(200);
- }
- while (1)
- {
- if (t % 10 == 0) /* 每100ms讀取一次 */
- {
- dht11_read_data(&temperature, &humidity); /* 讀取溫濕度值 */
- printf("%lf\n",temperature);
- printf("%lf\n",humidity);
- }
- delay_ms(100);
- t++;
- if (t == 20)
- {
- t = 0;
- //LED0_TOGGLE(); /* LED0閃爍 */
- }
- }
- }
復制代碼 |