欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
dht11和ds18b20溫濕度控制 單片機(jī)程序
[打印本頁(yè)]
作者:
1091212269
時(shí)間:
2019-6-5 12:44
標(biāo)題:
dht11和ds18b20溫濕度控制 單片機(jī)程序
基于51單片機(jī),傳感器使用dht11和ds18b20,dht11測(cè)溫度精度有限,18b20可以彌補(bǔ)。第一行顯示dht11采集到的濕度和溫度,以及繼電器狀態(tài)。第二行顯示18b20采集到溫度和THI。THi是畜牧業(yè)衡量動(dòng)物熱應(yīng)激指數(shù)的標(biāo)準(zhǔn),不需要的刪除掉。繼電器是通過(guò)THI指數(shù)高低控制的。
1.jpg
(90.36 KB, 下載次數(shù): 39)
下載附件
2019-6-6 03:58 上傳
單片機(jī)源程序如下:
/*********************************************************************************************
程序名: DHT11-1602
編寫(xiě)人: fby
編寫(xiě)時(shí)間: 2019年3月21日
硬件支持: STC89C52RC DHT11 LCD1602
接口說(shuō)明: DHT11:VCC DATA NC GND
*********************************************************************************************
說(shuō)明:1、單片機(jī)是STC89C52RC,晶振頻率11.0592MHz,實(shí)驗(yàn)成功。
2、好東西要共享,大家隨意折騰~~
*********************************************************************************************/
#include "reg52.h"
#include<intrins.h> //此文件中定義了單片機(jī)的一些特殊功能寄存器
#include<stdio.h>
#include"temp.h"
#define uchar unsigned char //無(wú)符號(hào)字符型類(lèi)型數(shù)據(jù)
#define uint unsigned int //無(wú)符號(hào)整型數(shù)據(jù)
#define ulong unsigned long //無(wú)符號(hào)整型數(shù)據(jù)
#define xiao float //xiaoshu
#define IODATA P0
uchar dat_r[10]; //用于存放從DHT11讀取到的數(shù)值
uchar sData[10];
sbit DATA=P2^0; //定義數(shù)據(jù)線(xiàn)
sbit RS=P2^6; //定義rs端口
sbit RW=P2^5; //定義rw端口
sbit E=P2^7;
sbit jidian=P3^7; //定義繼電器
static uint i;
extern uint zheng;
void delay200ms(void) //誤差 0us
{
unsigned char a,b,c;
for(c=4;c>0;c--)
for(b=116;b>0;b--)
for(a=214;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
/*******************************************************************************
* 函 數(shù) 名 : datapros()
* 函數(shù)功能 : 溫度讀取處理轉(zhuǎn)換函數(shù)
* 輸 入 : temp
* 輸 出 : 無(wú)
*******************************************************************************/
void datapros(int temp)
{
float tp;
if(temp< 0) //當(dāng)溫度值為負(fù)數(shù)
{
sData[0]=0;
//因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
//后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
//算加上0.5,還是在小數(shù)點(diǎn)后面。
}
else
{
sData[0]=1;
tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
//如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
temp=tp*0.0625*100+0.5;
//留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
//后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
//算加上0.5,還是在小數(shù)點(diǎn)后面。
}
//顯示數(shù)據(jù)處理
sData[1] = '0'+(temp / 10000);
sData[2] = '0'+(temp % 10000 / 1000);
sData[3] = '0'+(temp % 1000 / 100) ;
sData[4] = '0'+(temp % 100 / 10);
sData[5] = '0'+(temp % 10);
//真實(shí)數(shù)據(jù)
sData[7] = temp / 10000;
sData[8] = temp % 10000 / 1000;
sData[9] = temp % 1000 / 100 ;
sData[10] =temp % 100 / 10;
}
/*******************************************************************************
* 函 數(shù) 名 : Timer1Init
* 函數(shù)功能 : 定時(shí)器1初始化
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
void Timer1Init()
{
TMOD|=0X10;//選擇為定時(shí)器1模式,工作方式1,僅用TR1打開(kāi)啟動(dòng)。
TH1=0XFC; //給定時(shí)器賦初值,定時(shí)1ms
TL1=0X18;
ET1=1;//打開(kāi)定時(shí)器1中斷允許
EA=1;//打開(kāi)總中斷
TR1=1;//打開(kāi)定時(shí)器
}
/*********************************************************************************************
函數(shù)名:延時(shí)函數(shù)
調(diào) 用:Delay30us();/Delay20ms();/Delay1s();
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:延時(shí)相應(yīng)時(shí)間
備 注:振蕩晶體為11.0592MHz(所有延時(shí)函數(shù)Copy自STC-ISP(v6.85).exe)
**********************************************************************************************/
void Delay30us() //@11.0592MHz-40
{
unsigned char i;
i = 11;
while (--i);
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
void Delay1s() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*********************************************************************************************
函數(shù)名:DHT11啟動(dòng)函數(shù)
調(diào) 用:無(wú)
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:DHT11開(kāi)始工作
備 注:
**********************************************************************************************/
void DHT11_start() // 主機(jī)控制DHT11開(kāi)始工作
{
DATA=1; // 主線(xiàn)空閑狀態(tài)
_nop_();
_nop_();
DATA=0; // 主機(jī)發(fā)送開(kāi)始工作信號(hào)
Delay20ms(); //延時(shí)18ms以上
DATA=1; // 拉高并延時(shí)等待DHT11響應(yīng)
Delay30us();
}
/*********************************************************************************************
函數(shù)名:DHT11讀數(shù)據(jù)函數(shù)
調(diào) 用:? = DHT11_rec_byte();
參 數(shù):無(wú)
返回值:
結(jié) 果:讀DHT11數(shù)據(jù)并保存到dat
備 注:
**********************************************************************************************/
uchar DHT11_rec_byte() //接收一個(gè)字節(jié)
{
uchar i,dat=0;
for(i=0;i<8;i++) //從高到低依次接收8位數(shù)據(jù)
{
while(!DATA); ////等待50us低電平過(guò)去
Delay30us();
Delay30us(); //延時(shí)60us,如果還為高則數(shù)據(jù)為1,否則為0
dat<<=1; //左移位使正確接收8位數(shù)據(jù),數(shù)據(jù)為0時(shí)直接移位
if(DATA==1) //數(shù)據(jù)為1時(shí),使dat加1來(lái)接收數(shù)據(jù)1
dat+=1;
while(DATA); //等待數(shù)據(jù)線(xiàn)拉低
}
return dat;
}
/*********************************************************************************************
函數(shù)名:接收DHT11的40位的數(shù)據(jù)并校驗(yàn)
調(diào) 用:? = DHT11_receive();
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:結(jié)果保存到dat_r[i]中
備 注:
**********************************************************************************************/
void DHT11_receive() //接收40位的數(shù)據(jù)
{
uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
//xiao thi;
//uint zheng;
DHT11_start(); // 主機(jī)控制DHT11開(kāi)始工作
if(DATA==0)
{
while(DATA==0); //等待拉高
Delay30us();
Delay30us();
Delay30us(); //拉高后延時(shí)80us
R_H=DHT11_rec_byte(); //接收濕度高八位
R_L=DHT11_rec_byte(); //接收濕度低八位
T_H=DHT11_rec_byte(); //接收溫度高八位
T_L=DHT11_rec_byte(); //接收溫度低八位
revise=DHT11_rec_byte(); //接收校正位
Delay30us(); //結(jié)束
if((R_H+R_L+T_H+T_L)==revise) //校正
{
RH=R_H;
RL=R_L;
TH=T_H;
TL=T_L;
}
/*數(shù)據(jù)處理,方便顯示*/
dat_r[0]='0'+(RH/10);
dat_r[1]='0'+(RH%10);
dat_r[2]='0'+(TH/10);
dat_r[3]='0'+(TH%10);
dat_r[4]=RH;
//dat_r[4]='0'+(zheng/100);
//dat_r[5]='0'+(zheng%100/10);
//dat_r[6]='0'+(zheng%10);
//dat_r[7]='0'+(zheng/10);
//dat_r[8]=Thi;
//dat_r[7]='0'+(h);
//dat_r[7]='0'+(zheng);
}
}
/********************************************************************
* 名稱(chēng) : bit Busy(void)
* 功能 : 這個(gè)是一個(gè)讀狀態(tài)函數(shù),讀出函數(shù)是否處在忙狀態(tài)
* 輸入 : 輸入的命令值
* 輸出 : 無(wú)
***********************************************************************/
void Busy(void)
{
bit busy_flag = 1;
IODATA = 0xff;
RS = 0; //指令關(guān)
Delay30us();
RW = 1; //讀狀態(tài)
Delay30us();
E = 1; //使能高電平
while(1)
{
busy_flag = (bit)(IODATA & 0x80); //強(qiáng)制取最高位
if(busy_flag == 0)
{
break;
}
}
E = 0; //E 1->0,rs=0,rw=1,
//將數(shù)據(jù)寄存器內(nèi)的數(shù)據(jù)讀到DB0~DB7,分別將狀態(tài)標(biāo)志BF和地址計(jì)數(shù)器(AC)內(nèi)容讀到DB7和DB6~DB0。
}
/********************************************************************
* 名稱(chēng) : lcd1602_write_cmd(uchar del)
* 功能 : 1602命令函數(shù)
* 輸入 : 輸入的命令值
* 輸出 : 無(wú)
***********************************************************************/
void lcd1602_write_cmd(uchar del)
{
RS = 0;
Delay30us();
RW = 0;
Delay30us();
E = 0;
Delay30us();
IODATA = del;
Delay30us();
E = 1;
Delay30us();
E = 0; //E 1->0,rs=0,rw=0, 將指令代碼寫(xiě)入指令寄存器中
}
/********************************************************************
* 名稱(chēng) : lcd1602_write_data(uchar del)
* 功能 : 1602寫(xiě)數(shù)據(jù)函數(shù)
* 輸入 : 需要寫(xiě)入1602的數(shù)據(jù)
* 輸出 : 無(wú)
***********************************************************************/
void lcd1602_write_data(uchar del)
{
Busy();
Delay30us();
RS = 1;
Delay30us();
RW = 0;
Delay30us();
E = 0;
Delay30us();
IODATA = del;
Delay30us();
E = 1;
Delay30us();
E = 0; //E 1->0,rs=1,rw=0, 數(shù)據(jù)寫(xiě)入數(shù)據(jù)寄存器中
}
/********************************************************************
* 名稱(chēng) : lcd1602_init()
* 功能 : 1602初始化,請(qǐng)參考1602的資料
* 輸入 : 無(wú)
* 輸出 : 無(wú)
***********************************************************************/
void lcd1602_init(void)
{
Delay20ms();
lcd1602_write_cmd(0x38); //8位數(shù)據(jù),雙列,5*7字形
Delay20ms();
lcd1602_write_cmd(0x38);
Delay20ms();
lcd1602_write_cmd(0x38);
Busy();
lcd1602_write_cmd(0x08);// 只開(kāi)顯示
Busy();
lcd1602_write_cmd(0x01); //清屏
Busy();
lcd1602_write_cmd(0x06);//顯示地址遞增,即寫(xiě)一個(gè)數(shù)據(jù)后,顯示位置右移一位
Busy();
lcd1602_write_cmd(0x0c); //開(kāi)啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍
}
/********************************************************************
* 名稱(chēng) : lcd1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符顯示"b" ,調(diào)用該函數(shù)如下
L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無(wú)
***********************************************************************/
void lcd1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
Busy();
lcd1602_write_cmd(a); //置數(shù)據(jù)存貯器地址
Busy();
lcd1602_write_data(sign);
}
/********************************************************************
* 名稱(chēng) : lcd1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符開(kāi)始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無(wú)
***********************************************************************/
void lcd1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
while(1)
{
Busy();
lcd1602_write_cmd(a);
Busy();
lcd1602_write_data(*p);
a++;
p++;
if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符結(jié)束或每行最后一個(gè)字符
{
break;
}
}
}
void kongzhi() //控制函數(shù)
{
if(dat_r[8]>78) {jidian=0;lcd1602_string(1,16,"K");} // 上限74
else if(dat_r[8]<77) {jidian=1;lcd1602_string(1,16,"G");} // 下限72
else {lcd1602_string(1,16,"L");}
}
//thi計(jì)算函數(shù)
void thisuan()
{
xiao th;
uint thi,shi,wen;
shi=dat_r[4] ;
wen=sData[7]*100+sData[8]*10+sData[9]+sData[10]/10 ;
th=wen*0.81+(0.99*wen-14.3)*shi/100+46.3+0.5;
thi=th*10;
dat_r[5]='0'+(thi/100);
dat_r[6]='0'+(thi%100/10);
dat_r[7]='0'+(thi%10);
dat_r[8]=th;
}
/*********************************************************************************************
函數(shù)名:主函數(shù)
調(diào) 用:無(wú)
參 數(shù):無(wú)
返回值:無(wú)
結(jié) 果:讀DHT11數(shù)據(jù)并送到1602顯示
備 注:
**********************************************************************************************/
void main (void)
{
Delay20ms();
lcd1602_init(); //LCD初始化
while(1)
{
datapros(Ds18b20ReadTemp());
delay200ms; //經(jīng)測(cè)試,兩次連讀要至少延時(shí)80ms
DHT11_receive();//接受數(shù)據(jù)
thisuan();
lcd1602_string(1,1,"S:");
lcd1602_char(1,3,dat_r[0]);
lcd1602_char(1,4,dat_r[1]);
lcd1602_string(1,5,"%");
lcd1602_string(1,7,"W:");
lcd1602_char(1,8,dat_r[2]);
lcd1602_char(1,9,dat_r[3]);
lcd1602_char(1,10,0XDF);
lcd1602_string(1,11,"C");
lcd1602_string(2,1,"T:");
lcd1602_char(2,3,dat_r[5]);
lcd1602_char(2,4,dat_r[6]);
lcd1602_string(2,5,".");
lcd1602_char(2,6,dat_r[7]);
if(sData[0]==0)
{
lcd1602_string(2,8,"-");
}
if(sData[7]>0)
{
lcd1602_char(2,9,sData[1]);
}
lcd1602_char(2,10,sData[2]);
lcd1602_char(2,11,sData[3]);
lcd1602_string(2,12,".");
lcd1602_char(2,13,sData[4]);
//lcd1602_char(2,14,sData[5]);
lcd1602_string(1,13,"ji:");
kongzhi();
}}
//void Timer0() interrupt 3 //定時(shí)器中斷
//{
//TH0=0XFC; //給定時(shí)器賦初值,定時(shí)1ms
//TL0=0X18;
//i++;
//}
復(fù)制代碼
所有資料51hei提供下載:
THI dht11 18b20.zip
(78.98 KB, 下載次數(shù): 90)
2019-6-5 12:42 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
eagleking
時(shí)間:
2019-11-2 15:29
樓主你太辛苦了,謝謝啊
作者:
Eli_
時(shí)間:
2019-11-6 23:19
stc89c52rc,11.0592MHz,實(shí)測(cè)可以運(yùn)行!
作者:
明明12
時(shí)間:
2020-3-2 17:25
你好,我想問(wèn)一下,DHT11怎么接入51開(kāi)發(fā)板,接哪個(gè)引腳,小白一個(gè)。不是很懂
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1