温度控制程序.docx
《温度控制程序.docx》由会员分享,可在线阅读,更多相关《温度控制程序.docx(9页珍藏版)》请在冰豆网上搜索。
温度控制程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^7;//ds18b20DQ接口
sbitbeep=P3^6;//蜂鸣器
sbithigh=P1^0;//温度上限报警位
sbitlow=P1^1;//温度下限报警位
sbitpoint=P3^3;//小数点位
sbitheat=P3^2;//加热控制位
/*数码管段码*/
ucharcodeduan_table[]={0,1,2,3,4,5,6,7,8,9,0x0f};
/*小数位对照*/
ucharcodedf_table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchartemp_value[]={0x00,0x00};//从DS18B20读取的温度值
uchardisplay_digit[]={0,0,0,0,0};//显示的温度数位
charwarn_temp_hl[2]={70,-20};//报警温度上下限,ds18b20测温范围是-50~+125
bithigh_warn=0,low_warn=0;//高低温报警标志
bitds18b20_well=1;//ds18b20正常
ucharcurrent=0;//温度整数部分
uinttime0=0;//定时器0延时累加
/********************************************************************************************/
/*延时程序,约为1us*/
voiddelay(uintx)
{
while(--x);
}
/*ds18b20初始化*/
uchards12b20_init()
{
ucharstatus;
DQ=1;delay(8);
DQ=0;delay(90);
DQ=1;delay(8);
status=DQ;
delay(100);
DQ=1;
returnstatus;//初始化成功返回值
}
/*读一字节*/
ucharread_one_byte()
{
uchari,dat=0;
DQ=1;
_nop_();
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
_nop_();
_nop_();
if(DQ)dat|=0x80;
delay(30);
DQ=1;
}
returndat;
}
/*写一字节*/
voidwrite_one_byte(uchardat)
{
uchari;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
}
/*读取温度值*/
voidread_temp()
{
if(ds12b20_init()==1)
ds18b20_well=0;//ds18b20故障
else
{
write_one_byte(0xcc);//跳过序列号
write_one_byte(0x44);//启动温度转换
ds12b20_init();//初始化
write_one_byte(0xcc);//跳过序列号
write_one_byte(0xbe);//读取温度寄存器
temp_value[0]=read_one_byte();//温度低8位
temp_value[1]=read_one_byte();//温度高8位
warn_temp_hl[0]=read_one_byte();//报警温度上限
warn_temp_hl[1]=read_one_byte();//报警温度下限
ds18b20_well=1;
}
}
/*设置DS18B20温度报警值*/
voidset_warn_temp_value()
{
ds12b20_init();
write_one_byte(0xcc);//跳过序列号
write_one_byte(0x4e);//将设定的温度报警值写入ds18b20
write_one_byte(warn_temp_hl[0]);//写温度上限
write_one_byte(warn_temp_hl[1]);//写温度下限
write_one_byte(0x7e);//精度设置
ds12b20_init();
write_one_byte(0xcc);//跳过序列号
write_one_byte(0x48);//温度报警值出入ds18b20
}
/*在数码管上显示温度*/
voiddisplay_temp()
{
uchari;
uchart=150;//延时值
ucharng=0,np=0x01;//负数标志及其位置
charsigned_current_temp;//有符号的当前温度值
/***********************负数转换,取反加一************************/
if((temp_value[1]&0xf8)==0xf8)
{
temp_value[1]=~temp_value[1];
temp_value[0]=~temp_value[0]+1;
if(temp_value[0]==0x00)temp_value[1]++;
ng=1;
}
/****************************************************************/
display_digit[0]=df_table[temp_value[1]&0x0f];//小数温度部分
current=((temp_value[0]&0xf0)>>4)|((temp_value[1]&0x07)<<4);//获取温度整数部分
signed_current_temp=ng?
-current:
current;//有符号的当前温度值
high_warn=signed_current_temp>=warn_temp_hl[0]?
1:
0;
low_warn=signed_current_temp<=warn_temp_hl[1]?
1:
0;//高低温报警标志位
/************整数部分分解************/
display_digit[3]=current/100;
display_digit[2]=current%100/10;
display_digit[1]=current%10;
if(display_digit[3]==0)
{
display_digit[3]=10;//高位为0不显示
np=0x01;//调整负号位置
if(display_digit[2]==0)
{
display_digit[2]=10;
np=0x02;
}
}
for(i=0;i<30;i++)
{
point=1;
P0=duan_table[display_digit[0]];
P2=0X08;delay(t);P2=0X00;//小数位
P0=duan_table[display_digit[1]];
point=0;
P2=0X04;delay(t);P2=0X00;//个位及小数点
point=1;
P0=duan_table[display_digit[2]];
P2=0X02;delay(t);P2=0X00;//十位显示
point=1;
P0=duan_table[display_digit[3]];
P2=0X01;delay(t);P2=0X00;//个位显示
if(ng==1)
{
//point=1;
P0=0X0c;//译码器显示不了负号,用这个代替
P2=np;//显示负号
delay(t);
P2=0X00;//负号没有显示
}
}
}
/*串口发送字符函数*/
voiduart_sendchar(ucharsch)
{
SBUF=sch;
while(TI==0);
TI=0;
}
/*串口发送字符串函数*/
voiduart_sendstring(uchar*s)
{
ucharc;
for(;;)
{
c=*s;
if(c=='\0')break;
s++;
uart_sendchar(c);
}
}
/*定时器中断,控制报警声音*/
voidtime_warn()interrupt1
{
TH0=-1000/256;
TL0=-1000/256;
beep=!
beep;
if(++time0==4)
{
time0=0;
if(high){high=~high;heat=1;}
elsehigh=1;
if(low){low=~low;heat=0;}
elselow=1;
}
}
/*串口接收中断函数*/
voiduart_receive()interrupt4
{
intvalue;
if(RI)//接收到一字节
{
RI=0;//清除串口中断标志位
value=SBUF;
if(value>0)warn_temp_hl[0]=SBUF;
if(value<0)warn_temp_hl[1]=SBUF;
}
}
/****************************主函数*********************************/
voidmain(void)
{
uchar*s="pleaseset:
/nHI_Alarm=/nLO_Alarm=";
heat=1;
ET0=1;
ES=1;
EA=1;
SCON=0X50;
PCON=0X00;
TMOD=0X21;
TH0=-1000/256;
TL0=-1000/256;
TH1=0XFD;
TL1=0XFD;
TR0=0;
TR1=1;
high=1;
low=1;
point=1;
set_warn_temp_value();
read_temp();
delay(50000);
delay(50000);
uart_sendstring(s);
while
(1)
{
read_temp();
if(ds18b20_well)
{
if(high_warn==1||low_warn==1)TR0=1;
elseTR0=0;
display_temp();
}
else
{
P0=P2=0X00;
}
}