//*****************************************************************
/*
程序功能:在1602液晶屏上顯示當前溫度
涉及芯片:1602液晶、SD18b20溫度傳感器
*/
//*****************************************************************
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P0^3;
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
uchar low,high;
//====================================函數聲明
//*********sd18b20*******************
void delayus(uint time);
void init_18b20();
void write_18b20(uchar date);
uchar read_18b20();
void wndu();
//**********1602液晶**************
void init_1602();
void write_com1602(uchar com);
void write_date1602(uchar date);
//====================================
void delayms(uint time)//毫秒級延時函數
{
uint i,j;
for(i=time;i>0;i--)
for(j=110;j>0;j--);
}
void delayus(uint time)//微秒級延時函數
{
while(time--);
}
void init_18b20()//對sd18b20的初始化
{
uchar n;
DQ=1;
delayus(8);
DQ=0;
delayus(80);
DQ=1;
delayus(8);
n=DQ;
delayus(8);
}
/*將數據線拉為低電平產生寫時間片,在數據線口拉為低電平在15微秒到60微秒間對數據
線進行數據采樣.如果為高電平則為寫“1”,如果為低電平則為寫零。
對于主機產生的寫“1”時間片的情況:數據線必須必先拉為低電平,然后被釋放,是
數據線在產生時間片15微秒之內拉至高電平;
對于主機產生的寫“0”時間片的情況:數據線必須被拉至邏輯電平并且保持低電平60個微秒*/
void write_18b20(uchar com)
{
uint i;
for(i=0;i<8;i++)
{
DQ=0;
//delayus(4);
DQ=com&0x01;
delayus(10);
DQ=1;
com>>=1;
delayus(4);
}
delayus(4);
}
/*從ds18b20讀數據時,主機產生讀時間片。當主機把數據線從邏輯高電平拉至低電平時,產生
讀時間片。數據線必須保持在邏輯低電平至少1個微秒。來至ds18b20的數據在讀時間下降沿之
后15微秒有效。因此,為了讀出從時間片開始15微秒的狀態,主機必須停止保持數據線為邏輯
低電平。*/
uchar read_18b20()
{
uint i;
uchar date=0x00;
for(i=0;i<8;i++)
{
DQ=0;
date>>=1;
DQ=1;
if(DQ)date|=0x80;
delayus(4);
DQ=1;
delayus(4);
}
return date;
}
void wendu()
{
init_18b20();
write_18b20(0xcc);//跳過ROM
write_18b20(0x44);//啟動溫度測量
delayus(300);
init_18b20();
write_18b20(0xcc);//跳過ROM
write_18b20(0xbe);//讀取溫度
low=read_18b20(); //先讀低八位
high=read_18b20();//后讀高八位
}
void xianshi()
{
uchar a,b,c,d;
float m,n=0.0625;
high<<=4;
high+=(low&0xf0)>>4;
m=(low%10)*n;
delayus(4);
write_com1602(0x80+0x03);
a=high/10; //顯示十位上的數
write_date1602(0x30+a);
delayms(5);
write_com1602(0x80+0x04);
b=high%10; //顯示個位上的數
write_date1602(0x30+b);
delayms(5);
write_com1602(0x80+0x06);
c=(int)(m*10); //小數點后一位
write_date1602(0x30+c);
delayms(5);
d=(int)(m*100)%10; //小數點后第二位
write_com1602(0x80+0x07);
write_date1602(0x30+d);
delayms(5);
write_com1602(0x80+0x08);
write_date1602(0x27);
delayms(5);
write_com1602(0x80+0x09);
write_date1602('C');
delayms(5);
write_com1602(0x80+0x05);
write_date1602(0x2e);
delayms(5);
}
void main()
{
init_1602();
while(1)
{
wendu();
xianshi();
}
}
void init_1602()
{
en=0;
rw=0;
write_com1602(0x28);
delayms(5);
write_com1602(0x01);
delayms(5);
write_com1602(0x0c);
delayms(5);
write_com1602(0x06);
delayms(5);
}
void write_com1602(uchar com)
{
uchar gao,di;
gao=com&0xf0;
di=(com<<4)&0xf0;
delayms(5);
P2=gao;
rs=0;
delayms(5);
en=1;
delayms(5);
en=0;
delayms(5);
P2=di;
rs=0;
delayms(5);
en=1;
delayms(5);
en=0;
delayms(5);
}
void write_date1602(uchar date)
{
uchar gao,di;
gao=date&0xf0;
di=(date<<4)&0xf0;
delayms(5);
P2=gao;
rs=1;
delayms(5);
en=1;
delayms(5);
en=0;
delayms(5);
P2=di;
rs=1;
delayms(5);
en=1;
delayms(5);
en=0;
delayms(5);
}