|
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcden=P3^4; //定義lcd使能端
sbit lcdrs=P3^5; //定義lcd數據命令選擇端
sbit lcdwr=P3^6; //定義lcd讀寫選擇端
sbit lcdrd=P3^7; //定義并串選擇端
sbit DQ=P2^2; //定義DS18B20數據線引腳端
uchar high,low;
char a,d2,d1,d0;
float f_temp;
uint i,j,temp;
uchar code line2[]="當前室溫:";
uchar code line3[]="00.0度";
//-------------------毫秒級延時函數-------------------------
void delay_ms(uint z) //延時z毫秒
{
uint x,y;
for(x=z;x>0;x--)
for(y=115;y>0;y--);
}
//------------lcd寫指令函數-------------
void wr_cmd(uchar cmd)
{
lcden=0;
lcdrs=0;
P0=cmd;
delay_ms(1);
lcden=1;
delay_ms(1);
lcden=0;
}
//-----------lcd寫數據函數-----------
void wr_dat(uchar dat)
{
lcden=0;
lcdrs=1;
P0=dat;
delay_ms(1);
lcden=1;
delay_ms(1);
lcden=0;
}
//-----------------------用戶界面文字顯示函數--------------------------
void face_dis()
{
wr_cmd(0x30); //選擇功能:8位數據基本指令操作
wr_cmd(0x0c); //整體顯示開,不顯示光標
wr_cmd(0x01); //lcd清屏
wr_cmd(0x02); //游標歸原點
wr_cmd(0x90); //設置第二行起始位
for(a=0;a<10;a++) //寫入第二行數據
{
wr_dat(line2[a]);
}
wr_cmd(0x8c); //設置第三行起始位
for(a=0;a<6;a++) //寫入第三行數據
{
wr_dat(line3[a]);
}
}
//------------------------用戶界面數據顯示函數-------------------------------
void dat_dis()
{
wr_cmd(0x8c); //顯示溫度
wr_dat(0x30+d2);
wr_dat(0x30+d1);
wr_dat(0x2e); //寫入“.”號
wr_dat(0x30+d0);
}
//-----------------------------初始化函數------------------------------------
void init()
{
delay_ms(20); //等待液晶輸入電源穩定
lcdrd=1; //選定lcd與單片機并行連接
lcdwr=0; //因為我們不需要從lcd模塊讀數據,所以可直接將此端口清零,便于之后利用矩陣鍵盤
face_dis(); //顯示用戶界面
}
//-----------------------獲溫部分:初始化函數--------------------
void init_temp()
{
DQ=0; //拉低總線,產生復位信號
i=80;while(i>0)i--; //延時480~960us
DQ=1; //拉高總線
i=4;while(i>0)i--; //延時15~60us
while(DQ); //等待產生應答脈沖
i=70;while(i>0)i--; //延時至少480us
}
//------------------獲溫部分:寫函數-------------------------------
void wr_temp(uchar dat) //寫1個字節
{
bit testb;
for(j=8;j>0;j--)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //寫1
{
DQ=0; //拉低總線,產生寫時間隙
i++; //延時大于1us
DQ=1; //拉高總線
i=8;while(i>0)i--; //延時至少60us,供DS18B20采樣
}
else //寫0
{
DQ=0; //拉低總線,產生寫時間隙
i=8;while(i>0)i--; //保持至少60us,供DS18B20采樣
DQ=1; //拉高總線
i++;i++;
}
}
}
//------------------獲溫部分:讀函數-------------------------------
uchar rd_temp() //讀1個字節
{
bit b; //定義存放接收到的1個字節
uchar i_b;
uchar rdbyte;
for(j=8;j>0;j--)
{
DQ=0; //拉低總線,產生讀時隙
i++; //延時大于1us
DQ=1; //釋放總線
i++;i++; //給一定時間讓總線釋放
b=DQ; //讀取數據
i=8;while(i>0)i--; //延時至少60us
i_b=b;
rdbyte=(i_b<<7)|(rdbyte>>1); //將讀取到得一位值左移7位,存放讀取的數據變量rdbyte右移1位
}
return rdbyte;
}
//----------------------溫度獲取函數---------------------------
void get_temp()
{
init_temp(); //初始化,復位并獲取應答信號
wr_temp(0xcc); //跳過ROM
wr_temp(0x44); //開始溫度轉換
delay_ms(1000); //等待溫度轉換完成
init_temp(); //將DS18B20復位
wr_temp(0xcc); //跳過ROM
wr_temp(0xbe); //讀暫存器
low=rd_temp(); //讀取低8位
high=rd_temp(); //讀取高8位
temp=high;
temp<<=8;
temp=temp|low; //將讀取的低8位和高8位合并
f_temp=temp*0.0625; //溫度在寄存器中為12位 分辨率位0.0625°
temp=f_temp*10+0.5; //精確到十分位,四舍五入
d2=temp/100; //顯示數據:十位
d1=temp%100/10; //顯示數據:個位
d0=temp%10; //顯示數據:十分位
}
//-----------------主函數------------------------
void main()
{
init(); //lcd初始化
while(1)
{
get_temp(); //獲取溫度
dat_dis(); //顯示溫度
}
}
|
|