#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[17]={0x03,0xe7,0x49,0x19,0x35,0x91,0x81,0x3b,0x01,0x11,0x21,0x85,0xc3,0x0d,0xc1,0xe1,0xdf};
sbit DQ=P1^4; //温度输入口
uchar flag;//正负标志位 1为负
uchar temp_data[2];//读出温度暂存数组
uchar dis_data[3];//显示温度数组
uchar TempeH=20;//温度下限值
uchar TempeL=10;//温度上限值
uchar Set_flag=0;
sbit Key0=P1^0; //设置按键
sbit Key1=P1^1; //设置加键
sbit Key2=P1^2; //设置减键
sbit Key3=P1^3; //设置转换键
sbit TT1=P3^5;
uchar Key_flag=0;//按键标志位
bit Cov=0; //上下限标志位
sbit Beep=P1^5;//蜂鸣器
//**********************************************
//延时函数
//**********************************************
void Delayms(uint i)
{
uchar j;
while(i--)
{
for(j=0;j<115;j++);
}
}
//**********************************************
//串口初始化
//**********************************************
void Initi_UART()
{
SCON = 0x10; // 设定串行口工作方式1 允许接收,相当于下面三句
PCON =0x00; // 波特率不倍增
}
//*******************************************
// 传送两个字符
//*******************************************
void send_char(unsigned char txd1,unsigned char txd2)
{
SBUF = txd1;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
SBUF = txd2;
while(!TI); // 等特数据传送
TI = 0; // 清除数据传送标志
}
//*******************************************
// 定时器初始化
//*******************************************
void Initi_Timer1()
{
EA=1; //开总中断
ET1=1; //定时器T1中断允许
TMOD=0x60; //定时器自动重装,8位计数器
TH1=255; //定时器T1的高8位赋初值
TL1=255; //定时器T1的高8位赋初值
TR1=1; //启动定时器T1
}
/***********11微秒延时函数**********/
//
void delay(uint t)
{
for(;t>0;t--);
}
/***********18B20复位函数**********/
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
presence=DQ; // presence=0继续下一步
}
delay(45); //延时500us
presence = ~DQ; //因为延时500us后总线会释放,因为从机只拉低最多240us
}
DQ=1;//释放总线
}
//
//
/**********18B20写命令函数*********/
//向 1-WIRE 总线上写一个字节
void write_byte(uchar val)
{
uchar i;
for (i=8; i>0; i--) //
{
DQ=1;_nop_();_nop_(); //释放总线
DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移一位
}
DQ = 1;
delay(1);
}
//
/*********18B20读1个字节函数********/
//从总线上读取一个字节
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();//释放总线
value>>=1; //左移的原因是低位先传输
DQ = 0; //拉低总线至少1us
_nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //释放总线等待 4us 采样
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;//释放总线
return(value);
}
/************开启转换****************/
void Start_Ds18b20()
{
ow_reset(); // 开机先转换一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令
}
/***********读出温度函数**********/
//
void read_temp()
{
ow_reset(); //总线复位
write_byte(0xCC); // 发Skip ROM命令相当于广播信号
write_byte(0xBE); // 发读命令
temp_data[0]=read_byte(); //温度低8位
temp_data[1]=read_byte(); //温度高8位
ow_reset();//终止读过程(不终止,将读出10个寄存器)
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 发转换命令,启动下次转换
}
//
/***********温度数据处理函数**********/
void work_temp()
{
uchar temp;
//负温度求补码
if((temp_data[1]&0xf8)!=0x00)//因为如果为负温度,则高5位为一
{
temp_data[1]=~(temp_data[1]);
temp_data[0]=~(temp_data[0])+1;
flag=1;
}
temp_data[0]>>=4;//去掉低四位
temp_data[1]=temp_data[1]&0x07; //取低三位
temp_data[1]<<=4;
temp=temp_data[0]+temp_data[1];
dis_data[2]=temp/100;
dis_data[1]=temp%100/10;
dis_data[0]=temp%10;
}
//*****************************************
//按键扫描
//*****************************************
void Scan_key()
{
P1=0xfe;
Delayms(50);
//加键
P1=0xfd;
Delayms(50);
if(Key_flag==1)
{
if(Cov==0)
{
if(Set_flag==1)
{TempeH+=10;}
if(Set_flag==2)
{TempeH+=1;}
if(TempeH>=100)
TempeH=0;
}
else
{
if(Set_flag==1)
{TempeL+=10;}
if(Set_flag==2)
{TempeL+=1;}
if(TempeL>=100)
TempeL=0;
}
Key_flag=0;//清除标志位
while(!TT1);// 等待按键释放
}
//减键
P1=0xfb;
Delayms(50);
if(Key_flag==2)
{
if(Cov==0)
{
if(Set_flag==1)
{TempeH-=10;}
if(Set_flag==2)
{TempeH-=1;}
if(TempeH<0)
TempeH=99;
}
else
{
if(Set_flag==1)
{TempeL-=10;}
if(Set_flag==2)
{TempeL-=1;}
if(TempeL<0)
TempeL=99;
}
Key_flag=0;//清除标志位
while(!TT1);//等待按键释放
}
//上下限转换键
P1=0xf7;
Delayms(50);
}
//*****************************************
//温度比较
//*****************************************
void Comp_temp()
{ //比较上限
if(dis_data[1]>(TempeH/10))
{
Beep=0;
P2=0xfd;
}
if(dis_data[1]==(TempeH/10))
{
if(dis_data[0]>(TempeH%10))
{
Beep=0;
P2=0xfd;
}
}
//比较下限
if(dis_data[1]<(TempeL/10))
{
Beep=0;
P2=0xfe;
}
if(dis_data[1]==(TempeL/10))
{
if(dis_data[0]<(TempeL%10))
{
Beep=0;
P2=0xfe;
}
}
//查看是否正常
if(dis_data[1]<(TempeH/10))
{
if(dis_data[1]>(TempeL/10))
{
Beep=1;
P2=0xfb;
}
if(dis_data[1]==(TempeL/10))
{
if(dis_data[0]>(TempeL%10))
{
Beep=0;
P2=0xfe;
}
}
}
if(dis_data[1]==(TempeH/10))
{
if(dis_data[0]<(TempeH%10))
{
if(dis_data[1]>(TempeL/10))
{
Beep=1;
P2=0xfb;
}
if(dis_data[1]==(TempeL/10))
{
if(dis_data[0]>(TempeL%10))
{
Beep=0;
P2=0xfe;
}
}
}
}
}
//
/****************主函数**********************/
void main()
{
Initi_UART();
Initi_Timer1();
P1=0xfe;
P2=0xfb;
while(1)
{
while(Set_flag==0)
{
Start_Ds18b20();
read_temp();
work_temp();
send_char(table[dis_data[0]],table[dis_data[1]]);
Delayms(100);
Comp_temp();
}
while(Set_flag)
{
P2=0xff;//关掉所有灯
if(Cov==0)
{
send_char(table[TempeH%10],table[TempeH/10]);
}
else
{
send_char(table[TempeL%10],table[TempeL/10]);
}
Scan_key();
}
P1=0xfe;//准备下次设置
}
}
/**************************************************************
函数功能:定时器T1的中断服务程序
**************************************************************/
void Time1(void) interrupt 3 using 0 //“interrupt”声明函数为中断服务函数
{
uchar temp;
EA=0;
temp=P1&0x0f;
switch (temp)
{
case (0x0e):
{
Set_flag++;
if(Set_flag==3)
{Set_flag=0;
Key_flag=0;
Cov=0;
}
while(!TT1);// 等待按键释放
} break;
case (0x0d):
{
Key_flag=1;
}break;
case(0x0b):
{
Key_flag=2;
}break;
case(0x07):
{
Cov=~Cov;
while(!TT1);// 等待按键释放
}break;
}
EA=1;
}
评论2
最新资源