前言
本項目主要通過使用STM32F103C8T6作為主控MCU,ESP8266作為數據透傳模塊,接入機智云AIoT云平臺,通過在線智能產品,實現了遠程聯網、溫濕度監測、APP控制等功能。
在上文中,主要介紹了“創建云端產品,燒錄Gagent”,以便讓設備能夠聯網,當然其中也備注了ESP8266燒寫Gagent固件時的注意事項,說明定義數據點的作用。
在本文中,從原理開始講解,闡述DHT11驅動的編寫。
進入正文
1、DHT11 簡要介紹
DHT11 器件采用簡化的單總線通信,DATA 引腳用于微處理器與 DHT11 之間的通訊和同步,一次傳送 40 位數據,高位先出。
舉例:
2、時序分析(附代碼)
用戶主機(MCU)發送一次開始信號后,DHT11 從低功耗模式轉換到高速模式,待主機開始信號結束后,DHT11 發送響應信號,送出 40bit 的數據,信號發送如圖所示。
注意:主機(MCU)從 DHT11 讀取的溫濕度數據總是前一次的測量值。
總線空閑:
DHT11 的 DATA 數據線由上拉電阻拉高一直保持高電平,此時 DHT11 的DATA 引腳處于輸入狀態,時刻檢測外部信號。
MCU 發出請求信號:
MCU I/O 設置為輸出同時輸出低電平,且低電平保持時間不能小于 18ms,然后MCU I/O設置為輸入狀態。由于上拉電阻,MCU I/O 即 DHT11 的 DATA 數據線也隨之變高,之后等待 DHT11 作出回答信號。
DHT11 發出應答信號:
當 DHT11 的 DATA 引腳檢測到外部信號有低電平時,等待外部信號低電平結束,延遲后 DHT11 的 DATA引腳處于輸出狀態,輸出 80us的低電平作為應答信號,緊接著輸出 80us 的高電平通知 MCU 準備接收數據,MCU I/O 此時處于輸入狀態,檢測到 DHT11 回應信號后,等待 80us 的高電平后的數據接收。
MCU 接收 40 位數據
由 DHT11 的 DATA 引腳輸出 40 位數據,MCU 根據 I/O 電平的變化來判斷是 “0” 還是 “1” 。
位數據 “0” 的格式為:
50us 的低電平和 26-28us的高電平。
位數據 “1” 的格式為:
50us 的低電平加 70us 的高電平。
DHT11 發出結束信號
DHT11 的 DATA 引腳輸出 40 位數據后,繼續輸出低電平 50us 后轉為輸入狀態,由于上拉電阻存在,變為高電平。
// 本驅動采用 HAL 庫,us 級延時使用通用定時器實現,對 IO 引腳的狀態的改變采用位操作以及直接寄存器操作
// 復位DHT11
void DHT11_Rst(void)
{
DHT11_IO_OUT(); //設置為輸出
DHT11_DQ_OUT = 0; //拉低
HAL_Delay_ms(20); //拉低至少18ms
DHT11_DQ_OUT = 1; //拉高
HAL_Delay_us(30); //主機拉高20~40us
}
//等待DHT11的回應
//返回1:未檢測到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(void)
{
uint8_t retry = 0;
DHT11_IO_IN(); //設置為輸入
while(DHT11_DQ_IN && retry < 100) //DHT11會拉低40~80us
{
retry++;
HAL_Delay_us(1);
}
if(retry >= 100)
return 1;
else
retry = 0;
while(!DHT11_DQ_IN && retry < 100) //DHT11拉低后會再次拉高40~80us
{
retry++;
HAL_Delay_us(1);
}
if(retry >= 100)
return 1;
return 0;
}
//從DHT11讀取一個位
//返回值:1/0
uint8_t DHT11_Read_Bit(void)
{
uint8_t retry = 0;
while(DHT11_DQ_IN && retry < 100)//等待變為低電平
{
retry++;
HAL_Delay_us(1);
}
retry = 0;
while(!DHT11_DQ_IN && retry < 100)//等待變高電平
{
retry++;
HAL_Delay_us(1);
}
delay_us(40);//等待40us
if(DHT11_DQ_IN)
return 1;
else
return 0;
}
//從DHT11讀取一個字節
//返回值:讀到的數據
uint8_t DHT11_Read_Byte(void)
{
uint8_t i,dat;
dat = 0;
for (i=0;i<8;i++)
{
dat <<= 1;
dat |= DHT11_Read_Bit();
}
return dat;
}
//從DHT11讀取一次數據
//temp0~50°)
//humi20%~90%)
//返回值:0,正常;1,讀取失敗;2,校驗和錯誤
uint8_t DHT11_Read_Data(uint8_t *temp, uint8_t *humi)
{
uint8_t buf[5];
uint8_t i;
DHT11_Rst();
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 2; // 校驗和錯誤
}
else
return 1;
return 0;
}
//初始化DHT11的 IO口, 同時檢測DHT11的存在
//返回1:不存在
//返回0:存在
uint8_t DHT11_Init(void)
{
DHT11_GPIO_Init();
DHT11_Rst();
return DHT11_Check();
}
3、使用串口觀察數據
將 printf 函數重定向至與 PC 相連的串口上。由于重定向相關函數已經包含在機智云生成的代碼中(gizwits_product.c),我們直接使用 printf 進行數據打印即可。
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
以下為相關測試代碼:
state = DHT11_Read_Data(&temperature, &humidity);
if(state == 2)
{
printf("the checksum is error\n");
}
else if(!state)
{
printf("temp = %d , humi = %d\n", temperature, humidity);
}
else
{
printf("DHT11 is not answer\n");
}
若采集到的數據沒有問題,即可將機智云協議相關代碼移植進工程中。
本文結束。
在下篇內容中,介紹結合STM32cubx實現機智云代碼工程移植、采集數據上發、控制數據下拉、成品測試環節。
-
物聯網
+關注
關注
2909文章
44557瀏覽量
372790 -
監測系統
+關注
關注
8文章
2719瀏覽量
81305
發布評論請先 登錄
相關推薦
評論