/**
描述:DHT11 測試
*/
#include "ioCC2530.h"
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define DHT11_DATA P0_4
/*****************全局變量的定義******************/
uchar Overtime_counter; //判斷等待是否超時的計數器。利用uchar型的數值範圍進行自動延時控制(時長由初值決定),並判斷是否超時
uchar bit_value; //從DATA總線上讀到的位值
uchar T_data_H, T_data_L, RH_data_H, RH_data_L, checkdata;//校驗過的溫度高8位,溫度低8位,溼度高8位,溼度低8位,校驗和8位
uchar T_data_H_temp, T_data_L_temp, RH_data_H_temp, RH_data_L_temp, checkdata_temp;//未經校驗的數據
uchar comdata; //從DHT11讀取的一個字節的數據
void Delay(uint);
void InitialAD(void);
char str[16];
/*****************************************************
* @brief 初始化串口
*****************************************************/
void initUARTSEND(void)
{
PERCFG = 0x00; // 設置外設控制爲P0
P0SEL = 0x2c; // 選擇P0_2,P0_3,P0_4,P0_5作爲串口
P2DIR &= ~0XC0; //P0優先作爲UART0
U0CSR |= 0x80; //UART方式
U0GCR |= 9;
U0BAUD |= 59; //波特率設爲19200
UTX0IF = 0; //UART0 TX中斷標誌初始置位0
}
/********************************************
* @brief 串口發送數據
*
* @param Data - 數據
* len - 數據長度
********************************************/
void UartTX_Send_String(char Data[], int len)
{
int j;
for (j = 0; j < len; j++)
{
U0DBUF = Data[j]; // 填充數據到串口數據寄存器
while (UTX0IF == 0); // 等待串口發送完畢
UTX0IF = 0; // 將串口中斷標誌置0,準備下一次的發送
}
}
/*****************延時函數******************/
void Delay(unsigned int n)
{
unsigned int i;
for(i = 0; i < n; i++);
for(i = 0; i < n; i++);
for(i = 0; i < n; i++);
for(i = 0; i < n; i++);
for(i = 0; i < n; i++);
}
void Delay_10us(unsigned char n)
{
for( ; n > 0; n--);
}
/*****************從DHT11讀取一個字節函數******************/
void Read_Byte(void)
{
uchar i;
for (i = 0; i < 8; i++) //循環8次,讀取8bit的數據
{
Overtime_counter = 2; //讀取並等待DHT11發出的12-14us低電平開始信號
//P0DIR &= ~0x10;
while ((!DHT11_DATA) && Overtime_counter++);
Delay_10us(80); //26-28us的低電平判斷門限
bit_value = 0; //跳過門限後判斷總線是高還是低,高爲1,低爲0
if(DHT11_DATA)
bit_value = 1;
Overtime_counter=2; //等待1bit的電平信號結束,不管是0是1在118us後都變爲低電平,否則錯誤超時
while (DHT11_DATA && Overtime_counter++); //當U8FLAG加到255後溢出爲0,跳出循環,並後加加爲1
if (Overtime_counter == 1)
break; //超時則跳出for循環
comdata <<= 1; //左移1位,LSB補0
comdata |= bit_value; //LSB賦值
}
}
/*****************DHT11讀取五個字節函數******************/
void Read_DHT11(void)
{
uchar checksum;
P0DIR |= 0x10;
DHT11_DATA = 0;//主機拉低18ms
Delay(8900);
DHT11_DATA = 1;//總線由上拉電阻拉高 主機延時20us-40us
Delay_10us(150);
DHT11_DATA = 1;//主機轉爲輸入或者輸出高電平,DATA線由上拉電阻拉高,準備判斷DHT11的響應信號
//P0DIR &= ~0x10;
if (!DHT11_DATA)//判斷從機是否有低電平響應信號 如不響應則跳出,響應則向下運行
{
Overtime_counter = 2; //判斷DHT11發出的80us的低電平響應信號是否結束
while ((!DHT11_DATA)&&Overtime_counter++);
Overtime_counter=2; //判斷DHT11是否發出80us的高電平,如發出則進入數據接收狀態
while ((DHT11_DATA)&&Overtime_counter++);
Read_Byte(); //讀取溼度值整數部分的高8bit
RH_data_H_temp = comdata;
Read_Byte(); //讀取溼度值小數部分的低8bit
RH_data_L_temp = comdata;
Read_Byte(); //讀取溫度值整數部分的高8bit
T_data_H_temp = comdata;
Read_Byte(); //讀取溫度值小數部分的低8bit
T_data_L_temp = comdata;
Read_Byte(); //讀取校驗和的8bit
checkdata_temp = comdata;
//P0DIR |= 0x10;
DHT11_DATA = 1; //讀完數據將總線拉高
checksum = (T_data_H_temp + T_data_L_temp + RH_data_H_temp + RH_data_L_temp);//進行數據校驗
if (checksum == checkdata_temp)
{
RH_data_H = RH_data_H_temp;
RH_data_L = RH_data_L_temp;
T_data_H = T_data_H_temp;
T_data_L = T_data_L_temp;
checkdata = checkdata_temp;
}
}
}
/****************************************************************
*函數功能 :主函數 *
*入口參數 :無 *
*返 回 值 :無 *
*說 明 :無 *
****************************************************************/
void main(void)
{
CLKCONCMD &= ~0x40; //晶振
while (CLKCONSTA & 0x40); //等待晶振穩定
CLKCONCMD &= ~0x47; //CLKSPD128分頻
SLEEPCMD |= 0x04;
P1DIR |= 0x01;
initUARTSEND();
Delay(50000);
while (1)
{
Read_DHT11();//調用溫溼度讀取子程序
Delay(60000);//循環採樣的延時,讀取模塊數據週期不易小於2S
sprintf(str, "%dC, %dH\n", T_data_H, RH_data_H);
UartTX_Send_String(str, 16);
P1_0 ^= 1;
}
}
DHT11溫溼度傳感器 下載地址
具體知識點,可在下載文檔研讀,個人今天學習了,還是不太懂,所以,望賜教~