单片机课程设计——多路温度巡回检测仪的设计及单片机实验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机课程设计
——多路温度巡回检测仪的设计及单片机实验
姓名:东京的樱花
学号:10090####
设计题目:7、多路温度巡回检测仪
指导老师:潘#
楼主造福东华学子啦,后面程序可以直接运行哦
目录
1、项目设计要求 (3)
2、方案可行性分析........................................................ ........................................................ (3)
3、硬件电路设计........................................................ ........................................................ (4)
(1)、铂电阻测量单元........................................................ (4)
(2)、按键控制单元........................................................ (5)
(3)、AD转换单元........................................................ (6)
(4)、LED数码管显示单元........................................................ (7)
(5)、数据传输上位机单元........................................................ (8)
4、整体硬件设计连接图........................................................ (9)
5、软件设计........................................................ ........................................................ (10)
(1)、软件设计思想........................................................ (10)
(2)、程序流程图........................................................ (11)
(3)、程序清单........................................................ (12)
5、电路pcb原理图及pcb图设计........................................................ (13)
6、系统protues仿真及调试........................................................ (15)
7、结果与展望........................................................ ........................................................ (16)
9、参考文献........................................................ ........................................................ (16)
10、附录:程序源代码+ pcb 3d模拟图 (16)
1、项目设计要求
题7 多路温度巡回检测仪的设计
设计一个多路温度检测仪,共有8个测温点,每个点连续检测8次,以平均值代表该点温度,并轮流在LED显示器上显示。

测试检测元件为铂热电阻Pt1000, 温度测量范围为100℃——+500℃,测量精度为±1℃。

系统每隔10秒完成一个点的测量,测量值除在LED显示器上显示外,还必须通过串行口(RS485)发送到上位机。

任何时刻,可以通过按键切换显示通道。

2、方案可行性分析
在测温系统中,用温度敏感元件通过电路的调整可以把温度信号转换为模拟电压信号,在将模拟电压信号远距离传输并通过A/D转换得到相应的数字信号,通过程序进行处理得到实时的温度数值。

铂热电阻测量范围为-200~850℃,R0有10Ω、100Ω和1000Ω三种,分度号分别为Pt10、Pt100和Pt1000。

铂热电阻的精度高,体积小,测温范围宽,稳定性好,再现性好,但是价格较贵。

其电阻与温度的关系为:
当T≥0℃时 R(T)= R0(1+AT+BT²)
当T< 0℃时 R(T)= R0 [1+AT+BT²+CT³(T-100)]
式中: R T为被测温度T下的阻值,单位为Ω
R0为0℃下的阻值
T为实际温度值
A为常数3.9083×10ˉ³/℃
B为常数-5.775×10ˉ7/℃²
C为常数-4.183×10ˉ12/℃4
由于我们要测得温度是100-500,所以,不用考虑小于0的情况了。

所以公式为:R(T)= R0(1+AT+BT²)
由数学知识可以直接解出T=(-A-sqrt(A^2-4*B(1-R(t)/R0)))/2B (1)
因为A、B、R(0)已知,所以只要测到R(t)就能够算出T。

所以我们将测量电阻上的电压来算出电阻的阻值,进而得出他现在的温度。

2、硬件电路设计
(1)、铂电阻测量单元
设计思想:
铂金属的阻值会随着温度变化而变化,所以可以通过测量它的电阻来确定温度。

我们可以通过串接另一个阻值已知的电阻通过电压的变化而确定铂金属的阻值。

由电路知识求得:RV9=3*u/(5-u)………………………….(2)式
(2)、按键控制单元
设计思想:
由于有八路信号,所以可以用3*3的矩阵键盘,或者用8各独立的键盘来控制八路信号。

我这里由于简化设计就用了8个独立的键盘控制。

低电平有效。

(3)、AD转换单元
设计思想:
由于精度要求+-1度,从100-500所以有400个档位,所以要9位(512)或者9位以上的AD转换器才能实现这个精度。

我这里使用了TLC1543,这个ad芯片的精度很高,为10位串行逐步逼近型AD转换器(1024)。

所以能精确到0.4度。

其工作过程分为两个周期:访问周期和采样周期。

(4)、LED数码管显示单元
设计思想:
LED接收来自p0口的数据信号与地址信号,通过地址锁存,分时复用来实现LED 数码管的动态显示,我这里用74ls373来作为锁存器,来锁住数据与地址信息。

(5)、数据传输上位机单元
设计思想:
由于rs232传输的距离有限,所以我们这里使用传输距离更远的rs485。

Max485位一款rs485。

但是由于485电平和rs232电平不符,所以,当我们连接计算机的时候还是要接上max232用来转换电平。

4、整体硬件设计连接图
软件设计
(1)、软件设计思想
在本次设计中,mcu主要的工作是将ad采集来的数据,通过一定的计算转化成为温度的值,并且将这个值通过p0口输出到led数码管上。

在循环扫描八个检测点的时候,顺便扫描按键部分,看有没有按键被按下,按下则进入按键服务程序,执行按键指定的测量。

并通过串口传输到上位机上。

由于软件源代码过长,这里简略的写ad部分(详细软件部分见附录)
uint ADC(uchar chn1)
{
uchar i;
uchar addr8;
uint ADresult;
AD_eoc=1;
AD_cs=0;
_nop_();
addr8=chn1;
addr8<<=4;
for(i=0;i<4;i++)//写地址
{
AD_add=(bit)(addr8&0x80);
AD_clk=1;
AD_clk=0;
addr8<<=1;
}
for(i=0;i<6;i++) //采样
{
AD_clk=1;
AD_clk=0;
}
AD_cs=1;
while(!AD_eoc);//查询
_nop_();
ADresult=0;
AD_cs=0; //移位传数据
for(i=0;i<10;i++)
{
AD_clk=1;
ADresult<<=1;
m=AD_dat;
ADresult+=m;
AD_clk=0;
}
AD_cs=1;
return(ADresult); }
(2)、程序流程图
(3)、程序清单
void delay(uint z)
延时z 毫秒
void display(num)
显示子程序,显示num和数据
uint ADC(uchar chn1)
AD转换子程序,负责转化模拟信号位数字信号
void Send(unsigned char dat)
串口发送子程序,负责将收集到的数据发送到上位机上
void jianpan(void)
键盘检测子程序,负责不断地扫描键盘,看是否有键盘按下
void main()
主函数
5、电路pcb原理图及pcb图设计
用altium designer6.9设计并做出原理图
pcb图设计
画好原理图后电器检查通过后编译,并design-updatato pcb 再布局布线覆铜。

6、系统protues仿真及调试
通过protues仿真,可以了解自己的电路到底能不跑起来,大部分的原件还是找得到的,就是不知道叫什么名字,所以在百度里查查名字后再连线,之后就是通过keil来编译生成的hex文件烧到mcu中去。

8、结果与展望
通过本次课程设计,我更深刻理解了单片机,特别是51系列的单片机。

当然,我也了解了一点avr的知识。

Avr价格上面还是有点高,所以现在51单片机还是有很大的市场的。

但是51的引脚比较少,所以还是主要用于简单的控制上面。

对于我们大自动化的学生,我们可不要认为会51就好了,至少得学个arm cortex-m3吧。

对于有追求,有理想的学生,我们更应该好好学习arm9的内容,以及linux系统。

要是更高级的话,x86芯片也可以去研究。

可是学校给我们做实验的机会太少了。

就那几台设备,而且课内充满做一下,都不到在干什么。

对于实验室,我只能说,粥少僧多啊。

主要还是没有实验室地皮的问题。

建议扩展地皮,要建一个自由实验室,以用来给买不起试验设备的学子一个做实验的平台。

我们应该做的是扬长避短,发挥所长,为社会做贡献。

9、参考文献
《郭天祥10天学会单片机》视频
《mcs-51单片机原理与应用》张毅刚刘杰哈尔滨工业大学出版社
《郭天祥10天学会PCB教程》视频
10、附录:程序源代码+ pcb 3d模拟图(见附录)附录
#include <reg52.h>
#include<intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
uint num;
float num1;
int keyval;
int o;
int i;
int q;
int rt;
int tr;
double n2;
uchar port,m;
uchar ge,shi,bai,qian;
sbit wela=P2^7;
int sy;
sbit dula=P2^6;
uchar led[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; sbit AD_eoc=P1^0;
sbit AD_clk=P1^1;
sbit AD_add=P1^2;
sbit AD_dat=P1^3;
sbit AD_cs=P1^4;
sbit S1=P3^5; //将S1位定义为P1.4引脚
sbit S2=P3^4;
sbit S3=P2^0;
sbit S4=P2^1;
sbit S5=P2^2;
sbit S6=P2^3;
sbit S7=P2^4;
sbit S8=P2^5;
void delay(uint z)
{
uint k;
for(z;z>0;z--)
for(k=1000;k>0;k--);
}
void display(num)
{
n2=num;
n2=n2*5/1024;
n2=(3*n2)/(5-n2)*1000;//r1=3k电压求电阻
n2=3383.8-8.658*(sqrt(175850-23.1*n2)) ;
sy=n2;
bai=sy/100%10;
shi=sy/10%10;
ge=sy%10;
P0=0xff;
wela=1;
wela=0;
P0=led[bai];
dula=1;
dula=0;
P0=0Xf7;
wela=1;
wela=0;
delay(1);
P0=0xff;
wela=1;
wela=0;
P0=led[shi];
dula=1;
dula=0;
P0=0xef;
wela=1;
wela=0;
delay(1);
P0=0xff;
wela=1;
wela=0;
P0=led[ge];
dula=1;
dula=0;
P0=0xdf;
wela=1;
wela=0;
delay(1);
P0=0xff;
wela=1;
wela=0;
P0=o;
dula=1;
dula=0;
P0=0xfe; //显示哪一路标号wela=1;
wela=0;
delay(1);
}
uint ADC(uchar chn1)
{
uchar i;
uchar addr8;
uint ADresult;
AD_eoc=1;
AD_cs=0;
_nop_();
addr8=chn1;
addr8<<=4;
for(i=0;i<4;i++)//写地址
{
AD_add=(bit)(addr8&0x80);
AD_clk=1;
AD_clk=0;
addr8<<=1;
}
for(i=0;i<6;i++) //采样
{
AD_clk=1;
AD_clk=0;
}
AD_cs=1;
while(!AD_eoc);//查询
_nop_();
ADresult=0;
AD_cs=0; //移位传数据
for(i=0;i<10;i++)
{
AD_clk=1;
ADresult<<=1;
m=AD_dat;
ADresult+=m;
AD_clk=0;
}
AD_cs=1;
return(ADresult);
}
void Send(unsigned char dat)
{
SBUF=dat;
while(TI==0)
;
TI=0;
}
void delay5(void)
{
unsigned char m,n;
for(m=0;m<200;m++)
for(n=0;n<250;n++)
;
}
void jianpan(void)
{
if(S1==0) //按键S1被按下
{ tr=0;
for(rt=0;rt<10;rt++)
{port=0x0a; o=led[1];
num=ADC(port); tr=num+tr;}
num=tr/10;
for(q=0;q<50;q++){ display(num);}
Send(led[bai]); Send(led[shi]); Send(led[ge]); //发送数据
tr=0;
}
if(S2==0)
{ keyval=2;
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x09; o=led[2];
num=ADC(port);tr=num+tr;}
num=tr/10; for (q=0;q<50;q++) {display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;}
if(S3==0)
{keyval=3; tr=0;
for(rt=0;rt<10;rt++)
{ port=0x08; o=led[3];
num=ADC(port);tr=num+tr; } num=tr/10;
for (q=0;q<50;q++){ display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]); }
tr=0; }
if(S4==0)
{ keyval=4; tr=0;
for(rt=0;rt<10;rt++)
{ port=0x07; o=led[4];
num=ADC(port);tr=num+tr;} num=tr/10;
for (q=0;q<50;q++){ display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
}
if(S5==0)
{ tr=0; for(rt=0;rt<10;rt++)
{ port=0x06; o=led[5];
num=ADC(port); tr=num+tr;} num=tr/10;
for (rt=0;rt<50;rt++){ display(num); } Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0; }
if(S6==0)
{ tr=0; for(rt=0;rt<10;rt++) { port=0x05; o=led[6];
num=ADC(port); tr=num+tr;} num=tr/10;
for (q=0;q<50;q++){ display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
}
if(S7==0)
{ tr=0; for(rt=0;rt<10;rt++)
{ port=0x04; o=led[7];
num=ADC(port); tr=num+tr;} num=tr/10;
for (q=0;q<50;q++){ display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0; }
if(S8==0)
{ tr=0; for(rt=0;rt<10;rt++)
{ port=0x03; o=led[8];
num=ADC(port);tr=num+tr; } num=tr/10;
for (q=0;q<50;q++){ display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
o=led[1]; }
;
}
void main()
{
TMOD=0x20; //TMOD=0010 0000B,定时器T1工作于方式2 SCON=0x40; //SCON=0100 0000B,串口工作方式1
PCON=0x00; //PCON=0000 0000B,波特率9600
TH1=0xfd; //根据规定给定时器T1赋初值
TL1=0xfd; //根据规定给定时器T1赋初值
TR1=1; //启动定时器T1
while(1)
{ jianpan();
tr=0;
for(rt=0;rt<10;rt++)
{port=0x0a; o=led[1];
num=ADC(port); tr=num+tr;jianpan();
}
num=tr/10;
for(q=0;q<20;q++){ display(num);jianpan();}
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x09;
jianpan();
o=led[2];
num=ADC(port);tr=num+tr;}
num=tr/10; for (q=0;q<30;q++) {jianpan();display(num); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x08; o=led[3];jianpan();
num=ADC(port);tr=num+tr; } num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x07; o=led[4]; jianpan();
num=ADC(port);tr=num+tr;} num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x06; o=led[5]; jianpan();
num=ADC(port);tr=num+tr;} num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x05; o=led[6]; jianpan();
num=ADC(port); tr=num+tr;} num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x04; o=led[7]; jianpan();
num=ADC(port); tr=num+tr;} num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
tr=0;
for(rt=0;rt<10;rt++)
{ port=0x03; o=led[8]; jianpan();
num=ADC(port);tr=num+tr; } num=tr/10;
for (q=0;q<30;q++){ display(num); jianpan(); }
Send(led[bai]); Send(led[shi]); Send(led[ge]);
o=led[1];
}
}。

相关文档
最新文档