基于51的温度控制系统设计C语言源程序.docx
《基于51的温度控制系统设计C语言源程序.docx》由会员分享,可在线阅读,更多相关《基于51的温度控制系统设计C语言源程序.docx(18页珍藏版)》请在冰豆网上搜索。
基于51的温度控制系统设计C语言源程序
/*程序名称:
温度监控系统*/
/*程序功能:
利用89C52单片机和DS18B20温度传感器实现环境*/
/*温度的实时测量和高、低温报警*/
/*程序版本:
*/
/*作者:
*/
/*编写时间:
*/
/*********************************************************/
#include<>
#include<>//含_nop_()延时函数
//定义数据类型
#defineucharunsignedchar
#defineuintunsignedint
//定义端口
#defineLEDP0//段码输出口
sbitDQ=P3^2;//传感器数据口
sbitSMG_q=P1^0;//定义数码管阳级控制脚(千位)
sbitSMG_b=P1^1;//定义数码管阳级控制脚(百位)
sbitSMG_s=P1^2;//定义数码管阳级控制脚(十位)
sbitSMG_g=P1^3;//定义数码管阳级控制脚(个位)
sbitbuzzer=P1^5;//蜂鸣器
sbitled_low=P2^6;//低温指示灯
sbitled_high=P2^7;//高温指示灯
sbitled_ok=P2^5;//温度正常指示灯
sbitled_work=P2^4;//工作指示灯
sbitset=P3^7;//设置按键
sbitadd=P3^4;//加一按键
sbitdec=P3^5;//减一按键
//定义变量和常量
intcount=0;//按键次数寄存器
inth;//主函数用循环计数器
uinttemp;//温度值
ucharr;//温度值整数形式
ucharhigh=35,low=20;//上下限初值
//共阳LED段码表"0""1""2""3""4""5""6""7""8""9""不亮""-"
ucharcodeLED_code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
ucharcodeLED_code1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
ucharcodeditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//小数部分转换码表
uchardatatemp_data[2]={0x00,0x00};//存储从传感器读出的温度值
uchardatadp[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算
//子函数声明
voidds_reset();//DS18B20初始化函数
voidds_write(uchards_wrdata);//DS18B20写数据函数
uchards_read();//DS18B20读数据函数
read_temp();//读取温度函数
voidchange_temp(uinttem);//温度数据处理
voidxianshi(inthorl);//温度显示转换
voiddisplay();//数码管显示函数
voidkeyscan();//按键查询函数
voidwarn_led();//超限报警
voiddelay(uintt);//延时函数,单次25us
/********************主函数*********************/
voidmain()
{
LED=0x00;//初始化显示端口
led1=0;
led2=0;
led3=0;
led4=0;
for(h=0;h<4;h++)
{
dp[h]=8;
}
while
(1)//循环执行显示和温度读取
{
uchari;
for(i=0;i<200;i++)
{
warn_led();//指示灯控制
display();//显示
keyscan();//按键扫描
}
change_temp(read_temp());//温度数据读取和处理
}
}
/***********************************************/
/*函数名称:
ds_reset()*/
/*函数功能:
DS18B20初始化*/
/*入口参数:
无*/
/*输出参数:
无*/
/*调用函数:
delay();_nop_();*/
/*全局变量:
无*/
/*局部变量:
presence*/
/***********************************************/
voidds_reset(void)
{
charpresence=1;
while(presence)
{
while(presence)
{
DQ=1;//传感器数据段先置高电平
_nop_();
_nop_();//适当延时
DQ=0;//传感器数据段从高电平拉到低电平
delay(50);//延时
DQ=1;//再置高电平
delay(6);//延时
presence=DQ;//初始化成功,继续下一步
}
delay(45);//延时
presence=~DQ;
}
DQ=1;//拉高电平
led_work=0;//开工作指示灯
}
/***********************************************/
/*函数名称:
ds_write()*/
/*函数功能:
向DS18B20写数据*/
/*入口参数:
ds_wrdata*/
/*输出参数:
无*/
/*调用函数:
delay();_nop_();*/
/*全局变量:
无*/
/*局部变量:
ds_wrdata*/
/***********************************************/
voidds_write(uchards_wrdata)
{
uchari;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();
_nop_();
DQ=0;
_nop_();
_nop_();
_nop_();
_nop_();
DQ=ds_wrdata&0x01;//最低位移出
delay(6);
ds_wrdata=ds_wrdata/2;//右移1位
}
DQ=1;
delay
(1);
}
/***********************************************/
/*函数名称:
ds_read()*/
/*函数功能:
从DS18B20读数据*/
/*入口参数:
无*/
/*输出参数:
value*/
/*调用函数:
delay();_nop_();*/
/*全局变量:
*/
/*局部变量:
i;value;*/
/***********************************************/
uchards_read(void)
{
uchari;
ucharvalue=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();
_nop_();
value>>=1;
DQ=0;
_nop_();
_nop_();
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
_nop_();
_nop_();
if(DQ)value|=0x80;
delay(6);
}
DQ=1;
return(value);
}
/***********************************************/
/*函数名称:
read_temp()*/
/*函数功能:
读温度数据数据*/
/*入口参数:
无*/
/*输出参数:
yemp*/
/*调用函数:
ds_reset();ds_write();ds_read();*/
/*delay();*/
/*全局变量:
temp*/
/*局部变量:
temp_data[];*/
/***********************************************/
read_temp()
{
ds_reset();//传感器初始化
delay(200);
ds_write(0xcc);//发跳过读取序列号命令
ds_write(0x44);//发温度转换命令
ds_reset();
delay
(1);
ds_write(0xcc);
ds_write(0xbe);//读18B20中存储器
temp_data[0]=ds_read();//读温度值的低字节命令
temp_data[1]=ds_read();//读温度值的高字节
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0];//两字节合成一个整型变量
returntemp;//返回温度值
}
/***********************************************/
/*函数名称:
chang_temp()*/
/*函数功能:
将温度传感器中独到的数据进行转换*/
/*入口参数:
tem*/
/*输出参数:
dp[]*/
/*调用函数:
无*/
/*全局变量:
dp[];ditab[];r;*/
/*局部变量:
tem*/
/***********************************************/
voidchange_temp(uinttem)
{
ucharn=0;
if(tem>6348)//温度值正负判断
{
tem=65536-tem;//负温度求补码
n=1;//标志位置1
}
dp[4]=tem&0x0f;//取小数部分的值
dp[0]=ditab[dp[4]];//存入小数部分显示值
dp[4]=tem>>4;//取中间八位,即整数部分的值
dp[3]=dp[4]/100;//取百位数据
dp[1]=dp[4]%100;//取后两位数据
dp[2]=dp[1]/10;//取十位数据
dp[1]=dp[1]%10;//个位
r=dp[1]+dp[2]*10+dp[3]*100;//实际温度值(十进制)
if(!
dp[3])//符号位显示判断
{
dp[3]=0x0a;//最高位为0时不显示
if(!
dp[2])
{
dp[2]=0x0a;//次高位为0时不显示
}
}
if(n)
{
dp[3]=0x0b;//负温度时最高位显示"-"
}
}
/***********************************************/
/*函数名称:
xianshi()*/
/*函数功能:
温度数据转换成显示所需LED段码*/
/*入口参数:
horl*/
/*输出参数:
dp[]*/
/*调用函数:
无*/
/*全局变量:
dp[];*/
/*局部变量:
n;*/
/***********************************************/
voidxianshi(inthorl)
{
intn=0;
if(horl>128)//负数补码转换
{
horl=256-horl;
n=1;
}
dp[3]=horl/100;
dp[3]=dp[3]&0x0f;//百位
dp[2]=horl%100/10;//十位
dp[1]=horl%10;//个位
dp[0]=0;//小数位
if(!
dp[3])//高位为零不显示
{
dp[3]=0x0a;
if(!
dp[2])
{
dp[2]=0x0a;
}
}
if(n)//负数最高位显示“-”
{
dp[3]=0x0b;
}
}
/***********************************************/
/*函数名称:
display()*/
/*函数功能:
数码管显示*/
/*入口参数:
无*/
/*输出参数:
无*/
/*调用函数:
delay()*/
/*全局变量:
dp[];LED_code[];LED_code1[];*/
/*led1;led2;led3;led4;*/
/*局部变量:
j;*/
/***********************************************/
voiddisplay()
{
intj;
for(j=0;j<4;j++)//4位LED扫描控制
{
switch(j)
{
case0:
LED=LED_code[dp[0]];
led4=1;
delay(450);
led4=0;
break;//小数位
case1:
LED=LED_code1[dp[1]];
led3=1;
delay(450);
led3=0;
break;//个位
case2:
LED=LED_code[dp[2]];
led2=1;
delay(450);
led2=0;
break;//十位
case3:
LED=LED_code[dp[3]];
led1=1;
delay(450);
led1=0;
break;//百位
}
}
}
/***********************************************/
/*函数名称:
keyscan()*/
/*函数功能:
按键查询*/
/*入口参数:
无*/
/*输出参数:
无*/
/*调用函数:
delay();display();xianshi();*/
/*全局变量:
count;high;low;*/
/*局部变量:
无*/
/***********************************************/
voidkeyscan()
{
if(set==0)//set键按下
{
while
(1)
{
delay(500);//延时去抖动
if(set==0)//重新判断set键是否按下
{
count++;
while(!
set)//按键弹起继续显示前面内容
display();
}
if(count==1)//set按下一次执行此段
{
xianshi(high);//转换上限温度为段码并显示
display();
if(add==0)//add键是否按下
{
while(!
add)//弹起时上限温度加一并显示
display();
high+=1;
}
if(dec==0)//dec键是否按下
{
while(!
dec)//弹起时上限温度减一并显示
display();
high-=1;
}
}
if(count==2)//set键按下两次执行此段
{
xianshi(low);//转换下限温度为段码并显示
display();
if(add==0)//add键是否按下
{
while(!
add)//弹起时下限温度加一并显示
display();
low+=1;
}//dec键是否按下
if(dec==0)
{
while(!
dec)//弹起时下限温度减一并显示
display();
low-=1;
}
}
if(count>=3)//set键按下三次回到温度显示状态
{
count=0;
break;
}
}
}
}
/***********************************************/
/*函数名称:
warn_led()*/
/*函数功能:
工作情况指示灯控制*/
/*入口参数:
无*/
/*输出参数:
无*/
/*调用函数:
无*/
/*全局变量:
high;low;r;*/
/*局部变量:
无*/
/***********************************************/
voidwarn_led()
{
if(r>high)//温度高于上限温度
{
led_low=1;//“低温”指示灯灭
led_high=0;//“高温”指示灯亮
led_ok=1;//“正常”指示灯灭
buzzer=0;//蜂鸣器发声
}
elseif(r{
led_low=0;//“低温”指示灯亮
led_high=1;//“高温”指示灯灭
led_ok=1;//“正常”指示灯灭
buzzer=0;//蜂鸣器发声
}
else//温度正常
{
led_low=1;//“低温”指示灯灭
led_high=1;//“高温”指示灯灭
led_ok=0;//“正常”指示灯亮
buzzer=1;//蜂鸣器不发声
}
}
/***********************************************/
/*函数名称:
delay()*/
/*函数功能:
延时函数,单次25us左右延时*/
/*入口参数:
t;*/
/*输出参数:
无*/
/*调用函数:
无*/
/*全局变量:
无*/
/*局部变量:
t;*/
/***********************************************/
voiddelay(uintt)
{
for(;t>0;t--);
}
/*******************程序结束********************/