标题:
基于89c1单片机的温控程序
[打印本页]
作者:
立即俩的爹
时间:
2020-6-15 11:09
标题:
基于89c1单片机的温控程序
51hei图片20200615110759.jpg
(108.83 KB, 下载次数: 50)
下载附件
2020-6-15 11:08 上传
sbit DS=P3^7;//定义 DS18B20 接口
sbit buzz=P3^6;//定义蜂鸣器
sbit key1=P3^5;//选择调整上限或者下限温度
sbit key2=P3^4;//温度增加
sbit key3=P3^3;//温度减少
sbit key4=P3^2;//显示实际温度并与上、 下限温度比较
sbit p23=P2^3;
sbit p22=P2^2;
sbit p21=P2^1;
sbit p20=P2^0;
uchar flag=1;
uchar flag1=0;
uchar flag2=0;
static uint tmpH=5;
static uint tmpL=-5;
int tmp;//十六位
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//7 段数码管
段码表共阳,0~9 和熄灭, 负的段码值
uchar data disp_buf[]={0x00,0x00,0x00,0x00}; //保存各个位上的数值
//引脚及标志变量初始化
void init()
{
key1=1;
key2=1;
key3=1;
key4=1;
flag1=0;
flag2=0;
}
//串口初始化
void init_com()
{
TMOD=0x20;//设置定时器方式 1, 用定时器设置串口波特率
TH1=0xfd;// 装入初值
TL1=0xfd;
TR1=1;//启动定时器 1;TR1 为 TCON 中的第六位
REN=1;//串口初始化, 运行串口接收
SM0=0;
SM1=1;//这两行设置串口方式 1
EA=1;//开启总中断
ES=1;//打开串口中断开关
}
void delay(uint x)
{
for(x;x>0;x--);
}
void Init_ds18b20()//初始化
{
unsigned char x=0;
DS = 1; //DS 复位
delay(8); //稍做延时
DS = 0; //单片机将 DQ 拉低
delay(80); //精确延时 大于 480us
DS = 1; //拉高总线
delay(5);
x=DS; //稍做延时后 如果 x=0 则初始化成功 x=1 则初始化失败
delay(20);
}
void Write_ds18b20(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DS=0;
//_nop_();
//_nop_();//启动写时许开始, 延时 2us
if(dat&0x01)
{
DS=1;//发 1 状态
delay(10);//延时 60us
}
else //发 0 状态
{
DS=0;
delay(10);//延时 60us
DS=1;//释放总线
_nop_();//回复时间延时 2us
_nop_();
}
dat>>=1;
}
//delay(4);
}
uchar Read_ds18b20()
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
DS=1; //特别注意此处
//_nop_();//延时 1us //特别注意此处
delay(1); //特别注意此处
DS=0;//启动读开始 //特别注意此处
dat>>=1;
DS=1;//释放总线
//delay(8);//延时 16us
if(DS)
dat=dat|0x80;
delay(5);
}
return dat;
}
int ReadTemperature(void)
{
uchar a,b;//uchar 八位
int temp; //十六位
Init_ds18b20();
Write_ds18b20(0xCC);// 跳过读序号列号的操作
Write_ds18b20(0x44);// 启动温度转换
delay(200);
Init_ds18b20();
Write_ds18b20(0xCC);//跳过读序号列号的操作
Write_ds18b20(0xBE);//读取温度寄存器等(共可读 9 个寄存器) 前两个就是温度
a=Read_ds18b20();//低 8 位
b=Read_ds18b20();//高 8 位
temp=b;
temp=temp<<8;
temp=temp+a;
return temp;
}
void change()
{
int tp;
if((tmp&0xf800)==0xf800)//温度小于零度时
{
tp=tmp;
tp=~tp+1;
tmp=tp&0x000f;
disp_buf[0]=(tmp&0x000f)*0.625+0.5;
tp=tp>>4;
tp=tp%100;
disp_buf[2]=tp/10;
disp_buf[1]=tp%10;
if(disp_buf[2]==0)
{
disp_buf[3]=10;
disp_buf[2]=11;
}
else
{
disp_buf[3]=11;
}
}
else
{
disp_buf[0]=(tmp&0x000f)*0.625+0.5;//小数部分
tp=tmp>>4;//整数部分
disp_buf[3]=tp/100;//百位
tp=tp%100;
disp_buf[2]=tp/10;//十位
disp_buf[1]=tp%10;//个位
if(!disp_buf[3])
{
disp_buf[3]=10;
if(!disp_buf[2])
{
disp_buf[2]=10;
}
}
}
}
void delayms(uint v)//延时, 实现数码管的动态显示
{
uint m,n;
for(m=v;m>0;m--)
for(n=73;n>0;n--);
}
void display()//温度显示函数
{
p20=0;//开百位显示
P0=tab[disp_buf[3]];//显示百位
delayms(5);//延时
p20=1;//关百位显示
p21=0;
P0 =tab[disp_buf[2]];//显示十位
delayms(5);
p21=1;
p22=0;
P0=tab[disp_buf[1]]&0x7f;//显示个位,并带小数点
delayms(5);
p22=1;
p23=0;
P0 =tab[disp_buf[0]];//显示小数位
delayms(5);
p23=1;
}
int main()
{
uchar data pc[6];
uint i;
init();
init_com();
tmp=ReadTemperature();
change();
pc[1]=disp_buf[2]+'0';
pc[2]=disp_buf[1]+'0';
pc[3]='.';
pc[4]=disp_buf[0]+'0';
while(1)
{
if(flag==1)
{
ES=0;
for(i=1;i<5;i++)
{
SBUF=pc[ i];
while(!TI);
TI=0;
}
ES=1;
flag=0;
}
while((flag1==0)&&(flag2==0))//flag1=1 时调上限。flag1=2 时调下限
{
tmp=ReadTemperature();
change();
display();
if(key1==0)//按下 1 键
{
delayms(100);
flag1=1;
key1 = 1;
}
}
while(flag1==0&&flag2==1)
{
buzz=1;
tmp=ReadTemperature();
change();
display();
while(tmp>=tmpH||tmp<=tmpL)
{
tmp=ReadTemperature();
change();
display();
buzz=0;
}
}
while(flag1==1)
{
tmp=(tmpH<<4);
change();
while(flag1==1)
{
display();
if(key2==0)//上限升高
{
tmpH++;
tmp=(tmpH<<4);
change();
while(!key2)
display();
}
if(key3==0)//上限降低
{
tmpH--;
tmp=(tmpH<<4);
change();
while(!key3)
display();
}
if(key1 == 0)//切换到调整下限模式
{
delayms(5);
flag1=2;
tmp=(tmpH<<4);
while(!key1);
}
if(key4==0)//按下 key4,实际温度与上限、 下限比较
{
flag1=0;
flag2=1;
//tmp=tmpH;
while(!key4);
}
}
}
while(flag1==2)//调下限
{
tmp=(tmpL<<4);
change();
while(flag1==2)
{
display();
if(key2==0)
{
tmpL++;
tmp=(tmpL<<4);
change();
while(!key2)
display();
}
if(key3==0)
{
tmpL--;
tmp=(tmpL<<4);
change();
while(!key3)
display();
}
if(key1==0)
{
flag1=1;
tmp=(tmpL<<4);
while(!key1);
}
if(key4==0)
{
flag1=0;
flag2=1;
//tmp=tmpL;
while(!key4);
}
}
}
}
return 0;
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1