智能仪器设计.docx
《智能仪器设计.docx》由会员分享,可在线阅读,更多相关《智能仪器设计.docx(29页珍藏版)》请在冰豆网上搜索。
智能仪器设计
摘要:
本文主要介绍了温度的自动测量,包括温度传感器、单片机接口及其应用软件的设计,大体分为以下几大部分:
介绍了国内外温度检测技术和特种测温一钢水温度检测的发展现状,并且分析了温度检测技术的未来发展方向;根据实际使用要求设计了相应的单片机硬件系统,该系统能够实现数据采集、数据处理、温度值的在线显示以及时钟电路的时间显示;简略介绍了该仪表的软件部分;对该温度仪表的未来发展进行了展望。
多功能智能化温度测量仪是以STC89C51单片机系统和温度检测元件一TLC1594相结合的温度测量系统。
本系统的数学模型合理,测量方法容易实现。
实际仪器采用抗干扰、低零漂、低温漂的电子元件,性能稳定。
该测量仪总体特点是使用简便、实用、使用对象广、并且实现了自动化。
关键词:
温度测量多功能智能化单片机
第一章智能仪器简介
一、智能仪器简介
智能仪器是计算机技术与测量仪器相结合的产物,是含有微计算机或微处理器的测量(或检测)仪器,它拥有对数据的存储、运算、逻辑判断及自动化操作等功能,具有一定智能的作用(表现为智能的延伸或加强等)。
近年来,智能仪器已开始从较为成熟的数据处理向知识处理发展。
网络化虚拟仪器、模糊判断、故障诊断、容错技术、传感器融合、机件寿命预测等,使智能仪器的功能向更高的层次发展。
智能仪器对仪器仪表的发展以及科学实验研究产生了深远影响,是仪器设计的里程碑。
二、ST89C51简介
主芯片简介
STC89C51系列单片机是从引脚到内核都完全兼容标准8051的单片机,有PDIP-40、PLCC-44、PQFP-44三种封装形式。
Intel公司MCS-51单片机的基本结构如图1-4所示。
该单片机具有如下资源:
(1)一个8位算术逻辑单元(CPU)。
(2)4组,共32个I/O口,每口8个引脚,可单独寻址,其中P0、P2口具有地址/数据总线功能。
(3)两个16位定时/计数器(简称为定时器)。
(4)全双工串行通信口。
(5)5个中断源,具有两个中断优先级。
(6)128B内置RAM。
(7)具有64KB可寻址数据和代码区。
(8)各个模块采用三总线(地址、数据和控制)连接。
(9)开放总线接口,P0口分时作为8位数据总线与8位地址总线,P2口作为地址总线高8位。
每个MCS-51单片机处理周期包括12个时钟周期(又称为一个机器周期),每12个时钟(一个机器)周期用来完成一个操作,例如取指令等,指令执行时间为时钟频率除以12后取倒数,如果系统时钟是12MHz,则相当于执行每条指令所需要的时间1μs。
引脚简介
P0口:
P0口是一个8位漏极开路的双向I/O口。
作为输出口,每位能驱动8个TTL逻辑电平。
对P0端口写“1”时,引脚用作高阻抗输入。
当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。
在这种模式下,P0具有内部上拉电阻。
在flash编程时,P0口也用来接收指令字节;在程序校验时,输出指令字节。
程序校验时,需要外部上拉电阻。
P1口:
P1口是一个具有内部上拉电阻的8位双向I/O口,p1输出缓冲器能驱动4个TTL逻辑电平。
对P1端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
此外,P1.0和P1.2分别作定时器/计数器2的外部计数输入(P1.0/T2)和时器/计数器2的触发输入(P1.1/T2EX),具体如下表所示。
在flash编程和校验时,P1口接收低8位地址字节。
引脚号第二功能
P1.0T2(定时器/计数器T2的外部计数输入),时钟输出
P1.1T2EX(定时器/计数器T2的捕捉/重载触发信号和方向控制)
P1.5MOSI(在线系统编程用)
P1.6MISO(在线系统编程用)
P1.7SCK(在线系统编程用)
P2口:
P2口是一个具有内部上拉电阻的8位双向I/O口,P2输出缓冲器能驱动4个TTL逻辑电平。
对P2端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOVX@DPTR)时,P2口送出高八位地址。
在这种应用中,P2口使用很强的内部上拉发送1。
在使用8位地址(如MOVX@RI)访问外部数据存储器时,P2口输出P2锁存器的内容。
在flash编程和校验时,P2口也接收高8位地址字节和一些控制信号。
P3口:
P3口是一个具有内部上拉电阻的8位双向I/O口,p2输出缓冲器能驱动4个TTL逻辑电平。
对P3端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
P3口亦作为STC89C52特殊功能(第二功能)使用,如下表所示。
在flash编程和校验时,P3口也接收一些控制信号。
端口引脚第二功能
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2INTO(外中断0)
P3.3INT1(外中断1)
P3.4TO(定时/计数器0)
P3.5T1(定时/计数器1)
P3.6WR(外部数据存储器写选通)
P3.7RD(外部数据存储器读选通)
此外,P3口还接收一些用于FLASH闪存编程和程序校验的控制信号。
RST——复位输入。
当振荡器工作时,RST引脚出现两个机器周期以上高电平将是单片机复位。
ALE/PROG——当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。
要注意的是:
每当访问外部数据存储器时将跳过一个ALE脉冲。
对FLASH存储器编程期间,该引脚还用于输入编程脉冲(PROG)。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。
该位置位后,只有一条MOVX和MOVC指令才能将ALE激活。
此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE禁止位无效。
PSEN——程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当STC89C52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲,在此期间,当访问外部数据存储器,将跳过两次PSEN信号。
EA/VPP——外部访问允许,欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。
需注意的是:
如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接Vcc端),CPU则执行内部程序存储器的指令。
FLASH存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。
第二章智能仪器设计
一、方案与方案设计选择说明
1.设计题目及要求
实现智能数字显示仪表。
要求8位数码管显示(4位显示测量值,4位显示设定值),4输入按钮(功能选择、数码管选择、数字增加、数字减少),可设定上下限报警(蜂鸣器报警)。
适配E型(镍铬-铜镍)热电偶,测温范围为0℃~700℃。
采用位式(两位、三位,具有滞环)控制、并用晶闸管过零驱动1000W电加热器(电源电压为AC220V)。
2.方案选择及说明
(1)器件选择
STC89C511片
4位数码管2个
按钮4个
蜂鸣器1个
适配E型(镍铬-铜镍)热电偶1个
LED4个
1000W电加热器1个
(2)模块选择
电源模块复位电路
晶振电路蜂鸣器电路
串口通信电路单片机
电加热器电路发光二极管电路
按钮电路温度测量电路
数码管电路
3.设计预想
(1)任务分析
本数显仪表设计任务要求使用STC89C51单片机作为主控芯片,设计一个智能显示仪表。
本系统采用2个共8位数码管分别显示测量温度值和设定值;系统拥有报警功能,当当前温度超过上限值或者下限值时,蜂鸣器响,且上限报警/下限报警LED灯亮以区分上/下限报警;系统有四个控制按键,功能分别是:
功能选择、数码管选择、数字增加、数字减少,用来对温度设定值、上限值、下限值等设置;在设定状态时两个数码管用来分别显示设置功能号和该功能实现的设置当前值;本系统还有四个状态显示LED灯,分别显示:
正常运行、设定状态、上限报警、下限报警;除此之外,本系统还要求有对加热器控制的功能以达到使温度控制在设定值的要求。
(2)功能实现
采用STC89C51作为主控芯片,必须利用外部AD转换电路进行,因为STC89C51没有内置的A/D转换器。
仪表适配E型(镍铬-铜镍)热电偶,因此首先需要一个E型(镍铬-铜镍)热电偶的信号调理电路,使热电阻的热电势转化为MCU可直接测得的电压值,从而测得当前温度值。
按键采用中断方式进行处理,先按“功能选择”键可以启动按键扫描,对其进行处理,对不同的键有不同的处理程序进行操作。
在处理过程中需要关中断,防止按键1一直中断,各功能都设置完后,再按“功能选择”键以退出处理程序;不同按键有不同的作用:
a.“功能选择”键:
启动中断,选择切换不同的设置对象和存储上一个对象设置的值,最后切换完所有功能后按下保存所有设定值并退出中断;
b.“数码管选”键:
选择待设定对象的数码管,即选择该对象加/减操作的单位量;
c.“数字增加”键:
在以选择的位上加1;
d.“数字减少”键:
在以选择的位上减1。
对加热器的控制,采用最简单的二位式控制,能够满足一般精度要求。
状态显示和蜂鸣器操作分别用单片机的输出端口操作。
采用晶闸管过零驱动电路来驱动1000W的电加热器。
(3)热电偶
E型热电偶是一种廉金属的热电偶,正极(EP)为:
镍铬10合金,化学成分与KP相同,负极(EN)为铜镍合金,名义化学成分为:
55%的铜,45%的镍以及少量的锰,钴,铁等元素。
该热电偶的使用温度为-200~900℃。
E型热电偶的特点:
热电动势之大,灵敏度之高属所有热电偶之最,宜制成热电堆,测量微小的温度变化。
对于高湿度气氛的腐蚀不甚灵敏,宜用于湿度较高的环境。
E热电偶还具有稳定性好,抗氧化性能优于铜-康铜,铁-康铜热电偶,价格便宜等优点,能用于氧化性和惰性气氛中,广泛为采用。
E型热电偶不能直接在高温下用于硫,还原性气氛中,热电势均匀性较差
二、原理图与原理图说明
1.总体原理图
2.各模块原理图及说明
(1)电源模块
说明:
Vcc是数字电源;+5V为模拟电源;数字地与模拟地之间接两个0欧姆电阻。
C4,C5,C6是为稳定电压用。
(2)复位电路
(3)晶振电路
(4)蜂鸣器电路
(5)串口通信电路
(6)发光二极管电路
(7)单片机
(8)按键电路
(9)温度测量电路
(10)数码管电路
(11)电加热器驱动电路
说明:
晶闸管过零驱动电路图
(12)4-20mA输出电路
三.总电路图
第三章软件设计
一、主程序流程图
二、程序清单
AD转换程序
#include
#include
unsignedchaADH;
UnsignedintI;
Voidtimer0()_init(void)
{
TCCR0=0X00;
TCNT0=0X83;
TCCR0=0X02;
}
Voidport_init(void)
{
PORTA=0X80;
DDRA=0X80;
ORTB=0XFF;
DDRB=0XFF;
PORTC=0XFF;
DDRC=0XFF;
PORTD=0XFF;
DDRD=0XFF;
}
Voidadc_ini(void)
{
ADCSRA=0X00;
ADMUX=0XE0;
ADCSRA=0XE2;
SFIOP=0X80;
}
Voidinit_devices(void)
{
Timer0_init();
Port_init();
Adc_init();
MCUCR=0X00;
GICR=0X00;
TIMSK=0X01;
#ASM(sei);
}
ConstunsignedcharSHUMA[]={0xc0,0cf9,0xa40xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}
{
Init_devices();
While
(1)
{
PORTB=SHUMA[ADH/16];
PORTC=SHUMA[ADH%16];
}
}
INTERRUPT[TIM0_OVF]voidtimer0_ovf_isr(void)
{
TCNT0=0X83;
While(!
(ADCSRA&(1<<4)));
ADH=ADCH;
I++;
If(i>250)
{
i=0;
PORTA.7=~PORTA.7
}
}
数码管显示程序
#include
#include
Unsignedchardisp[]={0xc0,0cf9,0xa40xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
Unsignedintweizhi[]={0x01,0x02,0x04,0x08,0xc0,0x20,0x40,0x80}
Unsignedintdata[8];
VoidSPI_Masterinit(void)
{
DRRB|=(1<<5)|(1<<7);
SPCR=(1<<6)|1<<4|(1<<5)|(1<<1)|(1<<0);
}
VoidSPI_595_OUT(unsignedchari)
{
SPDR=i;
While(!
(SPDR&(1<<7)))
{;}
}
Voidmain()
{
Unsignedcharsaomiao=0;
ucharint_t;
uchari;
ucharj;
ucharcount=2;//2个字
uintk=0;
voidt0_int()interrupt1
{
TL0=0x18;
TH0=0x1C;
int_t++;
if(int_t==2)//移动速度2ms
{
int_t=0;
k=k+2;
if(k==count*32)
k=0;
}
}
voiddelay(uintdt)//2字节
{
ucharbt;//1字节
for(;dt;dt--)
{
for(bt=0;bt<255;bt++);
}
}
voidserial_send(uchardat)
{
SCON=0x00;
SBUF=~dat;
while
(1){if(TI){TI=0;break;}}
}
unsignedcharcodehzdot[64]={
/*测CB2E2*/
0x40,0x02,0x27,0xC2,0x24,0x42,0x84,0x52,0x45,0x52,0x55,0x52,0x15,0x52,0x25,0x52,
0x25,0x52,0x25,0x52,0xC5,0x52,0x41,0x02,0x42,0x82,0x42,0x42,0x44,0x4A,0x48,0x04,
/*试CCAD4*/
0x00,0x20,0x40,0x28,0x20,0x24,0x30,0x24,0x27,0xFE,0x00,0x20,0xE0,0x20,0x27,0xE0,
0x21,0x20,0x21,0x10,0x21,0x10,0x21,0x0A,0x29,0xCA,0x36,0x06,0x20,0x02,0x00,0x00
};
voiddisplay()
{
j=k;
for(i=0;i<16;i++)
{
P1=i;
serial_send(hzdot[j]);
j++;
serial_send(hzdot[j]);
j++;
if(j==count*32)
j=0;
delay
(1);
}
}
voidmain()
{
SCON=0x00;
TMOD=0x01;
IE|=0x82;
TL0=0x18;
TH0=0x1C;
delay(100);
TR0=1;//启动T0定时器
for(;;)
display();
}
位式算法
voiddisplay()
if(pv>=sv)
out=’off’;
else
out=’on’;
{
unsignedcharcodenumber[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
unsignedchardisp_num[6];
unsignedintk,k1;
k=high_time;
k=k%1000;
k1=k/100;
if(k1==0)
disp_num[0]=0;
else
disp_num[0]=0x60;
k=k%100;
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
k=k%100;
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
}
/***********************************************************
主程序
***********************************************************/
main()
{
unsignedcharz;
unsignedchara,b,flag_2=1,count1=0;
unsignedcharphil[]={2,0xce,0x6e,0x60,0x1c,2};
TMOD=0x21;
TH0=0x2f;
TL0=0x40;
SCON=0x50;
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
PS=1;
EA=1;
EX1=0;
ET0=1;
ES=1;
TR0=1;
TR1=1;
high_time=50;
low_time=50;
PIDInit(&spid);//InitializeStructure
spid.Proportion=10;//SetPIDCoefficients
spid.Integral=8;
spid.Derivative=6;
spid.SetPoint=100;//SetPIDSetpoint
while
(1)
{
if(plus==0)
{
EA=0;
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(plus==0)
{
set_temper++;
flag=0;
}
}
elseif(subs==0)
{
for(a=0;a<5;a++)
for(b=0;a<102;b++){}
if(subs==0)
{
set_temper--;
flag=0;
}
}
elseif(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
{
flag=0;
break;
}
EA=1;
}
get_temper();
b=temper;
if(flag_2==1)
a=b;
if((abs(a-b))>5)
temper=a;
else
temper=b;
a=temper;
flag_2=0;
if(++count1>30)
{
display();
count1=0;
}
compare_temper();
}
TR0=0;
z=1;
while
(1)
{
EA=0;
if(stop==0)
{
for(a=0;a<5;a++)
for(b=0;b<102;b++){}
if(stop==0)
disp_1(phil);
//break;
}
EA=1;
}
}
//DS18b20子程序
#include
sbitDQ=P2^1;//定义端口
typedefunsignedcharbyte;
typedefunsignedintword;
//延时
voiddelay(worduseconds)
{
for(;useconds>0;useconds--);
}
//复位
byteow_reset(void)
{
bytepresence;
DQ=0;//DQ低电平
delay(29);//480us
DQ=1;//DQ高电平
delay(3);//等待
presence=DQ;//presence信号
delay(25);
return(presence);
}//0允许,1禁止
//从1-wire总线上读取一个字节
byteread_byte(viod)
{
bytei;
bytevalue=0;
for(i=8;i>0;i--)
{
value>>=1;
DQ=0;
DQ=1;
delay
(1);
if(DQ)value|=0x80;
delay(6);
}
return(value);
}
//向1-wire总线上写一个字节
voidwrite_byte(charval)
{
bytei;
for(i=8;i>0;i--)//一次写一个字节
{
DQ=0;
DQ=val&0x01;
delay(5);
DQ=1;
val=val/2;
}
delay(5);
}
//读取温度
charRead_Temperature(void)
{
union{
bytec[2];
intx;
}temp;
ow_reset();
write_byte(0xcc);
write_byte(0xBE);
temp.c[1]=read_byte();
temp.c[0]=read_byte();
ow_reset();