2018.电子系统综合设计报告
摘要:
目标是设计一个基于MCS-51单片机的温度控制器,温度测量范围为0到100度,且保证精度误差正负1°;通过四位七段LED数码管来实时显示温度;温度控制器采用智能PID控制,当通热电阻采集的被测温度偏离所希望的给定值时,温度控制器可根据测量信号与给定值的偏差从而控制继电器通断比率,促使测量值恢复到给定值,达到自动控制的效果;控制器还具有上、下限温度告警和继电器输出功能。通过实验箱上的按键还可以返回温度值及学号等参数到显示器上。
关键字:单片机 温度传感器 温度控制 控制器
1 前言
2 系统设计
2.1 系统方案设计
2.2 基本要求
3 理论分析与计算
3.1 调理电路
4 系统电路设计
4.2 A/D转换电路
4.3 89C51RD+
4.3.1 功能
4.4四段数码管
4.4.1数码管…
4.5 电路功能…
4.5.1按键…
5软件设计
5.1主函数
5.2 A/D转换
5.3子程序
6系统测试
5.1系统功能
5.2理论与实际对比
7小结和体会
8参考文献
9附录
8.1主要参考元器件及实验箱…
8.2课程设计总电路…
1前言
本次设计的目标是要设计一个基于单片机的简易数字式温度计,其能对温度进行相对准确的测量,并且具备一些按键返回和判断上下限的功能;故设计中要解决的首要主要问题是对于由各个元器件组成的电路模块需要具有较深刻的认识,并将这些电路连接成可以实现仿真的完整电路;这要求我们要掌握各个元器件的参数原理及引脚连接,本次电路主要有信号调理电路、AD电路、动态显示电路、温度设定电路、继电器驱动电路、串口通信电路等;其次是要编写出对应的定时器工作方式,计数初值的设定,对应中断源开启,中断优先级,以及按键返回的程序,并将程序烧录进单片机中;这要求我们源程序的编写能力与Keil软件的使用有较深的认识,并能上手操作;由于本次设计的温度计是根据信号调理电路中电压与电阻的关系来反馈的故也需要先测量电压与温度的关系,还应注意信号调理电路中电阻的选用要根据热电阻的不同斟酌选取;最后就是面包板上具体的线路连接以及单片机开发板上的具体测试;连接面包板时要细心,不能急躁,而且要注意线路的排布,防止短路或断路的现象发生,最后的测试阶段要认真根据实验结果的反馈寻找线路或者程序的错误,及时纠正。
2 系统设计
2.1系统方案设计
2.1.1
方案一:采用了最简单的方式,就是将传感器输出的信号,经过D/A转换后直接显示。
方案二:
采用DS18B20来采集温度,DS18B20是采用1—wire总接口的数字温度计,测量温度范围为-55℃—+125℃,精度可达到0.0675℃,最大转换时间为200ns。这器件可用一根引与处理器相连,以串行方式将数据送到处理器,经处理器处理后直接显示。
方案三:
采用pt100热电阻作为温度采集的传感器,把采集到的温度直接送到单片机,经过单片机处理后送到显示器,显示器将显示采集的温度。
2.1.2方案比较
(1)控制部分
方案二、三都采用了单片机作为控制,作为一种新型的微处理器,可以通过智能编程的方式,可以进行扩展,而且能够具有超温报警和自动控制功能。而方案一没有采用控制,直接把温度显示出来就完了。这样就只能完成对温度的显示。
(2)传感器部分
方案一、三的传感器可以选一样,可以选热敏电阻和其它的传感器,但我们这里选用了pt100。方案二采用的传感器是DS18B20,这种传感器虽然硬件简单,但是成本较高。所以没有采用这种传感器。
(3)显示部分
方案一采用的是一种将十进制转换成七段码的ADC,可以采用ICL7106来将采集到的温度进行显示,这种方案很简单,但是它的可控性很差,只能进行显示。方案二、三都是采用了单片机在内部远算之后,才由显示部分显示出来。
2.3 方案选择
在上面几种方案中,虽然它们各自有自已的优点,特别是第二种方案,它的硬件很简单,只要把程序写好,就能够运行了。可是为了将学的知识系统的组合起来,我选择第三种方案,此方案不仅用到了单片机,还用到了模电和数点知识。系统很容易进行扩展。
2.1.3仿真电路图
2.1.4温控仪设计文字说明
温度传感器输出为电阻值,经信号调理电路得到电压值,再经AD转换电路实现数模转换。由单片机控制显示管输出。除此,可设置预置温度,通过单片机外部中断,用按键控制预置温度。当实际温度高于预置温度,红灯亮;低于时,则绿灯亮。
A/D采集电路: 启动、等待、采集数据。单片机电路:最小系统。键盘及显示电路:键盘数据输入和温度显示。输出控制电路:I/O驱动、继电器、指示灯、负载。
2.2基本要求
主要技术指标
(1)测量范围:0 ℃ ~ +100℃;
测温精度:1℃;
(2)温度采样时间:500ms ~1min (可调);
(3)实时温度显示(四位七段LED数码管);
(4)温度控制方式:继电器通、断(驱动降温或加热负载);
(5)超温报警:声、光报警;
(6)键盘功能:上下限温度值设定(温度+键、温度- 键、菜单键、确认键);
(7)通信接口:RS232;
波特率:9600;
通信格式:自定义;
(8)采用模拟和数字两种温度传感器设计双通道温度控制装置(提高部分)。
3 理论分析与计算
3.1调理电路
3.1.1电路功能
利用桥式整流电路实现电阻值到电压值的转换,并用OP07放大电压。电阻与温度关系如下:
温度与电阻的关系:
温度分段与电压的拟合曲线:(57℃到73℃)
温度分段与电压的拟合曲线:(40℃到56℃)
温度分段与电压的拟合曲线:(27℃到39℃)
4.系统电路设计
4.1调理电路
4.2 A/D转换电路
4.2.1 电路功能
单片机只能处理二进制信号
因此必须用A/D转换电路将纹理电路输出的模拟量转换成数字量,供单片机处理。
(1)IN0~IN7——8路模拟输入,通过3根地址译码线ADDA、ADDB、ADDC来选通一路。
(2)D7~D0——A/D转换后的数据输出端,为三态可控输出,故可直接和微处理器数据线连接。8位排列顺序是D7为最高位,D0为最低位。
(3)ADDA、ADDB、ADDC——模拟通道选择地址信号,ADDA为低位,ADDC为高位。地址信号与选中通道对应关系如表11.3所示。
(4)VR(+)、VR(-)——正、负参考电压输入端,用于提供片内DAC电阻网络的基准电压。在单极性输入时,VR(+)=5V,VR(-)=0V;双极性输入时,VR(+)、VR(-)分别接正、负极性的参考电压。
(5)ALE——地址锁存允许信号,高电平有效。当此信号有效时,A、B、C
三位地址信号被锁存,译码选通对应模拟通道。在使用时,该信号常和START信号连在一起,以便同时锁存通道地址和启动A/D转换。
(6)START——A/D转换启动信号,正脉冲有效。加于该端的脉冲的上升沿使逐次逼近寄存器清零,下降沿开始A/D转换。如正在进行转换时又接到新的启动脉冲,则原来的转换进程被中止,重新从头开始转换。
(7)EOC——转换结束信号,高电平有效。该信号在A/D转换过程中为低电平,其余时间为高电平。该信号可作为被CPU查询的状态信号,也可作为对CPU的中断请求信号。在需要对某个模拟量不断采样、转换的情况下,EOC也可作为启动信号反馈接到START端,但在刚加电时需由外电路第一次启动。
(8)OE——输出允许信号,高电平有效。当微处理器送出该信号时,ADC0808/0809的输出三态门被打开,使转换结果通过数据总线被读走。在中断工作方式下,该信号往往是CPU发出的中断请求响应信号。
4.3 89C51RD+
4.3.1功能
作为设计核心,协调各功能模块,是软件载体。
管脚图:
单片机I/O接口功能定义:
P0: AD数据采集;
P1:数码管段选信号(a,b,c,d,e,f,g);
P2.7、RD: A/D数据输出容许信号OE;
P2.7、WR:启动A/D;
P3.4 ~ P3.5:指示灯1,指示灯2 ;
P2.0~ P2.3 :数码管位选信号(1,2,3,4);
INT0: 模式选择键
4.4四段数码管
4.4.1数码管
显示实际温度和预置温度,采用动态显示
引脚说明:
4.4.2ULN2003A
驱动负载与数码管联接
4.5电路功能
4.5.1按键
通过按键控制预置温度,并且能在数码管显示。
3.5.2负载
当温度高于预设温度时,红灯亮。当温度低于预设温度时,绿灯会亮。
5 软件设计
5.1主函数
void main(void)
{
byte temp;
red=0;green=0;
l=10;
init();
while(1)
{
if(flag1==1)
{
flag1=0;
result=samp();
jisuan(result);
}
switch(flag2)
{
case 0: display(T);break;
case 1: displayH(sdH);
sdH=anjian(sdH);
break;
case 2: temp=sdL;
temp=anjian(temp);
if(temp>sdH)
{displayL(temp);
sdL=sdH;}
else {displayL(temp);
sdL=temp;}
break;
}
jidianqi();
chuankou(T);
}
}
5.2 AD转换
float samp()
{
PIN0=0xff; //启动A/D
for(i=0;i<0x9f;i++); //延时等待
result_reg=PIN0; //读取A/D转换结果
result=result_reg*5/255;
return result;
}
void jisuan(float result)
{
if(result>1.28&&result<1.95)
{T=16.604*result+6.6513;}
else if(result>2.03&&result<2.81)
{T=20.143*result-0.5804;}
else if(result>2.86&&result<3.4)
{ T=29.049*result-26.555;} //把电压转换为温度
}
5.3子程序
#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#define PIN0 XBYTE[0X7FF8] //ADC0809的绝对地址
typedef unsigned char byte;
typedef unsigned int word;
unsigned char xuehao[]="170210465";
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff}; //数码管熄灭
sbit int0=P3^2; //调整设定温度和显示当前温度转换
sbit green=P3^4; //加热电阻丝
sbit red=P3^5; //风扇
sbit ck=P2^4; //串口发送开关
sbit jia=P2^5;
sbit jian=P2^6;
byte l,m,flag1,flag2=0;
byte T,sdH=50,sdL=40; //设定温度
float result=0;
float result_reg;
byte i;
/*****************************************************
函数名:延时子函数
调 用:delay(?)
参 数:延时时长
返回值:无
结 果:延时
备 注:无
******************************************************/
void delay(int n)
{ word m;
for(m=0;m<n;m++);
}
/*****************************************************
函数名:初始化子函数
调 用:init()
参 数:无
返回值:无
结 果:对外部中断0,外部中断1,定时器中断0和串口寄存器进行初始化
备 注:无
*******************************************************/
void init()
{ TMOD=0X01;
TH0=(65536-50000)/256; //定时器0计数初值设置,0.5秒定时
TL0=(65536-50000)%256;
EX0=1; EX1=1;ET0=1;
PX0=0;PX1=0;
PT0=1;PT1=1;
EA=1;TR0=1;
IT1=1;IT0=1;
}
/*****************************************************
函数名:AD采集电压子程序
调 用:samp()
参 数:无
返回值:采集到的电压值模拟量
结 果:采集电压
备 注:无
*******************************************************/
float samp()
{ PIN0=0xFF;
for(i=0;i<0x9f;i++);
result_reg=PIN0;
result=result_reg*5/255;
return result;
}
/*****************************************************
函数名:电压转换为温度子函数
调 用:jisuan(?)
参 数:采集的电压值
返回值:无
结 果:得到当前温度的十位和个位,以及设定温度的十位和个位
备 注:无
*******************************************************/
void jisuan(float result)
{ if (result>2.04&&result<3.7)
{T= 19.329*result+ 20.611;}
if (T>60)
{T= 19.329*result+ 17.611;}
else
T= 19.329*result+ 21.611;
} //把电压转换为温度
/*****************************************************
函数名:继电器驱动发光二极管子函数
调 用:jidianqi()
参 数:无
返回值:无
结 果:当前温度>设定温度,红灯亮;当前温度<设定温度,绿灯亮
备 注:无
*******************************************************/
void jidianqi()
{ if(T>sdH){red=1;green=0;}
else if(T<sdL){red=0;green=1;}
else {red=1;green=1;}
}
/******************************************************
函数名:动态显示
调 用:display(?,?,?)
参 数:当前温度的十位,个位和大写C
返回值:无
结 果:数码管动态显示温度
备 注:无
*******************************************************/
void display(word temp)
{ unsigned char a,b;
a=temp/10;
b=temp%10;
P1=0xff;P2=0xf7;
P1=tab[12];//显示大写'C'
delay(100);
P1=0xff;P2=0xfb;
P1=0x9c;//显示'o'
delay(100);
P2=0xfe;P1=tab[a];
delay(100);
P2=0xfd;P1=tab[b];
delay(100);
}
void displayH(byte wendu)
{ unsigned char a,b;
a=wendu/10;
b=wendu%10;
P1=0xff;P2=0xf7;
P1=0x89;//显示大写'H'
delay(100);
P1=0xff;P2=0xfb;
P1=0xbf;//显示大写'-'
delay(100);
P1=0xff;P2=0xfd;
P1=tab[b];
delay(100);
P1=0xff;P2=0xfe;
P1=tab[a];
delay(100);
P1=0xff;
}
void displayL(byte wendu)
{ unsigned char a,b;
a=wendu/10;
b=wendu%10;
P1=0xff;P2=0xf7;
P1=0xc7;//显示大写'L'
delay(100);
P1=0xff;P2=0xfb;
P1=0xbf;//显示大写'-'
delay(100);
P1=0xff;P2=0xfd;
P1=tab[b];
delay(100);
P1=0xff;P2=0xfe;
P1=tab[a];
delay(100);
P1=0xff;
}
byte anjian(byte wendu)
{ if(jia==0)
{delay(100);
if(jia==0)
{wendu++;
if(wendu>100)wendu=100;
}
}
while(!jia);
if(jian==0)
{delay(100);
if(jian==0)
{wendu--;
if(wendu<0)wendu=0;
}
}
while(!jian);
return wendu;
}
/******************************************************
函数名:串口发送函数
调 用:chuankou (?,?)
参 数:发送当前温度的十位和个位
返回值:无
结 果:向PC机发送当前温度
备 注:无
*******************************************************/
void chuankou(byte wendu)
{ unsigned char a,b;
char t=0;
if(ck==0)
{delay(100);
if(ck==0)
{TMOD=0X21;
SCON=0X40; //串口工作于方式1
PCON=0;
TH1=0xFD; //设置波特率为9600
TL1=0xFD;
TR1=1;
a=(byte)wendu/10;
b=(byte)wendu%10;
SBUF=0x30+a;while(!TI);TI=0;
SBUF=0x30+b;while(!TI);TI=0;
SBUF='C';while(!TI);TI=0;
for(t=0;t<9;t++)
{SBUF=xuehao[t];while(!TI);TI=0;}
SBUF=' ';while(!TI);TI=0;
TR1=0;
}
}
while(!ck);
}
/******************************************************
函数名:主函数
调 用:main()
参 数:无
返回值:无
结 果:0.5秒采集电压,并显示,可调设定温度,按键发送当前温度给PC机
备 注:无
*******************************************************/
void main(void)
{ byte temp;
red=0;green=0;
l=10;
init();
while(1)
{if(flag1==1)
{ flag1=0;
result=samp();
jisuan(result);
}
switch(flag2)
{ case 0: display(T);break;
case 1: displayH(sdH);sdH=anjian(sdH);break;
case 2: temp=sdL;temp=anjian(temp);
if(temp>sdH)
{displayL(temp);
sdL=sdH;}
else
{displayL(temp);
sdL=temp;}
break;
}
jidianqi();
chuankou(T);
jisuan(result);
}
}
/******************************************************
函数名:t0定时器中断函数
参 数:无
返回值:无
结 果:0.5秒定时
备 注:无
*******************************************************/
void t0() interrupt 1 using 1
{ TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
l--;
if(l==0)
{flag1=1;l=10;}
}
/******************************************************
函数名:外部中断0中断函数
参 数:无
返回值:无
结 果:模式选择
备 注:无
*******************************************************/
void int00() interrupt 0
{ if(int0==0)
{delay(30);
if(int0==0)
{ flag2++;
if(flag2==3)flag2=0;
}
}
}
6 系统测试
6.1系统功能
通过传感器对温度的感知,测试得到电阻量,再由调理电路转换成电压量,进过A/D转换变为单片机能够处理的二进制。在单片机处理中,将实际测得的温度与设置的预设温度都能在数码管上显示,通过按键可以改变预置温度。如果实际温度小于预设温度时,绿灯会亮;如果实际温度大于预设温度时,红灯会亮。
6.2理论与实际误差
通过实际温度计读数与数码管显示温度对比,存在1度左右的误差。
7小结与体会
本次电子系统综合设计是简易温度控制仪,利用已学的单片机等一些专业知识,来独立完成设计。在实验过程中,我遇到了很多的困难。但是经过与小组成员的讨论以及请教老师都一一解决了。比如说,温度传感器一开始接到二号管脚,但实际应该与二号管脚出来的电阻相连,经过修改解决了这一问题,到了最终测试,我的误差并不能控制在一度以内,于是我就修改了自己的拟合函数,一点一点的减小误差,最终达到了实验的要求。这令我感到很满足。与小组成员的合作,测试温度都让我感觉到了团队的力量。
本次课程设计让我将学到的理论联系实际,理论再也不是纸上谈兵。遇到困难时,同学之间相互讨论解决大大提高了实验效率。
9 附录:
9.1 主要参考元器件及实验箱
- 89C51RD+
- AD0809
- OP07A
- MAX232
- 驱动器ULN2003A
- 四联数码管MT0546AR
- 发光二极管(红、绿色)
- 温度传感器、玻璃温度计
- 面包板、连接线、插头座
10.51单片机实验箱
9.2课程设计总电路
本文地址:https://blog.csdn.net/weixin_45281843/article/details/109242622