|
#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}; //用于存储高字节与低字节
uchar display_digit[]={0,0,0,0};//存储显示温度字符
uchar current_count=0; //存储整数(高字节低三位与低字节高四位)
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() //读一个字节
{
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(); //读警报数据
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);
/*** //写数据到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);//复制数据到存储器
}
void LCD_display_temperature()
{
char sign_current_count; //有符号型变量
uchar flag=0;//负数标识
/***高5位为1(0XF8)则为负数,为负数时取反加一****/
if((temp_num[0]&0xf8)==0xf8)
{
temp_num[0]=~temp_num[0]; //负数取反
temp_num[1]=~temp_num[1]+1;
if(temp_num[1]==0x00)
temp_num[0]++;
flag=1;//负数标识
}
/****温度小数部分*********/
display_digit[3]=df_tab[temp_num[1]&0x0f];
/*温度整数部分(高字节低4位与低字节高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比较,可以区分正负号比较) */
/**先比较大小,再选择1或者0;再赋值***********可以用IF语句代替******/
HI_alarm=sign_current_count>=alarm_HL[0]?
1:0;
LO_alarm=sign_current_count<=alarm_HL[1]?
1:0;
/* //分解整数部分 */
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]=' ';
/****负号放在适当的位置**************************************/
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;
|
|