题目要求
功能简述
模拟“温度采集与控制装置” 用于实现温度的实时监测与控制。单片机采集DS18B20温度传感器的输出信号, 并送到数码管进行显示; 通过传感器得到的温度数据将与用户设定温度上限、下限值做比较, 再由单片机启动控制或报警电路。系统硬件部分主要由单片机最小系统、数码管显示、 DS18B20 温度传感器、矩阵键盘等模块组成。 系统组成框图如图 1所示:
单总线驱动程序、 CT107D 单片机考试平台电路原理图以及本题所涉及到的芯片数据手册,可参考计算机上的电子文档。程序流程图及相关工程文件请以考生号命名,并保存在计算机上的考生文件夹中(文件夹名为考生准考证号,文件夹位于 Windows 桌面上)。
设计任务及要求
1. 温度检测
温度检测采用 DS18B20 温度传感器, 数据经过单片机处理后,与用户设定的温度上限(TMAX)和温度下限(TMIN)比较,确定当前温度所处的区间, 数码管温度显示格式如图 2 所示:
关于温度区间的说明:
温度区间 0: 当前温度<TMIN
温度区间 1: TMIN≤当前温度≤TMAX
温度区间 2: 当前温度>TMAX
可设定的最大温度区间: 0℃~99℃
2. 用户输入-3X4 矩阵键盘
通过矩阵键盘设定系统的工作参数,各个按键的功能定义如图 3 所示:
“设置”按键按下后,进入工作参数设定界面,如图 4 所示, 依次按下设定的数值,再次按下“设置” 按键, 保存当前输入的数据,并退出工作参数设定界面。
以设定 TMAX 为 35 摄氏度, TMIN为 25 摄氏度为例说明参数设定过程:按下“设置”按键,然后依次按下数字按键“3” “5” “2” “5” 如图 5 所示,再次按下“设置” 按键, 完成参数设定, 并退出参数设定界面。在输入过程中,按下“清除” 按键, 将清除当前输入数据, 若设定工作参数错误,如 TMAX<TMIN, L2 常亮,修正错误设定并保存参数后, L2 熄灭。
3. 执行机构
执行机构由指示灯 L1 和继电器组成,用于报警和连接外部高低温执行机构。
3.1 实时温度处在温度区间 0, 继电器关闭,指示灯 L1 以 0.8 秒为间隔闪烁;
3.2 实时温度处在温度区间 1, 继电器关闭,指示灯 L1 以 0.4 秒为间隔闪烁;
3.3 实时温度处在温度区间 2, 继电器打开,指示灯 L1 以 0.2 秒为间隔闪烁。
4. 初始化状态说明
系统默认的温度上限(TMAX)为 30℃, 温度下限(TMIN)为 20℃, 可以通过矩阵键盘修改。
5. 电路原理图设计
假定一个光敏电阻, 在光线充足的状态下, 阻值为 5 KΩ ,挡光状态下阻值≥45KΩ,使用简单阻容元件、晶体管、运算放大器等设计一个光敏电阻开关电路, 挡光状态下电路驱动 5V 继电器 K1 吸合, 反之, 继电器断开。 设计过程中, 需要考虑信号抖动等因素, 简述电路的工作原理与设计思路,并绘制出电路原理图。
程序代码
主函数
#include<stc15f2k60s2.h>
#include "temperature.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sbit beep=P0^6;
sbit Realy=P0^4;
uchar code SMG_duan[]={
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //0~9
uchar code SMG_wei[]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar set_display[8];
uchar temp_display[8];
uchar temp_val[8];
uchar temperature; //实时温度
uchar temp_max=50; //温度上限
uchar temp_min=20; //温度下限
uchar key_count; //按键计数,在设置温度上下限时使用
uchar key_return; //键值
uchar led_flag; //led闪烁频率选择
uchar set_flag; //设置标志
bit blink_flag; //闪烁
bit error_flag; //温度下限高于上限,错误位
bit key_flag;
void Timer0Init();
void delay(uint ms);
uchar Key_init();
void display1();
void Led_blink();
void main()
{
uchar key_val;
P2=0XA0;P0=0X00;
P2=0X80;P0=0XFF;
Timer0Init();
temp_display[0]=0x40; temp_display[2]=0x40; temp_display[3]=0x00;
temp_display[4]=0x00; temp_display[5]=0x00;
set_display[0]=0x40; set_display[5]=0x40;
set_display[3]=0x00; set_display[4]=0x00;
while(1)
{
temperature=temp_get();
temp_display[6]=SMG_duan[temperature%100/10];
temp_display[7]=SMG_duan[temperature%10];
temp_display[1]=SMG_duan[led_flag];
temp_display[1]=SMG_duan[led_flag];
temp_display[1]=SMG_duan[led_flag];
//display1();
if(temperature<temp_min)
{
led_flag=0;
}
if((temp_min<=temperature)&&(temperature<=temp_max))
{
led_flag=1;
}
if(temperature>temp_max)
{
led_flag=2;
}
if(key_count==2)
key_count=5;
if(key_count>7)
key_count=8;
if(key_flag)
{
key_flag=0;
key_val=Key_init();
switch(key_val)
{
case 4: key_count++; set_display[key_count]=SMG_duan[9];temp_val[key_count]=9;
break;
case 5: key_count++; set_display[key_count]=SMG_duan[6];temp_val[key_count]=6;
break;
case 6: key_count++; set_display[key_count]=SMG_duan[3];temp_val[key_count]=3;
break;
case 7: key_count++; set_display[key_count]=SMG_duan[0];temp_val[key_count]=0;
break;
case 8: set_flag++; //设置
if(set_flag==2)
{
set_flag=0;
temp_max=temp_val[1]*10+temp_val[2];
temp_min=temp_val[6]*10+temp_val[7];
}
if(temp_min>temp_max)
{
P2=0X80;P0=0xfd;P2=0X00;
error_flag=1;
}
else
{
P2=0X80;P0=0xff;P2=0X00;
error_flag=0;
}
break;
case 9: key_count++; set_display[key_count]=SMG_duan[7];temp_val[key_count]=7;
break;
case 10: key_count++; set_display[key_count]=SMG_duan[4];temp_val[key_count]=4;
break;
case 11: key_count++; set_display[key_count]=SMG_duan[1];temp_val[key_count]=1;
break;
case 12: key_count=0;
set_display[1]=0x00;
set_display[2]=0x00;
set_display[6]=0x00;
set_display[7]=0x00;
break;
case 13: key_count++; set_display[key_count]=SMG_duan[8];temp_val[key_count]=8;
break;
case 14: key_count++; set_display[key_count]=SMG_duan[5];temp_val[key_count]=5;
break;
case 15: key_count++; set_display[key_count]=SMG_duan[2];temp_val[key_count]=2;
break;
case 16:break;
case 17:break;
case 18:break;
case 19:break;
}
}
if(led_flag==0)
{
P2=0XA0;Realy=0;beep=0;P2=0X00;
}
if(led_flag==1)
{
P2=0XA0;Realy=0;beep=0;P2=0X00;
}
if(led_flag==2)
{
P2=0XA0;Realy=1;beep=0;P2=0X00;
}
}
}
void Timer0Init() //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xCD; //设置定时初值
TH1 = 0xD4; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1;
EA=1;
ET0=1;
ET1=1;
}
void Timer0() interrupt 1
{
static int key=0,led=0;
key++;
led++;
if(key>10)
{
key=0;
key_flag=1;
}
TR0=0;
if(error_flag==0)
{
if(led_flag==0)
{
if(led>800)
{
led=0;
blink_flag=~blink_flag;
}
if(blink_flag)
{
P2=0X80;P0=0xfe;P2=0X00;
}
else
{
P2=0X80;P0=0Xff;P2=0X00;
}
}
if(led_flag==1)
{
if(led>400)
{
led=0;
blink_flag=~blink_flag;
}
if(blink_flag)
{
P2=0X80;P0=0xfe;P2=0X00;
}
else
{
P2=0X80;P0=0Xff;P2=0X00;
}
}
if(led_flag==2)
{
if(led>200)
{
led=0;
blink_flag=~blink_flag;
}
if(blink_flag)
{
P2=0X80;P0=0xfe;P2=0X00;
}
else
{
P2=0X80;P0=0Xff;P2=0X00;
}
}
}
TR0=1;
}
void Timer1() interrupt 3
{
uchar i;
static unsigned int SMG_count=0;
TL1 = 0xCD; //设置定时初值
TH1 = 0xD4;
//TR1=0;
SMG_count++;
if(SMG_count==3)
{
SMG_count=0;
P2=0XC0;P0=0X00;P2=0X00;
P2=0XC0;P0=SMG_wei[i];P2=0X00;
if(set_flag==0)
{
P2=0XE0;P0=~temp_display[i];P2=0X00;
}
else
{
P2=0XE0;P0=~set_display[i];P2=0X00;
}
i++;
if(i==8)
i=0;
}
}
#define KEY P3
#define NO_KEY 0XFF //无按键按下
#define key_state0 0 //判断按键是否按下
#define key_state1 1 //确认按下
#define key_state2 2 //释放
uchar Key_init()
{
static uchar key_state=0;
uchar key_return=0,key_temp;
uchar key1,key2;
P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
if(P44==0) key1=0x70;
if(P42==0) key1=0xb0;
if(P35==0) key1=0xd0;
if(P34==0) key1=0xe0;
if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1))
key1=0xf0;
P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
if(P30==0) key2=0x0e;
if(P31==0) key2=0x0d;
if(P32==0) key2=0x0b;
if(P33==0) key2=0x07;
if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))
key2=0x0f;
key_temp=key1|key2;
switch(key_state)
{
case key_state0:
if(key_temp!=0xff)
key_state=key_state1;
break;
case key_state1:
if(key_temp!=0xff)
{
switch(key_temp)
{
case 0x77: key_return=4;break;
case 0x7b: key_return=5;break;
case 0x7d: key_return=6;break;
case 0x7e: key_return=7;break;
case 0xb7: key_return=8;break;
case 0xbb: key_return=9;break;
case 0xbd: key_return=10;break;
case 0xbe: key_return=11;break;
case 0xd7: key_return=12;break;
case 0xdb: key_return=13;break;
case 0xdd: key_return=14;break;
case 0xde: key_return=15;break;
case 0xe7: key_return=4;break;
case 0xeb: key_return=4;break;
case 0xed: key_return=4;break;
case 0xee: key_return=4;break;
}
key_state=key_state2;
}
else
key_state=key_state0;
break;
case key_state2:
if(key_temp==0xff)
key_state=key_state0;
break;
}
return key_return;
}
DS18B20温度传感器模块
#include "temperature.h"
void Delay500us();
void Delay15us();
void Delay60us();
void Delay100us();
void Delay_OneWire(unsigned int t)
{
while(t--);
}
void delayms(unsigned int ms)
{
int i,j;
for(i=0;i<=ms;i++)
for(j=845;j>0;j--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
Delay_OneWire(12);
DQ = 0;
Delay500us();
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
Delay15us();
DQ = dat&0x01;
Delay60us();
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
_nop_();
_nop_();
_nop_();
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay100us();
}
return dat;
}
void DS18b20()
{
Init_DS18B20();
delayms(1);
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Init_DS18B20();
delayms(1);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
}
int temp_get()
{
unsigned char low,high;
unsigned char temp;
DS18b20();
low=Read_DS18B20();
high=Read_DS18B20();
temp=high<<4;
temp|=low>>4;
return temp;
}
void Delay500us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 6;
j = 93;
do
{
while (--j);
} while (--i);
}
void Delay15us() //@11.0592MHz
{
unsigned char i;
i = 39;
while (--i);
}
void Delay60us() //@11.0592MHz
{
unsigned char i, j;
i = 1;
j = 162;
do
{
while (--j);
} while (--i);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
以上就是代码全部内容,欢迎交流,共同学习~