|
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit key0=P1^0;
sbit key1=P1^2;
sbit key2=P1^4;
sbit key3=P1^6;
sbit led0=P3^0;
sbit led1=P3^3;
sbit beep=P3^7;
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
sbit DQ=P2^3;
bit DS_OK=1; //溫度傳感器正常標志
bit HI_alarm=0;LO_alarm=0; //溫度正常標志,超出上下限時,=1
char alarm_HL[]={10,-10};
uint time=0;
uchar temp_num[]={0x00,0x00}; //用于存儲高字節(jié)與低字節(jié)
uchar display_digit[]={0,0,0,0};//存儲顯示溫度字符
uchar current_count=0; //存儲整數(shù)(高字節(jié)低三位與低字節(jié)高四位)
uchar alarm_HI_LO[]={"HI: LO: "};
uchar temperature_display[]={"TEMP: "};
uchar code tab0[]={"welcome to here"};
uchar code tab1[]={"----sky"};
uchar code temperature_title[]={"THE TEMPPERATURE"};
uchar code alarm_title[]={"ALARM TEMP HI LO"};
uchar code df_tab[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
void delay(uint z)
{
uint x;
while(z--)
for(x=120;x>0;x--);
}
void delay_4us()
{_nop_();_nop_();_nop_();_nop_();}
void delay_us(uint a)
{
while(a--);
}
uchar LCD_check_busy()
{
uchar state;
rs=0;
rw=1;
delay_4us();
en=1;
state=P0;
delay_4us();
en=0;
delay_4us();
return state;
}
void LCD_write_cmd(uchar cmd)
{
while((LCD_check_busy()&0x80)==0x80);
rs=0;
rw=0;
delay_4us();
en=1;
P0=cmd;
delay_4us();
en=0;
delay_4us();
}
void LCD_write_data(uchar dat)
{
while((LCD_check_busy()&0x80)==0x80);
rs=1;
rw=0;
delay_4us();
en=1;
P0=dat;
delay_4us();
en=0;
delay_4us();
}
void LCD_display(uchar *s)
{
uchar i;
for(i=0;i<16;i++)
{
LCD_write_data(s[i]);
}
}
void LCD_init()
{
LCD_write_cmd(0x38);
LCD_write_cmd(0x0c);
LCD_write_cmd(0x06);
LCD_write_cmd(0x01);
}
//LCD*************************************************
/*****************************************************/
/****************************************************/
/****************************************************/
uchar DS_init() //檢查溫度傳感器
{
uchar state;
DQ=1;
delay_us(8); //精確定時
DQ=0;
delay_us(80);
DQ=1;
delay_us(8);
state=DQ;
delay(100);
return state;
}
void DS_write_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
if((dat&0x01)==0) //寫0
{
DQ=0;
delay_us(5);
DQ=1;
}
else //寫1
{
DQ=0;
delay_us(1);
DQ=1;
delay_us(4);
}
dat>>=1;
}
}
uchar DS_read_byte() //讀一個字節(jié)
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
if(DQ==1)
dat|=0x80;
else
dat|=0x00;
delay_us(30);
DQ=1;
}
return dat;
}
void DS_read_temperature()
{
uchar a=15;
alarm_HL[0]=a%10;
alarm_HL[1]=-(a/10);
if(DS_init()==1) //檢查初始化溫度傳感器
DS_OK=0;
else
{
DS_init();
DS_write_byte(0xcc); //跳過序列號
DS_write_byte(0x44); //啟動溫度轉換
DS_init(); //重新檢查溫度傳感器
DS_write_byte(0xcc);//
DS_write_byte(0xbe);//啟動讀取溫度
/****先讀低8位,再讀高8位,不可調換************/
temp_num[1]=DS_read_byte();
temp_num[0]=DS_read_byte();
/***先裝載TH,再裝載TL******************************/
alarm_HL[0]=DS_read_byte(); //讀警報數(shù)據
alarm_HL[1]=DS_read_byte();
DS_OK=1; //正常工作
}
}
/*void key_set_HL()
{
if(key2==0)
{
alarm_HL[0]++;
if(alarm_HL[0]==40)
alarm_HL[0]=20;
}
if(key3==0)
{
alarm_HL[1]--;
if(alarm_HL[1]==-30)
alarm_HL[1]=-10;
}
} */
void DS_set_alarm()
{
DS_init();
//key_set_HL();
DS_write_byte(0xcc);
DS_write_byte(0x4e);
/*** //寫數(shù)據到RAM,先寫TH,再寫TL,不可調換*/
DS_write_byte(alarm_HL[0]);
DS_write_byte(alarm_HL[1]);
DS_write_byte(0x7f); //12位高精確度
DS_init();
DS_write_byte(0xcc);
DS_write_byte(0x48);//復制數(shù)據到存儲器
}
void LCD_display_temperature()
{
char sign_current_count; //有符號型變量
uchar flag=0;//負數(shù)標識
/***高5位為1(0XF8)則為負數(shù),為負數(shù)時取反加一****/
if((temp_num[0]&0xf8)==0xf8)
{
temp_num[0]=~temp_num[0]; //負數(shù)取反
temp_num[1]=~temp_num[1]+1;
if(temp_num[1]==0x00)
temp_num[0]++;
flag=1;//負數(shù)標識
}
/****溫度小數(shù)部分*********/
display_digit[3]=df_tab[temp_num[1]&0x0f];
/*溫度整數(shù)部分(高字節(jié)低4位與低字節(jié)高4位,無符號)***/
current_count=((temp_num[1]&0xf0)>>4)|((temp_num[0]&0x07)<<4);
/*有符號的當前溫度值,注意定義是char */
/***判斷sign_current_count是否等于current_count*****
***若相等則選擇-current_count,否則選擇current_count*****/
sign_current_count=flag?
-current_count:current_count;
/*高低溫報警標志(與char類型alarm_HL比較,可以區(qū)分正負號比較) */
/**先比較大小,再選擇1或者0;再賦值***********可以用IF語句代替******/
HI_alarm=sign_current_count>=alarm_HL[0]?
1:0;
LO_alarm=sign_current_count<=alarm_HL[1]?
1:0;
/* //分解整數(shù)部分 */
display_digit[0]=current_count/100;
display_digit[1]=current_count%100/10;
display_digit[2]=current_count%10;
/***刷新LCD顯示緩沖***/
temperature_display[11]=display_digit[3]+'0';
temperature_display[10]='.';
temperature_display[9]=display_digit[2]+'0';
temperature_display[8]=display_digit[1]+'0';
temperature_display[7]=display_digit[0]+'0';
/*百位為0時不顯示*/
if(display_digit[0]==0)
temperature_display[7]=' ';
/*百位為0,且十位為0時不顯示 */
if((display_digit[0]==0)&(display_digit[1]==0))
temperature_display[8]=' ';
// 負號顯示在恰當位置
if(flag)
{
if(temperature_display[8]==' ')
temperature_display[8]='-';
else
{
if(temperature_display[7]==' ')
temperature_display[7]='-';
else
temperature_display[6]='-';
}
}
LCD_write_cmd(0x80+0x00);
LCD_display(temperature_title);
LCD_write_cmd(0x80+0x40);
LCD_display(temperature_display);
LCD_write_cmd(0x80+0x4e);
LCD_write_data('C');
}
/*******************************************************/
/***********************************************************/
/**********************************************
************************************
******************************************************/
/*****顯示報警溫度************************************/
void LCD_display_alarm_temperature()
{
/****顯示高溫*****************************************************/
uchar i;
uchar flag=0;//負號標志
if(alarm_HL[0]<0)
{
alarm_HL[0]=~alarm_HL[0]+1;
flag=1;
}
/***分解高溫****************************************/
alarm_HI_LO[4]=alarm_HL[0]/100+'0';
alarm_HI_LO[5]=alarm_HL[0]%100/10+'0';
alarm_HI_LO[6]=alarm_HL[0]%10+'0';
/****屏蔽高位不顯示******************************************/
if(alarm_HI_LO[4]=='0')
alarm_HI_LO[4]=' ';
if(alarm_HI_LO[4]==' '&&alarm_HI_LO[5]=='0')
alarm_HI_LO[5]=' ';
/****負號放在適當?shù)奈恢?*************************************/
if(flag)
{
if(alarm_HI_LO[4]==' ')
alarm_HI_LO[4]='-';
else
if(alarm_HI_LO[5]==' ')
alarm_HI_LO[5]='-';
else
alarm_HI_LO[3]='-';
}
/************************************************************/
/**********低溫報警值****************************************/
flag=0;
if(alarm_HL[1]<0)
{
alarm_HL[1]=~alarm_HL[1]+1;
flag=1;
}
/****分解低溫*********************************************/
alarm_HI_LO[12]=alarm_HL[1]/100+'0';
alarm_HI_LO[13]=alarm_HL[1]%100/10+'0';
alarm_HI_LO[14]=alarm_HL[1]%10+'0';
/*********屏蔽高位不顯示************************************/
if(alarm_HI_LO[12]=='0')
alarm_HI_LO[12]=' ';
if(alarm_HI_LO[12]==' '&&alarm_HI_LO[13]=='0')
alarm_HI_LO[13]=' ';
/********負號顯示在適當位置************************************/
if(flag)
{
if(alarm_HI_LO[12]==' ')
alarm_HI_LO[12]='-';
else
if(alarm_HI_LO[13]==' ')
alarm_HI_LO[13]='-';
else
alarm_HI_LO[11]='-';
}
/****顯示高低溫報警溫度************************************/
LCD_write_cmd(0x80+0x00);
for(i=0;i<16;i++)
LCD_write_data(alarm_title[i]);
LCD_write_cmd(0x80+0x40);
for(i=0;i<16;i++)
LCD_write_data(alarm_HI_LO[i]);
LCD_write_cmd(0x80+0x47);
LCD_write_data('C');
LCD_write_cmd(0x80+0x4f);
LCD_write_data('C');
}
void main()
{
uchar i;
uchar current_opteration=1;
LCD_init();
led0=1;
led1=1;
TMOD=0x01;
TH0=-1000/256;
TL0=-1000%256;
EA=1;
ET0=1;
key_set_HL();
DS_set_alarm();
DS_read_temperature();
delay(50);
LCD_write_cmd(0x80+0x00);
for(i=0;i<16;i++)
{
LCD_write_data(tab0[i]);
delay(20);
}
LCD_write_cmd(0x80+0x48);
for(i=0;i<8;i++)
{
LCD_write_data(tab1[i]);
delay(20);
}
delay(1000);
for(i=0;i<16;i++)
{
LCD_write_cmd(0x1c);
delay(20);
}
delay(50);
LCD_write_cmd(0x01);
while(1)
{
if(key0==0)
current_opteration=1;
if(key1==0)
current_opteration=2;
switch(current_opteration)
{
case 1:
DS_read_temperature();
if(DS_OK)
{
if(HI_alarm==1||LO_alarm==1)
TR0=1;
else
TR0=0;
LCD_display_temperature();
}
delay(100);
break;
case 2:
DS_read_temperature();
LCD_display_alarm_temperature();
delay(100);
break;
}
}
}
void timer0() interrupt 1
{
TH0=-1000/256;
TL0=-1000%256;
beep=~beep;
if(++time==400)
{
time=0;
if(HI_alarm)
led0=~led0;
else
led0=1;
if(LO_alarm)
led1=~led1;
|
|