|
发表于 2014-9-10 20:19:05
|
显示全部楼层
#include <intrins.h>
#include <STC12C52.h>
sfr16 DPTR=0x82;
//数码管的位控制
sbit WE1=P1^0;
sbit WE2=P1^1;
sbit WE3=P1^2;
sbit SDA=P3^0;
sbit SCL=P3^1;
//高低温LED指示灯
sbit ledl=P1^7;
sbit ledh=P1^6;
//加热控制
sbit JR=P3^4;
//设置按键
sbit key=P3^3;
//DS18B20通信端口
sbit DQ = P3^7;
typedef unsigned int uint;
typedef unsigned char uchar;
// 0 1 2 3 4 5 6 7 8 9 -
uchar code led[] = { 0x77,0x14,0xB3,0xB6,0xD4,0xE6,0xE7,0x34,0xF7,0xF6,0x80 };
bit flag_low=0; //加热标示,当系统第一次到达最设定的低温度时置1
bit beep;
bit keytmp=1; //记录上一次检测时按键的状态
uchar setflag=0;//高低温设置标识符,非0则有按键被按下:1低温,2:高温
uint t_max=0; //最高温设置
uint t_min=0; //最低温设置
uchar count=0; //延时计数
uint db=0; //显示缓冲
uchar n1,n2,n3; //数码管变量
uchar discount=2;
uchar flag; //标识符:1 未检测到DS18B20,2 温度小于0,3 大于100
void init()
{
/*A/D转换,初始化P1端口*/
ADC_CONTR=0xE5; //开启A/D转换电源
P1ASF=0x20; //将P1.5设置为A/D
WE1=0;
WE2=0;
WE3=0;
/*定时器*/
TMOD=0x11; //设置工作模式为方式1
AUXR=0xC0; //设置T0为不分频
TH0=(65535-50000)/256;//设置定时器0的定时时间
TL0=(65535-50000)%256;
TH1=(65535-10000)/256;
TL1=(65535-10000)%256;
EA=1; //开总中断
ET0=1; //开定时器0中断
TR0=1; //启动定时器1
ET1=1;
TR1=1;
SCON=0; //初始化串行口方式
}
void delay(unsigned int i)
{
while(i--);
}
void input()
{
ledl=1;
ledh=1;
if(setflag)
{
ADC_RES=0x00;
ADC_CONTR=0xED;
while(!(ADC_CONTR & 0x10));
ADC_CONTR=0xE5;
db=ADC_RES+200;
if(setflag==1)
{
t_min=db;
ledl=0;
ledh=1;
}
else if(setflag==2)
{
t_max=db;
ledl=1;
ledh=0;
}
}
if(key==1 && keytmp==0)
setflag=(++setflag)%3;
keytmp=key;
}
//初始化函数
bit Init_DS1820(void)
{
bit tmp;
DQ = 0; //单片机将DQ拉低,复位DS1820
delay(160); //精确延时大于480us
DQ = 1; //拉高总线
delay(50); //延时检测DS1820是否存在
tmp=DQ;
delay(60);
return tmp;
}
//读一个字节
uchar Read1820(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
dat>>=1;
DQ = 0; //拉低单总线
delay(3);
DQ = 1; //释放单总线
delay(3);
if(DQ)
dat|=0x80;
delay(7);
}
return(dat);
}
//写一个字节
void Write1820(uchar dat)
{
uchar i = 0;
for (i=8;i>0;i--)
{
DQ = 0;
delay(5);
DQ=dat&0x01;
delay(10);
DQ = 1;
dat>>=1; //数据右移一位
}
}
void main()
{
init();
while(1)
{
if(!setflag)
{
beep=0;
if(db>=t_max) //加热控制
{
JR=0;
if(db>t_max+10) //高温报警,报警温度比t_max高1°C
beep=1;
}
if(db<=t_min)
{
JR=1;
if(flag_low && db<t_min-10)//低温报警,报警温度比t_min的1°C
beep=1;
}
}
}
}
void time0() interrupt 1 //定时5ms;每产生150次中断就读取、转换温度一次
{
TH0=(65535-50000)/256; //设置定时器0的定时时间
TL0=(65535-50000)%256;
count=(++count)%150;
if(count%10==0)
input();
if(count!=0)
return ;
if(setflag) //当前有按键被按下,暂时放弃与DS18B20的通信
return;
flag=0;
//读取温度
if(Init_DS1820()!=0) // 初始化DS1820
{
beep=1;
flag=1;
return ;
}
Write1820(0xCC); //跳过序列号命令
Write1820(0xBE); //读DS1820暂存器
DPL=Read1820();
DPH=Read1820();
db=DPTR;
if((DPH & 0x80)!=0)
{
db=~db;
db++;
flag=2;
}
db*=5; //转换后db*0.0625就是实际温度,这里只用一位小数所以扩大了10倍
db=db>>3;
//发送转换命令,预备下次读取
Init_DS1820();
Write1820(0xCC); //跳过序列号命令
Write1820(0x44); //发送温度转换命令
if(db>t_min)
flag_low=1;
}
void display() interrupt 3
{
TH1=(65535-50000)/256;
TL1=(65535-50000)%256;
if(flag==1 && setflag==0)//检测不到DS18B20时显示“---”的警告信息
{
n3=10;
n2=n3;
n1=n3;
}
else
{
n3=db/100;
n2=(db/10)%10;
n1=db%10;
if(n3>=10) //处理温度大于100°C时的情况
{
n1=n2;
n2=n3%10;
n3=1;
flag=3;
}
}
if(flag==2) //对负温进行判断
{
n1=n2;
n2=n3;
n3=10;
}
WE1=0;
WE2=0;
WE3=0;
discount=(++discount)%3;
if(discount==2)
{
SBUF=led[n3];
while(!TI);
WE3=1;
}
else if(discount==1)
{
if(flag)
SBUF=led[n2];
else
SBUF=led[n2] | 0x08; //为正数则输出小数点
while(!TI);
WE2=1;
}
else if(discount==0)
{
SBUF=led[n1];
while(!TI);
WE1=1;
}
TI=0;
}
ledh=0;
}
}
if(key==1 && keytmp==0)
setflag=(++setflag)%3;
keytmp=key;
}
//初始化函数
bit Init_DS1820(void)
{
bit tmp;
DQ = 0; //单片机将DQ拉低,复位DS1820
delay(160); //精确延时大于480us
DQ = 1; //拉高总线
delay(50); //延时检测DS1820是否存在
tmp=DQ;
delay(60);
return tmp;
}
//读一个字节
uchar Read1820(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
dat>>=1;
DQ = 0; //拉低单总线
delay(3);
DQ = 1; //释放单总线
delay(3);
if(DQ)
dat|=0x80;
delay(7);
}
return(dat);
}
//写一个字节
void Write1820(uchar dat)
{
uchar i = 0;
for (i=8;i>0;i--)
{
DQ = 0;
delay(5);
DQ=dat&0x01;
delay(10);
DQ = 1;
dat>>=1; //数据右移一位
}
}
void main()
{
init();
while(1)
{
if(!setflag)
{
beep=0;
if(db>=t_max) //加热控制
{
JR=0;
if(db>t_max+10) //高温报警,报警温度比t_max高1°C
beep=1;
}
if(db<=t_min)
{
JR=1;
if(flag_low && db<t_min-10)//低温报警,报警温度比t_min的1°C
beep=1;
}
}
}
}
void time0() interrupt 1 //定时5ms;每产生150次中断就读取、转换温度一次
{
TH0=(65535-50000)/256; //设置定时器0的定时时间
TL0=(65535-50000)%256;
count=(++count)%150;
if(count%10==0)
input();
if(count!=0)
return ;
if(setflag) //当前有按键被按下,暂时放弃与DS18B20的通信
return;
flag=0;
//读取温度
if(Init_DS1820()!=0) // 初始化DS1820
{
beep=1;
flag=1;
return ;
}
Write1820(0xCC); //跳过序列号命令
Write1820(0xBE); //读DS1820暂存器
DPL=Read1820();
DPH=Read1820();
db=DPTR;
if((DPH & 0x80)!=0)
{
db=~db;
db++;
flag=2;
}
db*=5; //转换后db*0.0625就是实际温度,这里只用一位小数所以扩大了10倍
db=db>>3;
//发送转换命令,预备下次读取
Init_DS1820();
Write1820(0xCC); //跳过序列号命令
Write1820(0x44); //发送温度转换命令
if(db>t_min)
flag_low=1;
}
void display() interrupt 3
{
TH1=(65535-50000)/256;
TL1=(65535-50000)%256;
if(flag==1 && setflag==0)//检测不到DS18B20时显示“---”的警告信息
{
n3=10;
n2=n3;
n1=n3;
}
else
{
n3=db/100;
n2=(db/10)%10;
n1=db%10;
if(n3>=10) //处理温度大于100°C时的情况
{
n1=n2;
n2=n3%10;
n3=1;
flag=3;
}
}
if(flag==2) //对负温进行判断
{
n1=n2;
n2=n3;
n3=10;
}
WE1=0;
WE2=0;
WE3=0;
discount=(++discount)%3;
if(discount==2)
{
SBUF=led[n3];
while(!TI);
WE3=1;
}
else if(discount==1)
{
if(flag)
SBUF=led[n2];
else
SBUF=led[n2] | 0x08; //为正数则输出小数点
while(!TI);
WE2=1;
}
else if(discount==0)
{
SBUF=led[n1];
while(!TI);
WE1=1;
}
TI=0;
}
大学时候写的,不要问我细节,记不清了 |
|