嵌入式在炉温控制中的应用.docx
《嵌入式在炉温控制中的应用.docx》由会员分享,可在线阅读,更多相关《嵌入式在炉温控制中的应用.docx(33页珍藏版)》请在冰豆网上搜索。
嵌入式在炉温控制中的应用
2系统的设计与实现
在这一章中,根据第二章和第三章的论述,设计出一个实现对温度进行测量和控制的嵌入式系统。
系统具有对外界两点温度进行采集的能力,采集的模拟信号经A/D模块转换成相应的数字量,送入微处理器进行处理。
采集到的每一路温度都要与系统此路温度设定值进行比较,然后根据结果调用合适的控制算法,并通过控制相应的继电器的占空比实现对温度的控制、测量、运算处理、输出控制、显示、通信。
为此引出串行通信设计
利用RS-232串行通信,实现了与PC机进行通讯功能和远程加载功能。
考虑到实际的应用及成本等因素,选用的主要硬件器件有台湾SynCMOS公司的生产的SM5964微控制器,数据采集部分选用了凌特公司(LinearTechnology)推出的20位无延迟模数转换器LTC2430,串行通讯部分使用MAX232芯片,液晶显示屏选用了北京精电蓬远显示技术公司生产的MGLS-12864。
嵌入式操作系统选用了源代码公开的μC/OS-II。
选用的开发环境是:
Windows2000Server
开发工具:
KeilC517.0、VC++6.0
使用的语言是:
汇编、C语言
2.1系统的硬件设计
系统的原理图如图4-1所示。
主要有键盘输入、数据采集、输出控制、LCD显示、通信及电源模块等组成。
图4-1系统原理框图
下面介绍一下主要部分的电路图设计。
1).键盘输入电路
键盘是一组按键的组合,它是常用的输入设备,可以通过键盘输入数据或者命令,实现简单的人机对话。
键盘可分为独立联接式和行列式(矩阵式)两类,每类按其译码方式又分为编码式及非编码式两类。
设计中使用的是独立联接非编码式键盘。
电路图如图4-2所示:
图4-2键盘原理图
每个按键使用的是一个瞬时接触开关,这种联接方式可以容易被微处理器检测,但由于按键会产生机械抖动,在按键被按下或者抬起的瞬间,一般持续5~15ms,因此设计中要去除键抖动。
可以通过硬件双稳态电路或者软件延时来实现,设计中采用延时20ms实现的。
对于串键,采用无限处理方法。
同时为了防止按一次键而产生多次处理的情况(键扫描和键处理速度较快而此时键还没释放),在有键按下时,作一次键处理后还要检测按下的键是否释放。
2).数据采集电路
本系统实现对两路温度信号的采集,为了节省硬件成本,在前向通道中采用了多路选择开关,使用了两个多路模拟开关器件CD4052,实现信号的差分输入,完成对两路温度信号的轮流采样,然后将信号送入一个公共的模数转换器LTC2430,完成模数转换。
由微处理器的P1.2、P1.3两引脚实现信道的选择。
电路图如图4-3所示:
图4-3数据采集原理图
对温度的测量使用铂(Pt)热敏电阻(100Ω),使用桥式电路进行测量。
铂电阻是一种高性能的贵金属热电阻,具有精度高、稳定性好、性能可靠等优点,铂电阻的温度测量范围在-200℃到+850℃之间,在小于200℃时,非线性误差小于0.3%,它的电阻值R和温度t之间的关系可以近似地表示为:
A,B为常数,A为热敏系数(ΔR/℃)。
测量时采用的是查表法来计算温度值。
对于模数转换器LTC2430,设计中使其工作在外部时钟驱动模式下,工作状态分为转换(Conversion)、休眠(Sleep)和数据输出(DataOutput)三个状态。
此时它的数据输出波形图如图4-4所示:
图4-4LTC2430数据输出波形图
3).通信电路
本系统所进行的通信是实现与PC机的通信,选择了RS232通信标准。
这是因为RS232标准是使用最为广泛的通信标准,几乎每一台PC机上都有两个符合RS232标准的串行口,所以采用RS232标准有利于通用性。
由于PC机使用的是RS232电平,而SM5964输出是TTL电平,因此选用MAX232解决电平匹配的问题。
电路图如图4-5所示:
图4-5通信电路原理图
SM5964的串行发送端口TXD和接收端口RXD经MAX232芯片进行电平转换后,分别与PC机的数据接收端口RXD和数据发送端口TXD相连接。
SM5964串行通信的发送端TXD连接到的11引脚,发出的数据信号经过MAX232芯片转换后,由0~5V的TTL电平变为-12~+12V的RS232电平,从14引脚输出到PC机串行口的第二引脚。
按RS232通信协议规定,PC机串行口的第二引脚为数据输入端,这样,发出的数据就可被PC机接收到。
由PC机串行口的发送端TXD(PC机串行口的第三引脚)传输来的数据,作为RS232电平的信号输入到MAX232芯片的第13引脚,经过MAX232芯片进行电平转换后变为TTL电平,再由MAX232的12引脚输出到SM5964串行口的接收端口RXD。
从而完成数据的双向传输。
在设计中,使用了两个发光二极管D7和D8监视通信的工作状态。
4).LCD显示电路
对于LCDMGLS-12864,内置HD61202图形液晶显示模块,厂家为其设置了7条指令来完成对它的控制,有两条指令用于显示状态的设置,其余指令用于数据读/写操作,在此不对其进行详细的说明。
MGLS-12864与微处理器的连接方式有两种:
一种是直接访问方式,一种为间接控制方式。
直接访问方式就是将液晶显示模块的接口作为存储器或者I/O设备直接挂在计算机总线上,计算机以访问存储器或者I/O设备的方式操作液晶显示模块的工作。
而间接控制方式是计算机通过自身的或者系统中的并行口与液晶显示模块连接,通过对接口的操作达到对液晶显示模块的控制。
设计中我采用了间接控制方式,这种方式的特点是电路简单,控制时序有软件实现,可以实现高速计算机与液晶显示模块的接口。
电路图如下图所示,以P2口作为数据口,P3.3为/CSA,P3.4为/CSB,实现左右两区的显示和切换。
P3.5为D/I,P3.6为R/W,P3.7为E,三者产生控制LCD数据与状态的读写等信号。
电位器用于显示对比度的调节。
电路图如图4-6所示:
图4-6显示电路原理图
5).输出控制及报警指示电路
输出控制电路采用12V直流继电器对外电路进行控制,通过控制继电器的吸合时间来实现对温度的控制,继电器是与强电控制电路(大电流、高电压)联系在一起,会对应用系统产生严重干扰,使系统不能正常工作。
为了消除干扰,在微机接口与继电器之间分别加了光耦,使系统主机部分的地与强电控制电路的地隔开。
当温度超限或者系统出现致命错误时,系统会发出报警指示且实现在LCD上显示。
(原理图略)
2.2系统的移植
移植是指使一个实时操作系统能够在某个微处理器平台上运行。
每个实时嵌入式操作系统都支持很多种处理器,为了使其在具体的硬件平台上工作,必须根据具体的硬件平台完成移植工作。
为了便于用户的使用,嵌入式操作系统生产商一般提供一些通用的板级支持包(BoardSupportPackage,BSP)(有的称为硬件抽象层(HardwareAbstractLayer,HAL)),用户只需选择与自己相近的BSP进行修改,可以很容易完成移植工作。
μC/OS-II没有提供BSP,需要用户独立完成此工作。
由于在设计时已经充分考虑了可移植性,移植工作并不太复杂,要根据具体硬件平台,对文件OS_CPU.H、OS_CPU_C.C和OS_CPU_A.ASM进行合理的修改。
要使其正常运行,处理器首先需满足以下要求:
✧处理器的C编译器能产生可重入代码;
✧用C语言就可以打开和关闭中断;
✧处理器支持中断,并且能够产生定时中断(通常在10Hz至100Hz之间);
✧处理器支持能够容纳一定数量数据(可能是几千字节)的硬件堆栈;
✧处理器有将堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。
针对本论文论文中选用的SM5964微处理器和开发工具KeilC517.0,进行移植时,重点考虑函数的重入和任务栈的结构及大小的确定。
对三个文件进行的修改如下。
1).设置OS_CPU.H中与处理器和编译器相关的代码
/*与编译器相关数据类型*/
typedefunsignedcharBOOLEAN;
typedefunsignedcharINT8U;//无符号8位数
typedefsignedcharINT8S;//有符号8位数
typedefunsignedintINT16U;//无符号16位数
typedefsignedintINT16S;//有符号16位数
typedefunsignedlongINT32U;//无符号32位数
typedefsignedlongINT32S;//有符号32位数
typedeffloatFP32;//单精度浮点数
typedefdoubleFP64;//双精度浮点数
typedefunsignedcharOS_STK;//栈单元宽度为8比特
/*处理器相关代码(大模式)*/
#defineOS_ENTER_CRITICAL()EA=0//关中断
#defineOS_EXIT_CRITICAL()EA=1//开中断
#defineOS_STK_GROWTH0//堆栈从下往上增长1=向下,
//0=向上
#defineOS_TASK_SW()OSCtxSw()/*因为微处理器没有软中断指令,所以用程序调用代替*/
2).在OS_CPU_C.C中用C语言编写6个与操作系统相关的函数
在此文件中主要是完成任务初始化函数OSTaskStkInit()的编写,每个任务在创建时,要初始化自己的任务堆栈,任务堆栈的结构类似系统发生一次中断后的堆栈结构,在进行任务切换时,它要用来存储与本任务相关的所有信息。
其它5个函数需要声明,因在此用不到,没有实际内容。
如果需要使用可以进行编程。
void*OSTaskStkInit(void(*task)(void*pd),void*ppdata,
void*ptos,INT16Uopt)reentrant
{
OS_STK*stk;
ppdata=ppdata;
opt=opt;/*opt没被用到,保留此语句防止报警产生*/
stk=(OS_STK*)ptos;//用户堆栈最低有效地址
*stk++=15;//用户堆栈长度
*stk++=(INT16U)task&0Xff;//任务地址低8位
*stk++=(INT16U)task>>8;//任务地址高8位
*stk++=0x00;//PSW
*stk++=0x0A;//ACC
*stk++=0x0B;//B
*stk++=0x00;//DPL
*stk++=0x00;//DPH
*stk++=0x00;//R0
*stk++=0x01;//R1
*stk++=0x02;//R2
*stk++=0x03;//R3
*stk++=0x04;//R4
*stk++=0x05;//R5
*stk++=0x06;//R6
*stk++=0x07;//R7
/*不用保存SP,任务切换时根据用户堆栈长度计算得出。
*/
*stk++=(INT16U)(ptos+MaxStkSize)>>8;
/*?
C_XBP仿真堆栈指针高8位*/
*stk++=(INT16U)(ptos+MaxStkSize)&0xFF;
/*?
C_XBP仿真堆栈指针低8位*/
return((void*)ptos);
}
voidOSTaskCreateHook(OS_TCB