2021-03-20 单片机——05 简单温度采集与控制装置
- 调试准备工作
添加头文件,打开.h文件添加函数声明
将延时函数扩大8-10倍:Delay_OneWire(50)
在DS18B20 .c文件添加 DS18B20的读取函数:
//读取函数,自己写
unsigned char Tempget(void)
{
unsigned char low,high,temp;
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);
low=Read_DS18B20();
high=Read_DS18B20();
temp=high<<4;
temp|=(low>>4);
return temp;
}
在main.c文件中的主函数进行验证:
//检验温度
wendu=Tempget();
qi=wendu/10;ba=wendu%10;
/解决最后一个灯异常亮的问题/
在display4最后,添加关闭所有数码管的语句
//解决最后一个灯超亮
P2=0XC0;//打开位选
P0=0XFF;//选择
P2=0XFF;//打开段选
P0=0XFF;
2.正文逻辑–先实现执行结构
- 温度检测
温度检测采用 DS18B20 温度传感器,数据经过单片机处理后,与用户设定的温度上限(T MAX )和温度下限(T MIN )比较,确定当前温度所处的区间,数码管温度显示格式如图 2 所示:
温度区间显示 (T MIN ≤T≤T MAX ) 不使用-熄灭 当前温度(28℃)- 关于温度区间的说明:
温度区间 0: 当前温度<T MIN
温度区间 1: T MIN ≤当前温度≤T MAX
温度区间 2: 当前温度>T MAX
可设定的最大温度区间:0℃~99℃
根据初始数码管的值,设定数码管:
yi=10;er=1;san=10;si=11;wu=11;liu=11;qi=0;ba=0;
根据题目判断温度所在区间,在数码管显示:
定义wendu;qujian=0,min,max(当前先设置初始值)
题目:
执行机构由指示灯 L1 和继电器组成,用于报警和连接外部高低温执行机构。
3.1 实时温度处在温度区间 0,继电器关闭,指示灯 L1 以 0.8 秒为间隔闪烁;
3.2 实时温度处在温度区间 1,继电器关闭,指示灯 L1 以 0.4 秒为间隔闪烁;
3.3 实时温度处在温度区间 2,继电器打开,指示灯 L1 以 0.2 秒为间隔闪烁。
因此需要定时器来实现,stc简便设置5ms的定时器,在前面进行函数声明,并将总中断和中断允许位打开:
一定不要忘记在主函数中初始化:Timer0Init();
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
//别忘了加这两句!!!!!!!!!!!!!!!
ET0=1;
EA=1;
}
在中断中实现闪烁:
定义 tt=0,标志位 bit fla=0;//fla闪烁
void timer0() interrupt 1
{
tt++;
if((qujian==0)&&(tt==160))
{
tt=0;
if(fla==0){fla=1;P2=0X80;P0=0XFE;}
else if(fla==1){fla=0;P2=0X80;P0=0XFF;}
}
else if((qujian==1)&&(tt==80))
{
tt=0;
if(fla==0){fla=1;P2=0X80;P0=0XFE;}
else if(fla==1){fla=0;P2=0X80;P0=0XFF;}
}
else if((qujian==2)&&(tt==40))
{
tt=0;
if(fla==0){fla=1;P2=0X80;P0=0XFE;}
else if(fla==1){fla=0;P2=0X80;P0=0XFF;}
}
}
在区间判断函数中判断继电器是否开启,完整函数:
wendu=Tempget();//先读取温度再进行判断
if(wendu<min)
{
qujian=0;P2=0XA0;P0=0X00;
}
else if((wendu>=min)&&(wendu<=max))
{
qujian=1;P2=0XA0;P0=0X00;
}
else if(wendu>max)
{
qujian=2;P2=0XA0;P0=0X10;
}
yi=10;er=qujian;san=10;si=11;wu=11;liu=11;qi=wendu/10;ba=wendu%10;
3.正文逻辑–实现矩阵按键
最后一列矩阵键盘不需要,可以直接删掉,定义键盘上的编码uchar num,bit shezhi=0,qingchu=0;
在主函数中判断shezhi是不是为0,若为0,则将上述读取温度判断区间的函数添在里面:
if(shezhi==0)
{
wendu=Tempget();
if(wendu<min)
{
qujian=0;P2=0XA0;P0=0X00;
}
else if((wendu>=min)&&(wendu<=max))
{
qujian=1;P2=0XA0;P0=0X00;
}
else if(wendu>max)
{
qujian=2;P2=0XA0;P0=0X10;
}
yi=10;er=qujian;san=10;si=11;wu=11;liu=11;qi=wendu/10;ba=wendu%10;
}
若不为0,则进入设置模式else if(shezhi==1)
LED灯,蜂鸣器继电器熄灭,并重新初始化数码管的值按照图示位置,之后将矩阵键盘附上名义上的码值:判断,哪个按键被按下,则就是码值几被按下,改变case后的值 定义uchar num=0
矩阵键盘的码值(num)依次在数码管上显示,增加标志位bit flag=0,将flag=1全部添加在case后
🔺在主函数shezhi==1函数中,在数码管上显示码值(二者关系)
(如何将表面上的码值真实的在数码管上显示(我卡住的地方))
清除按键部分:
添入main循环shezhi ==1 中,直接在键盘函数中,设置清除的值qingchu=1
LED闪烁的问题:
LED还在闪烁的原因是,关闭了LED和蜂鸣器继电器,但是没有关闭定时器中断和总中断,应在正常的时候再打开,中断开了,灯才会闪,正常状态下,灯是闪烁的;在键盘函数的shezhi里添加语句:
shezhi ==1ET0=0;EA=0;
shezhi ==0 ET0=1;EA=1;
断输入区间数大小是否正确:
在最后一位写完之后就判断
如果不对,则先初始设置数据,并使得LED2常亮
在shezhi中输入max,min的值
/****************************************
完整的主函数判断shezhi的代码:
****************************************/
if(shezhi==0)
{
wendu=Tempget();
if(wendu<min)
{
qujian=0;P2=0XA0;P0=0X00;
}
else if((wendu>=min)&&(wendu<=max))
{
qujian=1;P2=0XA0;P0=0X00;
}
else if(wendu>max)
{
qujian=2;P2=0XA0;P0=0X10;
}
yi=10;er=qujian;san=10;si=11;wu=11;liu=11;qi=wendu/10;ba=wendu%10;
}
else if(shezhi==1)
{
if(qingchu==1)
{
qingchu=0;
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11;
}
if((er==11)&&(flag==1))
{
flag=0;er=num;
}
else if((san==11)&&(flag==1))
{
flag=0;san=num;
}
else if((qi==11)&&(flag==1))
{
flag=0;qi=num;
}
else if((ba==11)&&(flag==1))
{
flag=0;ba=num;
if((qi*10+ba)>(er*10+san))
{
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11;
P2=0X80;P0=0XFD;
}
}
}
/****************************************
键盘函数shezhi功能实现的代码:
****************************************/
case 0xb7:
if(shezhi==0)
{
shezhi=1;
ET0=0;EA=0;
P2=0X80;P0=0XFF;P2=0XA0;P0=0X00;
yi=10;er=11;san=11;si=11;wu=11;liu=10;qi=11;ba=11;
}
else if(shezhi==1)
{
shezhi=0;
ET0=1;EA=1;
P2=0X80;P0=0XFF;
max=er*10+san;
min=qi*10+ba;
}
break;
/****************************************
一些乱七八糟的定义:
****************************************/
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};
uchar yi,er,san,si,wu,liu,qi,ba;
uchar wendu;
uchar max=30,min=20,qujian=0;
uchar tt=0;
uchar num=0;
bit fla=0;
bit shezhi=0,qingchu=0,flag=0;