|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
综合运用测控仪器设计相关章节基础知识,设计一套温度测量控制装置。
: |6 `0 p1 _4 ]/ O7 f' l. n4 ?" A- h: K" I' Y' A& i* Y
2.思路分析
$ D3 X) \+ `: t( j: W% s设计单片机(AT89C52)最小系统,并在此基础上完成对温度传感器DS18B20的读写操作,实现温度测量功能和实时显示功能,并通过设计外部电路使系统具备温度上下限设置、对超过(低于)设置温度值的状态进行报警和相应控制操作。
0 M1 c7 X2 W+ S; d5 V8 }; y3.系统功能
5 h3 T: i* l* o. R/ X" G- f' l6 r (1)采集温度,并通过LED数码管显示当前温度。LED数码管显示温度格式为四位,精确度可达±0.1℃。例如:27℃显示为27.0。
, F5 _8 @) ~( M' N* S% o/ k(2)通过按键可自由设定温度的上下限,并能在LED数码管显示设定的温度上下限值。4 \/ w" v7 f+ H! K& q# E- W
(3)通过控制三极管的导通与否来控制继电器的通断,继而控制外部加热(电烙铁升温)和制冷(电风扇降温)装置,使环境温度保持在设定温度范围内。/ w0 s( k2 s* ^2 A8 T9 r# j: D
(4)具有温度报警装置。当温度高于上限值,红灯亮起;或者低于下限值,黄灯亮起,并发出报警声。0 g# w6 a4 |5 l" k5 G
; ~5 k* E* Y+ V7 X. [$ _% d) H4.protues原理图:( Y+ S- m" ?3 \+ i$ R# |( G o9 k$ w
! q# |0 I. \7 ?8 m% v
. K d& d: Y8 i7 D% Y4 p. D
仿真原理图如下:
0 ~0 A, r* \* u5 N( d9 x![]()
5 o2 N! _8 r9 x/ S, S
9 ^- j1 L n$ D! R. k) y单片机源程序如下:2 ~/ ]4 Q) I) u! T
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit DQ=P3^0;
- sbit en=P1^0;
- sbit add=P1^1; //加1
- sbit jian=P1^2; //减1
- sbit wARM=P1^5; //加热
- sbit cool=P1^7; //制冷
- uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; //共阳极
- uchar code smg_we[]={0x08,0x04,0x02,0x01};
- uchar uflag,max=35,min=20,k;
- uint value,b_value;
- /*** 小延时函数 ***/
- void delay(uint i)
- {
- while(i--);
- }
- /*** 延时函数 ***/
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /*** DS18B20初始化函数 ***/
- void init_ds18b20()
- {
- uchar presence;
- DQ=0;
- delay(60);
- DQ=1;
- delay(5);
- presence=DQ;
- delay(20);
- }
- /*** 写入一个字节 ***/
- void write_ds18b20(uchar value)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=value&0x01;
- delay(5);
- DQ=1;
- value>>=1;
- }
- delay(4);
- }
- /*** 读出一个字节函数 ***/
- uchar read_ds18b20()
- {
- uchar j,val;
- for(j=0;j<8;j++)
- {
- DQ=0;
- val>>=1; //读数先读最低位,故右移
- DQ=1;
- if(DQ)
- val|=0x80;
- delay(4);
- }
- return val;
- }
- /*** 读温度函数 ***/
- uint read_temperature()
- {
- uchar a,a0,flag;
- uint b;
- uint temp;
- init_ds18b20(); //开始转化数据
- write_ds18b20(0xcc);
- write_ds18b20(0x44);
- delay(300);
- init_ds18b20(); //每操作一次都初始化并且至少有一条ROM指令
- write_ds18b20(0xcc);
- write_ds18b20(0xbe); //读数据允许
- a=read_ds18b20(); //低8位
- a0=read_ds18b20(); //高8位
- flag=a0&0xf8;
- b=a0*256+a;
- if(flag==0xf8)
- {
- uflag=0;
- temp=(~b+1)*0.625; // 负数取反再加1
- }
- else
- {
- uflag=1;
- temp=b*0.625;
- }
- return temp;
- }
- /*** 显示当前温度 ***/
- void display()
- {
- uchar i;
- value=read_temperature();
- b_value=value/10; //实时温度
- if(uflag==1)
- {
- for(i=0;i<4;i++)
- {
- P2=smg_we;
- delay(10);
- switch(i)
- {
- case 0
0=smg_du[value/1000];break; - case 1
0=smg_du[value%1000/100];break; - case 2
0=smg_du[value%100/10]&0x7f;break; - case 3:P0=smg_du[value%10];break;
- default: break;
- }
- delay(950);
- }
- }
- else
- {
- for(i=0;i<4;i++)
- {
- P2=smg_we;
- delay(10);
- switch(i)
- {
- case 0:P0=smg_du[10];break; //写“-”号
- case 1:P0=smg_du[value%1000/100];break;
- case 2:P0=smg_du[value%100/10]&0x7f;break;
- case 3:P0=smg_du[value%10];break;
- default: break;
- }
- delay(950);
- }
- }
- if(b_value>max) cool=0; //降温
- else cool=1;
- if(b_value<min) warm=0; //加热
- else warm=1;
- }
- /*** 按键处理 ***/
- void keyscan()
- {
- en=1;
- if(en==0)
- {
- delay_ms(6); //5~10ms
- if(en==0)
- {
- k++;
- if(k==3) k=0;
- while(!en);
- }
- }
- }
- /*** 调节上下限时的显示 ***/
- void con_display(uchar dat)
- {
- uchar i;
- for(i=2;i<4;i++)
- {
- P2=smg_we;
- delay(10);
- switch(i)
- {
- case 2:P0=smg_du[dat/10];break;
- case 3:P0=smg_du[dat%10];break;
- default: break;
- }
- delay(950);
- }
- }
- /*** 加热与降温 ***/
- void control()
- {
- if(k==1) //控制MAX
- {
- con_display(max);
- add=1; //+1
- if(add==0)
- {
- delay_ms(6); //5~10ms
- if(add==0)
- {
- max++;
- while(!add);
- }
- }
- jian=1; //-1
- if(jian==0)
- {
- delay_ms(6); //5~10ms
- if(jian==0)
- {
- max--;
- while(!jian);
- }
- }
- }
- if(k==2) //控制MIN
- {
- con_display(min);
- add=1; //+1
- if(add==0)
- {
- delay_ms(6); //5~10ms
- if(add==0)
- {
- min++;
- while(!add);
- }
- }
- jian=1; //-1
- if(jian==0)
- {
- delay_ms(6); //5~10ms
- if(jian==0)
- {
- min--;
- while(!jian);
- }
- }
- }
- }
- /*** 主函数 ***/
- void main()
- {
- while(1)
- {
- keyscan();
- if(k==0)
- display(); //显示当前温度
- else control(); //控制时显示
- }
- }
2 E% V8 h! \* l& v+ v! Q
9 g) f. Z! h5 e7 `0 ?; ^ L0 A% P6 M2 M& ] Y: P
|
|