编写一个冰箱测温程序,经测试,可以用
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
//小板接线
// sbit lcdrs=P2^4; //液晶接口
// sbit rw=P2^5; //液晶接口
// sbit lcden=P2^6; //液晶接口
sbit quanwe=P2^0;
sbit baiwe=P2^1;
sbit shiwe=P2^2;
sbit gewe=P2^3;
sbit Beep=P3^0;
sbit DS=P3^2; //温度传感器接口
sbit K1=P3^6; //16脚
sbit K2=P3^7; //17脚
sbit K3=P3^4; //14脚
sbit K4=P3^5; //15脚
uchar K1num;
uchar code smgdu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
bit flag;
uchar Thflag=1;
uchar con;
uchar Th;
uint temp;
//延迟函数
void delayus(uint t) // 延迟10微秒函数
{
while(t--);
}
void delayms(uint z) //延迟1毫秒函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//DS18B20温度函数
void DSreset(void) //复位
{
DS=1; //总线高电平
delayus(6); //延迟66us
DS=0; //拉低总线
delayus(65); //保持480-960us
DS=1; //释放总线
delayus(14);
if(DS==0) //检测到从件发出应答信号
flag=1;
else
flag=0; //未检测到从件发出应答信号
delayus(20);
}
bit DSread_bit( ) //读位函数,主机把总线由高拉低1微秒,释放,15微秒内检测并读取总线电平。
{
bit Dat;
DS=0; //拉低总线
_nop_( ); //延1微秒
_nop_( );
DS=1; //释放总线
_nop_( );
Dat=DS; //读取总线电平
delayus(10);
return Dat; //返出读取值
}
uchar DSreadByte( ) //读取8位并组装1字节函数
{
uchar i, j,k;
k=0; //K赋初值0
for(i=0; i<8; i++)
{
j=DSread_bit( );
k=(j<<7)|(k>>1); //j左移7位与上k,8次后组成1字节
}
return k;
}
void DSwrite_byte(uchar dat) //写1字节函数
{
uchar i;
for(i=1;i<=8;i++)
{
DS=0; //拉低总线
_nop_( ); //延1微秒
DS=dat&0x01; //总线电平等于需写入dat的未位,写1则DS=1,写0则DS=0
delayus(6);
DS=1; //释放总线,准备写入dat的未第2位。
dat=dat>>1; //dat右移,未2位移至未位。
}
delayus(6);
}
void tmpconvert(void) //转换温度函数
{
DSreset();
delayms(1);
DSwrite_byte(0xcc); //跳过ROM指令
DSwrite_byte(0x44); //启动转换温度命令
}
uint read_temperature( ) //读传感器温度值函数
{
//uint T;
uchar LSB,MSB;
float tp;
DSreset( ); //复位
DSwrite_byte(0xcc); //跳过ROM指令
DSwrite_byte(0xbe); //读暂存器温度
LSB=DSreadByte( ); //读低8位字节,存入LSB
MSB=DSreadByte( ); //读高8位字节,存入MSB
temp=MSB<<8|LSB;
if(temp<0)
{
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*10+0.5;
}
else
{
tp=temp;
temp=tp*0.0625*10+0.5; //扩大10倍,显示百十个。
}
return temp; //返出温度值
}
void displaysmg (uint temp)
{
uchar quan,bai,shi,ge;
if(Thflag) //标志位置1,数码管显示测量温度
{
bai=temp/100;
shi=temp%100/10;
ge=temp%10;
quanwe=0;
baiwe=0;
shiwe=0;
gewe=0;
//P0=smgdu[quan];
//quanwe=1;
//delayms(1);
//quanwe=0;
P0=smgdu[bai];
quanwe=1;
delayms(1);
quanwe=0;
P0=smgdu[shi]|0x80;
baiwe=1;
delayms(1);
baiwe=0;
P0=smgdu[ge];
shiwe=1;
delayms(1);
shiwe=0;
}
else //标志位置0,数码管显示设定后温度
{
bai=Th/100;
shi=Th%100/10;
ge=Th%10;
quanwe=0;
baiwe=0;
shiwe=0;
gewe=0;
P0=smgdu[bai];
quanwe=1;
delayms(1);
quanwe=0;
P0=smgdu[shi]|0x80;
baiwe=1;
delayms(1);
baiwe=0;
P0=smgdu[ge];
shiwe=1;
delayms(1);
shiwe=0;
}
}
void keyscan( ) //键盘设置函数
{
if(K1==0) //K1按下
{
delayms(10); //消抖
if(K1==0)
{
K1num++; //K1按下次数判断
while(!K1);//松手检测
if(K1num==1) //第1次按下K1
{
Thflag=0; //标志位置0,显示设置温度报警函数
}
if(K1num==2) //第2次按下K1
{
K1num=0;
Thflag=1; //标志位置1,显示测量温度
}
}
}
if(K1num==1) //第1次按下K1情况下
{
if(K2==0) //K2按下执行温度累加设定
{
delayms(10);
if(K2==0)
{
delayms(10);
//while(!K2)
{
Th++;
if(Th==300)
Th=180;
displaysmg(Th); //显示设定后温度
}
}
}
if(K3==0) //K3按下执行温度累减设定
{
delayms(10);
if(K3==0)
{
delayms(10);
//while(!K3)
{
Th--;
if(Th==100)
Th=280;
displaysmg(Th); //显示设定后温度
}
}
}
}
}
void timerinit( ) //蜂鸣器断续发声定时器函数
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
EA=1;
TR0=0;
Th=225;
}
void main()
{
timerinit( ); //定时器初始化函数
while(1)
{
keyscan( ); //键盘设置函数
tmpconvert(); //温度转换函数
displaysmg(read_temperature( )); //温度显示函数
if(temp>Th)
{
TR0=1;
}
else
{
TR0=0;
Beep=1;
//TH0=(65536-50000)/256;
// TL0=(65536-50000)%256;
}
}
}
void timet0( )interrupt 1 //定时器中断,报警断续声函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
con++;
if(con==20)
{
con=0;
Beep=!Beep;
}
}
|