|
- #include "reg52.h"
- #include <intrins.h>
- #include <string.h>
-
- #define dataBuf P0
-
- sfr AUXR = 0x8e;
-
- sbit RS = P1^0;
- sbit RW = P1^1;
- sbit EN = P1^2;
- sbit dht11 = P1^3;
-
- char dht11Data[5];
- char temperature[9];
- char humidity[9];
-
- void Delay40us() //@11.0592MHz
- {
- unsigned char i;
-
- _nop_();
- i = 15;
- while (--i);
- }
-
- void Delay5ms() //@11.0592MHz
- {
- unsigned char i, j;
-
- i = 9;
- j = 244;
- do
- {
- while (--j);
- } while (--i);
- }
-
- void Delay15ms() //@11.0592MHz
- {
- unsigned char i, j;
-
- i = 27;
- j = 226;
- do
- {
- while (--j);
- } while (--i);
- }
-
- void Delay30ms() //@11.0592MHz
- {
- unsigned char i, j;
-
- i = 54;
- j = 199;
- do
- {
- while (--j);
- } while (--i);
- }
-
- void Delay1000ms() //@11.0592MHz
- {
- unsigned char i, j, k;
-
- _nop_();
- i = 8;
- j = 1;
- k = 243;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
- //配置DHT11輸出數(shù)據(jù)
- void dht11Start()
- {
- dht11 = 1;
- dht11 = 0;
- Delay30ms();
- dht11 = 1;
- while(dht11); //等待自己拉到低電平
- while(!dht11); //等待自己拉到高電平
- while(dht11); //等待自己拉到低電平
- }
-
- //獲取DHT11的數(shù)據(jù)
- void obtainDht11Data()
- {
- int i,j;
- char tmp;
- char flag;
- dht11Start(); //開始輸出數(shù)據(jù)
- for (i = 0; i < 5; i++){ //總共獲取5個字符(40bit)的數(shù)據(jù)
- for (j = 0; j < 8; j++){
- //一次獲取一個bit數(shù)據(jù)
- while(!dht11); //等待自己拉到高電平
- Delay40us(); //高電平時間為27微秒左右表示0,高電平時間為70微秒左右表示1
-
- if(dht11 == 1){ //40微秒后為高電平即輸出1
- while(dht11);
- flag = 1;
- }else{ //40微秒后為低電平即輸出0
- flag = 0;
- }
- tmp = tmp << 1; //由于dht11的數(shù)據(jù)是高位先出,所以用左移的方式
- tmp = tmp | flag; //(|1成1,|0不變),即對于前面7個bit,flag都為0,不改變tmp的值
- }
- dht11Data[i] = tmp;
- }
-
-
- }
-
- //發(fā)送數(shù)據(jù)到字符數(shù)組,用于LCD1602顯示
- void sendStrData()
- {
- humidity[0] = 'H';
- humidity[1] = ':';
- humidity[2] = dht11Data[0]/10 + 0x30;
- humidity[3] = dht11Data[0]%10 + 0x30;
- humidity[4] = '.';
- humidity[5] = dht11Data[1]/10 + 0x30;
- humidity[6] = dht11Data[1]%10 + 0x30;
- humidity[7] = '%';
- humidity[8] = '\0';
- temperature[0] = 'T';
- temperature[1] = ':';
- temperature[2] = dht11Data[2]/10 + 0x30;
- temperature[3] = dht11Data[2]%10 + 0x30;
- temperature[4] = '.';
- temperature[5] = dht11Data[3]/10 + 0x30;
- temperature[6] = dht11Data[3]%10 + 0x30;
- temperature[7] = 'C';
- temperature[8] = '\0';
- }
-
- //檢測忙信號,讀數(shù)據(jù)線的D7位
- void checkBusySignal()
- {
- char tmp = 0x80;
- dataBuf = 0x80;
- while(tmp & 0x80){ //當(dāng)忙標(biāo)志位(數(shù)據(jù)位D7)為高電平時,此時模塊不能接收命令或者數(shù)據(jù)
- RS = 0;
- RW = 1;
- EN = 0;
- _nop_();
- EN = 1;
- _nop_();
- _nop_();
- tmp = dataBuf; //讀八位數(shù)據(jù)線的數(shù)據(jù),當(dāng)不忙時,硬件會自動將該位置0,當(dāng)檢測到D7為低電平時將退出死循環(huán)
- EN = 0;
- _nop_();
- }
- }
-
- //寫指令
- void writeCmd(char cmd)
- {
- checkBusySignal();
- RS = 0; //選擇寫指令寄存器
- RW = 0;
- EN = 0;
- _nop_(); //該函數(shù)為延時函數(shù),延時一微秒
- dataBuf = cmd; //將指令存入八位數(shù)據(jù)線中
- EN = 1;
- _nop_();
- _nop_();
- EN = 0;
- _nop_();
- }
-
- //寫數(shù)據(jù)
- void writeData(char myData)
- {
- checkBusySignal();
- RS = 1; //選擇寫數(shù)據(jù)寄存器
- RW = 0;
- EN = 0;
- _nop_(); //該函數(shù)為延時函數(shù),延時一微秒
- dataBuf = myData; //將數(shù)據(jù)存入八位數(shù)據(jù)線中
- EN = 1;
- _nop_();
- _nop_();
- EN = 0;
- _nop_();
- }
-
- //LCD1602初始化
- void lcd1602Init()
- {
- Delay15ms(); //延時 15ms
- writeCmd(0x38); //寫指令 38H(不檢測忙信號)
- Delay5ms(); //延時 5ms
- checkBusySignal();//以后每次寫指令,讀/寫數(shù)據(jù)操作均需要檢測忙信號
- writeCmd(0x38); //寫指令 38H:顯示模式設(shè)置
- writeCmd(0x08); //寫指令 08H:顯示關(guān)閉
- writeCmd(0x01); //寫指令 01H:顯示清屏
- writeCmd(0x06); //寫指令 06H:顯示光標(biāo)移動設(shè)置
- writeCmd(0x0C); //寫指令 0CH:顯示開及光標(biāo)設(shè)置
- }
-
- //LCD1602顯示一行字符
- void lcd1602ShowData(char rows,char columns,char *str)
- {
- switch (rows){ //選擇行
- case 1:
- writeCmd(0x80 + columns); //選擇列
- while(*str != '\0'){
- writeData(*str); //顯示字符
- str++;
- }
- break;
-
- case 2:
- writeCmd(0x80 + 0x40 +columns); //選擇列
- while(*str != '\0'){
- writeData(*str); //顯示字符
- str++;
- }
- break;
-
- default:
- break;
- }
- }
-
- void main()
- {
- lcd1602Init();
- //dht11上電后,需要延時1-2s度過不穩(wěn)定狀態(tài)
- Delay1000ms();
- Delay1000ms();
-
- //每1s獲取空氣中的溫濕度
- while(1){
- obtainDht11Data();
- sendStrData();
- lcd1602ShowData(2,0,humidity);
- lcd1602ShowData(1,0,temperature);
- Delay1000ms();
- }
- }
-
復(fù)制代碼
|
|