標(biāo)題:
DHT11驅(qū)動(dòng)程序
[打印本頁(yè)]
作者:
891896039
時(shí)間:
2017-11-26 22:36
標(biāo)題:
DHT11驅(qū)動(dòng)程序
/*********************************************************************************************
程序名: DHT11驅(qū)動(dòng)程序
編寫人: 王朗的誘惑
編寫時(shí)間: 2015年8月4日
硬件支持: STC12C5A60S2 DHT11
接口說(shuō)明: DHT11:VCC GND DATA
*********************************************************************************************
說(shuō)明:1、單片機(jī)是STC12C5A60S2,晶振頻率12MHz,實(shí)驗(yàn)成功。換用12T單片機(jī)或別的晶振的時(shí)候要修改
延時(shí)函數(shù)和JUDGE。程序里判斷超時(shí)的變量t的閥值也要改。
2、好東西要共享,大家隨意折騰~~
*********************************************************************************************/
#include <STC12C5A60S2.H>
typedef unsigned char uchar;
typedef unsigned int uint;
#define JUDGE 30 //用于判斷通信的0和1,與單片機(jī)速度和晶振頻率有關(guān)
sbit DATA = P1^0; //定義數(shù)據(jù)引腳
uchar dat_r[5]; //用于存放從DHT11讀取到的數(shù)值
/*********************************************************************************************
函數(shù)名:延時(shí)函數(shù)
調(diào) 用:Delay30us();/Delay20ms();/Delay1s();
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:延時(shí)相應(yīng)時(shí)間
備 注:振蕩晶體為12MHz(所有延時(shí)函數(shù)Copy自STC-ISP(v6.85).exe)
**********************************************************************************************/
void Delay30us() //@12.000MHz
{
unsigned char i;
i = 87;
while (--i);
}
void Delay20ms() //@12.000MHz
{
unsigned char i, j, k;
i = 1;
j = 234;
k = 113;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay1s() //@12.000MHz
{
unsigned char i, j, k;
i = 46;
j = 153;
k = 245;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*********************************************************************************************
函數(shù)名:UART串口初始化函數(shù)
調(diào) 用:UART_Init();
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:?jiǎn)?dòng)UART串口接收中斷,允許串口接收,啟動(dòng)T/C1產(chǎn)生波特率(占用)
備 注:振蕩晶體為12MHz,PC串口端設(shè)置 [ 4800,8,無(wú),1,無(wú) ]
**********************************************************************************************/
void UART_Init (void){
EA = 1; //允許總中斷(如不使用中斷,可用//屏蔽)
ES = 1; //允許UART串口的中斷
TMOD = 0x20; //定時(shí)器T/C1工作方式2
SCON = 0x50; //串口工作方式1,允許串口接收(SCON = 0x40 時(shí)禁止串口接收)
TH1 = 0xF3; //定時(shí)器初值高8位設(shè)置
TL1 = 0xF3; //定時(shí)器初值低8位設(shè)置
PCON = 0x80; //波特率倍頻(屏蔽本句波特率為2400)
TR1 = 1; //定時(shí)器啟動(dòng)
}
/*********************************************************************************************
函數(shù)名:UART串口發(fā)送函數(shù)
調(diào) 用:UART_T (?);
參 數(shù):需要UART串口發(fā)送的數(shù)據(jù)(8位/1字節(jié))
返回值:無(wú)
結(jié) 果:將參數(shù)中的數(shù)據(jù)發(fā)送給UART串口,確認(rèn)發(fā)送完成后退出
備 注:
**********************************************************************************************/
void UART_T (uchar UART_data){ //定義串口發(fā)送數(shù)據(jù)變量
SBUF = UART_data; //將接收的數(shù)據(jù)發(fā)送回去
while(TI == 0); //檢查發(fā)送中斷標(biāo)志位
TI = 0; //令發(fā)送中斷標(biāo)志位為0(軟件清零)
}
/*********************************************************************************************
函數(shù)名:DHT11讀數(shù)據(jù)函數(shù)
調(diào) 用:? = GetData();
參 數(shù):無(wú)
返回值:失敗->-1,-2,-3,-4;成功->0
結(jié) 果:讀DHT11數(shù)據(jù)并保存到數(shù)組dat_r[]
備 注:
**********************************************************************************************/
char GetData (void)
{
uchar i,j; //for循環(huán)變量
uchar t; //超時(shí)判斷
uchar dat8=0; //一次讀取的8位數(shù)據(jù),需要讀5次
DATA = 0; //主機(jī)發(fā)起始信號(hào)
Delay20ms(); //主機(jī)拉低總線至少18ms
DATA = 1; //主機(jī)拉高總線20~40us
Delay30us();
t = 80; //設(shè)置超時(shí)等待時(shí)間
while(DATA && t--); //等待DHT11拉低總線
if(t == 0) //超時(shí)
{
DATA = 1;
return -1; //通信錯(cuò)誤退出,返回錯(cuò)誤信號(hào):-1
}
//等80us響應(yīng)信號(hào)
t = 250; //設(shè)置超時(shí)等待時(shí)間
while(!DATA && t--); //等待DHT11拉高總線
if(t == 0) //超時(shí)
{
DATA = 1;
return -2; //通信錯(cuò)誤退出,返回錯(cuò)誤信號(hào):-2
}
//等80us響應(yīng)信號(hào)
t = 250; //設(shè)置超時(shí)等待時(shí)間
while(DATA && t--); //等待DHT11拉低總線
if(t == 0) //超時(shí)
{
DATA = 1;
return -3; //通信錯(cuò)誤退出,返回錯(cuò)誤信號(hào):-3
}
for(j=0; j<5; j++) //5次讀取
{
for(i=0; i<8; i++) //1次8個(gè)位
{
//等待50us開(kāi)始時(shí)隙
t = 150; //設(shè)置超時(shí)等待時(shí)間
while(!DATA && t--); //等待DHT11拉高總線
if(t == 0) //超時(shí)
{
DATA = 1;
return -4; //通信錯(cuò)誤退出,返回錯(cuò)誤信號(hào):-4
}
t = 0; //記錄時(shí)間清零
while(DATA && ++t); //等待并記錄高電平持續(xù)時(shí)間
dat8 <<= 1;
if(t > JUDGE) //高電平持續(xù)時(shí)間較長(zhǎng)(70us)
dat8 += 1; //傳輸值為1
//else dat8 += 0;
}
dat_r[j] = dat8;
}
Delay30us(); //等待DHT11拉低50us
Delay30us();
DATA = 1; //結(jié)束,拉高總線
return 0; //返回成功信號(hào)
}
/*********************************************************************************************
函數(shù)名:數(shù)據(jù)校驗(yàn)函數(shù)
調(diào) 用:? = Check();
參 數(shù):無(wú)
返回值:成功->0;失敗->-1;
結(jié) 果:數(shù)據(jù)校驗(yàn)
備 注:數(shù)據(jù)傳送正確時(shí)校驗(yàn)和數(shù)據(jù)等于“8bit濕度整數(shù)數(shù)據(jù)+8bit濕度小數(shù)數(shù)據(jù)+8bi溫度整數(shù)數(shù)據(jù)+8bit溫度小數(shù)數(shù)據(jù)”所得結(jié)果的末8位。
**********************************************************************************************/
char Check (void)
{
uchar i; //for循環(huán)變量
uint chk=0; //校驗(yàn)和
for(i=0; i<4; i++)
chk += dat_r[i]; //累加
if((uchar)chk != dat_r[4]) //比對(duì)
return -1; //返回錯(cuò)誤信號(hào):-1
else
return 0; //返回正確信號(hào):0
}
/*********************************************************************************************
函數(shù)名:主函數(shù)
調(diào) 用:無(wú)
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:讀DHT11數(shù)據(jù)并送到串口顯示
備 注:
**********************************************************************************************/
void main (void)
{
char i;
UART_Init(); //串口初始化
Delay1s(); //等待DHT11穩(wěn)定
do
{
i = GetData(); //讀數(shù)據(jù)
if(i != 0) //有錯(cuò)誤
{
UART_T(-i); //返回錯(cuò)誤值
break; //重新開(kāi)始
}
i = Check(); //數(shù)據(jù)校驗(yàn)
if(i != 0) //有錯(cuò)誤
{
UART_T(-i); //返回錯(cuò)誤值
break; //重新開(kāi)始
}
UART_T(dat_r[0]); //濕度整數(shù)
//UART_T(dat_r[1]); //濕度小數(shù)(根據(jù)數(shù)據(jù)手冊(cè),DHT11小數(shù)部分一直是0沒(méi)用)
UART_T(dat_r[2]); //溫度整數(shù)
//UART_T(dat_r[3]); //溫度小數(shù)(根據(jù)數(shù)據(jù)手冊(cè),DHT11小數(shù)部分一直是0沒(méi)用)
UART_T(dat_r[4]); //校驗(yàn)值
Delay1s(); //經(jīng)測(cè)試,兩次連讀要至少延時(shí)80ms
}while(1);
}//main
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1