资源描述
水温控制系统
文 摘 为了实现高精度的水温控制,本文介绍了一种以SPCE061A单片机为控制核心、以PID算法控制以及PID参数整定相结合的控制方法来实现的水温控制系统。文章着重介绍核心器件的选择、控制算法的确定、各部份电路及软件的设计。SPCE061A单片机完善的内部结构、优良的性能和强大的中断处理能力,决定了该控制系统的特点:电路结构简单、程序简短、系统可靠性高等。本次设计还充分利用了SPCE061A单片机成熟的语音处理技术和PC机的图形处理功能,来实现了语音播报温度和打印温度变化曲线的要求。
关键词 SPCE061A单片机;Pt1000;PID
温度、压力,流量和液位是四种最常见的过程变量,其中温度是一个非常重要的过程变量,因为它直接影响燃烧、化学反应、发酵、烘烤、煅烧、蒸馏、浓度、挤压成形,结晶以及空气流动等物理和化学过程。温度控制在工业领域应用非常广泛,由于其具有工况复杂、参数多变、运行惯性大、控制滞后等特点,它对控制调节器要求较高。温度控制不好就可能引起生产安全,产品质量和产量等一系列问题。尽管温度控制很重要,但是要控制好温度常常会遇到意想不到的困难。
随着嵌入式系统开发技术的快速发展及其在各个领域的广泛应用,人们对电子产品的小型化和智能化要求越来越高,作为高新技术之一的单片机以其体积小、价格低、可靠性高、适用范围大以及本身的指令系统等诸多优势,在各个领域、各个行业都得到了广泛应用。
本文主要介绍单片机温度控制系统的软件设计过程,其中涉及系统结构设计、元器件的选取和控制算法的选择、程序的调试和系统参数的整定。在系统构建时选取了凌阳科技公司提供的一款新产品SPCE061A芯片作为该控制系统的核心。温度信号由PT1000和电压放大电路提供。通过PID算法实现对电炉功率和水温控制。使用SSR固态继电器作执行部件。同时,具有温度数字语音播报和显示啊功能。 系统控制对象为1升净水,容器为搪瓷器皿。水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动控制,以保持设定的温度基本不变,具有较好的快速性与较小的超调。该系统为一实验系统,要求系统有控制能力,实现对主要可变参数的实时监控。因此系统控制部分程序设计在µ‘nSPTM集成开发环境中编辑、编译、链接、调试以及仿真的。使用软件编程既减少了系统设计的工作量,又提高了系统开发的速度,使用软件还可以提高所设计系统的稳定性,避免了因个人设计经验不足而产生过多的系统缺陷。
1 系统方案
1.1 水温控制系统设计任务和要求
该系统为一实验系统,系统设计任务:
设计一个水温自动控制系统,控制对象为1升净水,容器为搪瓷器皿。水温可以在一定范围内由人工设定,并能在环境温度降低时实现自动调整,以保持设定的温度基本不变。
系统设计具体要求:
⑴ 温度设定范围为40~90℃。
⑵ 环境温度降低时(例如用电风扇降温)温度控制的静态误差≤1℃。
⑶采用适当的控制方法,当设定温度突变(由40℃提高到60℃)时,减小系统的调节时间和超调量。
⑷用十进制数码管显示水的实际温度。
⑸ 在设定温度发生突变(由40℃提高到60℃)时,自动打印水温随时间变化的曲线。
1.2 水温控制系统关键部分确定
水温控制系统是一个过程控制系统,在设计的过程中,必须明确它的组成部分。过程控制系统的组成部分有:控制器、执行器、被控对象和测量变送单元,其框图如图1所示。
图1 过程控制组成框图
由图可知,在这个系统的设计中,主要设计如图几个部分。除此之外,根据题目要求,还要选取合适的控制算法来达到系统参数的要求。对于执行器件、测量变送元件将在部分电路设计中有说明。在这个部分我主要是对控制器的确定和控制算法的选择作一个详细的介绍。因为这两部分是实现本系统控制目的的关键。它们选取的好坏将直接影响着整个系统实现效果的优劣,所以这是一项不容怱视的工作。
1.2.1 CPU(Computer processing Unit)中央处理器
⑴ 方案一:此方案采用SPCE061A单片机实现。SPCE061A单片机除具有体积小,集成度高、易扩展、可靠性高、功耗低、结构简单、中断处理能力强等特点外,内置8路ADC,2路DAC。在实现控制系统中,采用SPCE061A为前端采集单元,具有较好的同步性和实时性。且内嵌32K字闪存FLASH,处理速度高,集成开发环境中,配有很多语音播报函数,实现语音播报极为方便。另外,比较方便的是该芯片内置在线仿真、编程接口,可以方便实现在线调试,这大大加快了系统的开发与调试。
⑵ 方案二:此方案采用89C51单片机实现,此单片机软件编程自由度大,可用编程实现各种控制算法和逻辑控制。但在数据采集时必须使用A/D(数/模转换),且在选择A/D时需考虑3个方面的内容:一是如何针对系统的需求,选择合适的A/D器件;二是如何根据所选的A/D器件设计外围电路与单片机的接口电路;三是编写控制A/D器件进行数据采集的单片机程序,这些大大加大了工作量。若要增加语音播报功能,还需要外接语音芯片及接口,加繁了外围电路设备,大大增加了软件实现难度。此外51单片机内部无在线仿真、编程接口,就需要用仿真器来实现软硬件调试,较为繁琐。
将两个方案一比较便可得出一个结论,采用凌阳单片机来实现本题目,不管是从结构上,还是从工作量上都占有很大的优势,所以最后决定用SPCE061A作为该控制系统的核心。
1.2.2 常用温度控制系统分析
温度是一个普通而又重要的物理量,在许多领域里人们需对温度进行测量和控制。长期以来国内外科技工作者对温度控制器进行了广泛深入的研究,产生了大批温度控制器,如性能成熟应用广泛的PID调节器、智能控制PID调节器、自适应控制等。此处主要对一些控制器特性进行分析以便选择适合的控制方法应用于改造。
⑴ 常规PID
PID在温度控制中已使用数十年,是一种成熟的技术,它具有结构简单、易于理解和实现,且一些高级控制都是以PID为基础改进的。在工业过程控制中90%以上的控制系统回路具有PID结构,在目前的温度控制领域应用十分广泛,即使在科技发达的日本,PID在其温度控制应用中仍然占80%的比例。其主要构成如图2所。
由图可知PID调节器是一种线性调节器,这种调节器是将设定值w与实际输出值y进行比较构成偏差
图2 模拟PID控制
并将其比例、积分、微分通过线性组合构成控制量。其动态方程为:
(1)
其中---为调节器的比例放大系数
---为积分时间常数
---为微分时间常数
PID调节器的离散化表达式为
其增量表达形式为:
其中T为采样周期。
可见温度PID调节器有三个可设定参数,即比例放大系数、积分时间常数、微分时间常数。
比例调节的作用是使调节过程趋于稳定,但会产生稳态误差;
积分作用可消除被调量的稳态误差,但可能会使系统振荡甚至使系统不稳定;
微分作用能有效的减小动态偏差。
在实际使用中,在满足生产过程需要的前提下,应尽量选择简单的调节器,这样,既节省投资,又便于维护. 常规PID控制调节器是一种应用广泛技术成熟的控制方法,它能满足一般工业控制的要求,其优点是原理简单、使用方便、适应性广。采用PID控制,控制效果的好坏很大程度上取决于PID三个控制参数的确定。对一个控制系统而言, 只要参数选择适当,都能取得较好的控制效果。
⑵ 自动控制方式
为了实现温度的自动控制,必须要组成一定的系统结构。如图3,该控制系统是把输出量检测出来,经过物理量的转换,再反馈到输入端去与给定量进行比较(综合),并利用控制器形成的控制信号通过执行机构SSR对控制对象进行控制,抑制内部或外部扰动对输出量的影响,减小输出量的误差,达到控制目的。在此控制系统中单片机就相当于常规控制系统中的运算器控制器,它对过程变量的实测值和设定位之间的误差信号进行运算然后给出控制信息。单片机的运算规则称为控制法则或控制算法。
图3 自动控制框图
常用的控制算法有以下几种
① 经典的比例积分微分控制算法。
② 根据动态系统的优化理论得到的自适应控制和最优控制方法。
③ 根据模糊集合理论得到模糊控制算法。
自适应控制、最优控制方法以及模糊控制算法是建立在精确的数学模型基础上的,在实时过程控制中,由于控制对象的精确数学模型难于建立,系统参数经常发生变化,运用控制理论进行综合分析要花很大代价,主要是时间。同时由于所得到的数学模型过于复杂难于实现。在实时控制系统中要求信号的控制信号的给出要及时,所以在目前的过程控制系统中较少采用自适应控制、最优控制方法和模糊控制算法。目前在过程控制中应用较多的还是PI控制算法、PD控制算法和PID控制算法。
2 系统硬件设计
2.1 总体设计框图及说明
本系统是一个简单的单回路控制系统。为了实现温度的自动测量和控制,本系统采用了SPCE061A单片机作为系统的控制中心,由数据采集模块检测到的温度信号传入单片机,并根据接收到的数据进行处理和控制运算,同时将数据保存,以便与下一次采样值进行比较,通过软件对所测电压进行数字非线性校正,同时由显示器进行实时显示。根据系统程序控制,进行PID运算以及输出控制,最终由CPU控制加热回路SSR的通断,达到调功的目的。系统还提供了键盘设定模块及打印机接口,便于用户与系统之间的对话。系统的硬件结构较简单,由若干个功能模块组成。具体结构图及说明如下,
图4 系统结构框图
键盘设定:用于温度设定,共三个按键。
数据采样:将由传感器及相关电路采集到的温度转为电压信号,送入SPCE061A相应接口中,经AD转换后,换算成温度值,用于播报和显示。
数据显示:采用了共阴极数码管LED5641A进行显示设置温度与测量温度。
串行口传输:将采样温度值,上传至PC机,以利用PC的图形处理功能来描绘曲线并打印。
继电器/热电炉:通过三极管控制继电器的开关来完成对热电炉的功率控制。
语音播放:语音播放水温设置温度,并播报整数温度变化。
2.2 部分外部电路设计
由总体框图可以看到,整个系统的设计都离不开SPCE061A的输入/输出接口。在单片机中,I/O口就是单片机与外设交换信息的主要通道。输入端口从外界接收检测的输入信号、键盘信号等各种开关量信号;输出端口向外部输出处理结果、显示信息、控制命令、驱动信号等。SPCE061A内部有并行和串行两种方式的I/O口。两个16位通用的并行I/O端口即A口和B口,这两个口的每一位都可通过编程单独定义为输入或输出口,通常对某一位的设定包括三个基本项:数据向量Data、属性向量Attribution和方向控制向量Direction,三个向量的每个对应位组合在一起形成一个控制字,用来定义相应I/O口位的输入、输出状态和工作方式。A口的IOA0~IOA7用作输入口时具有唤醒功能,常用于键盘输入。B口除常规的输入输出功能外,还具有特殊功能。比如后面串行通信用到的IOB7口和IOB10口,它们在此电路中就充当的是串行数据的接收和发送端口。具体的用法将在后面的电路设计中用到。
2.2.1 键盘设置电路
IOA0接KEY1,IOA1接KEY2,IOA2接KEY3。
KEY1: 设置温度的十位数;0—9
KEY2: 设置温度的个位数;0—9
KEY3: 工作模式选择键,共有三种工作模式:正常工作状态、温度重新设置、语音播报设置。
图5 键盘电路
系统上电后,数码管全部显示为零,根据按KEY1次数,十位的数码管顺序增加。同样KEY2,也如此。按KEY3后,系统开始测温,并与采集的温度进行比较,通过软件来控制电炉的开关。同时语音播报变化的整数值温度。
2.2.2 测温部分电路
如图6所示,运放采用HT9274集成芯片,温度传感器使用Pt电阻。
HT9274是微功率运算放大器,利用标准 CMOS 制成,提供与 LM324 、TL274 及 WT274 等相似产品完全兼容的接脚。其低操作电压及稳定的品质特性,提供了完美的输出驱动能力。HT9274 适用于低功率操作的应用,如电话局线界面、传感器放大器及一些电池操作的携带式电子产品。
采用温度传感器铂电阻Pt1000,是因为铂电阻的物理和化学性能在高温和氧化介质中很稳定、价格又便宜,常用作工业测量元件,以铂电阻温度计作基准器。此元件线性较好,在0~100摄氏度时,最大非线性偏差小于0.5摄氏度。铂热电阻与温度关系式,其中:
——温度为t摄氏度时的电阻;
——温度为0摄氏度时的电阻;
A、B——温度系数 A=3.94*102/℃ B=-5.84*10-7/℃
T——任意温度
因为Pt电阻在0摄氏度时,阻值为1千欧姆,在100摄氏度时,阻值为1380欧姆,则表示阻值变换从0—380欧姆,电压从0V---3.3V。 采用差动运放,通过可调分压电阻可以满足零点调节。因为Pt电阻中电流基本为1—2mA,则Pt电阻电压就在0—380mV波动。因此采用10倍电压放大。基本满足SPCE061A数模转换。
图6 测温电路
2.2.3 控制电路
此部份用于在闭环控制系统中对被控对象实施控制,此处被控对象为电炉丝,采用对加在电炉丝两端的电压进行通断的方法进行控制,以实现对水加热功率的调整,从而达到对水温控制的目的。
对电炉丝通断的控制采用SSR固态继电器,SSR是半导体继电器,所以较小的驱动功率即可使SSR工作。它的使用非常简单,只要在控制台端加上一TTL、CMOS电平或一晶体管,即可实现对继电器的开关。
图7 热电炉控制电路
图8 过零控制方式SSR工作波形
图7为通过三极管NPN8050来控制继电器的开关的,继电器采用的是带光电隔离的过零型双向可控硅AC-SSR常开式(常闭式)固态继电器,为使其实现过零控制,就是要实现工频电压的过零检测,并给出脉冲信号,由单片机控制双向可控硅过零脉冲数目。当在其输入端加入(撤离)控制信号时,输出端接通(断开),从而控制电炉与电源的通断,来达到加热或冷却炉丝的目的,最终实现使碗中水温度稳定在设定值上。
2.2.4 音频输出电路
SPCE061A提供了双通道音频输出方式。数字量分别写入P_DAC1和P_DAC2单元。DAC1、DAC2转换输出的模拟量为电流信号,分别通过DAC1和DAC2管脚输出。
图9 音频输出电路
SPCE061A内置两路10位DAC,只需要外接功放电路即可完成语音的播放.音频部分的原理图9所示,在图中可以看到两个跳线,其作用在于可以测量DAC的输出波形;另外拔掉跳线,可以断开DAC到喇叭放大的通路,使得DAC通道处于开路状态。这样便于用DAC做其他用途,用户可以用过这个跳线来加入自己的外围电路。
SPY0030是凌阳的芯片,相当于LM386,但是比386音质好,它可以工作在2.4~6.0V范围内,最大输出功率可达700mW(386必须工作在4V以上,而且功率只有100mW)。
用凌阳Compress Tool事先把所需要的语音信号录制好,本系统共包括十多个语音资源,整个语音信号经凌阳SACM_S480压缩算法压缩只占有13.2K存储空间,SPCE061A单片机具有32k闪存,使用内部flash即可满足要求。凌阳SPCE061A单片机自带双通道DAC音频输出, DAC1、DAC2转换输出的模拟量电流信号分别通过AUD1和AUD2管脚输出, DAC输出为电流型输出,所以DAC输出经过SPY0030音频放大,以驱动喇叭放音,放大电路如图所示,可以接喇叭,也可以接耳机,这为单片机的音频设计提供了极大方便。音频的具体功能主要通过程序来实现。
2.2.5 数码显示电路
图10 显示电路
本图采用了共阴极数码管LED5641A进行显示,LED5641A具有四位数码管,这四个数码管的段选a、b、c、d、e、f、g分别接在一起,每一个都拥有一个共阴的位选端。IOB0—IOB2口分别接三极管的p端,通过三极管来控制LED的片选。IOA8—IOA15口传输要显示的数据,利用其串/并转换功能,送入数码管显示。在此外接了两个电阻R-PACK4来保护LED。数据线也可直接接凌阳SPCE061A单片机的I/O口,因为I/O口输出电流很小,一般不会对LED造成很大的损坏,而它的电压值却足以驱动LED,这不像别的单片机还要外接驱动电路和电阻。采用凌阳SPCE061A单片机,将大大减化了设计过程和硬件电路.
2.2.6 串行通讯部分电路
系统设计要求控制系统能同PC联机通信,以利用PC图形处理能力打印显示温度曲线,故使用了SPCE061A的异步串行端口UART实现与PC通信。由于SPCE061A串行口电平和PC不一致,(SPCE061A的I/O为TTL电平,PC串行口为RS232电平),使用一片MAX232为进行电平转换驱动。通信速率为9600波特率。数据5秒传输一次。电路图如图11所示,MAX232的RXD1和TXD1分别接SPXEO61A的IOB10(TX)和IOB7(RX)。
图11 串行通讯电路
UART模块提供了一个全双工标准通信口,用于完成SPCE061A与外设之间的串行通信。根据RS-232的标准,SPCE061A单片机也是按照字节传输数据的。利用IOB口的特殊功能和UART IRQ中断,可以同时完成UART接口数据的接收和发送。此外,UART还可以带缓冲接收数据,即可以在读取缓存器数据之前接收新的数据。但是,如果新的数据被接收到缓存器之前一直未从中读取,先前的数据会发生数据丢失。P_UART_Data(7023H)单元用于接收和发送数据的缓存,向该单元写入数据,将发送的数据送入缓存器;读该单元取数据,可以从缓存器读出接收到的单字节数据。UART模块的接收管脚Rx和发送管脚Tx分别与IOB7和IOB10共用。
3 系统软件设计
3.1 程序结构说明
任何一个系统的软件设计都离不开硬件电路的连接,所以本课题硬件设计的高度模块化决定了软件设计的模块化。硬件接口连接如下:
IOA0--IOA2---KEY1---KEY3
IOA3----ADC
IOA4----Relay
IOA8-15----LEDa--dp.
IOB0-IOB2----LEDcs1-cs3
IOB7 IOB10---UART
由此可知其程序结构应包括:主控程序模块、键盘扫描及处理子程序、采样数据处理子程序、PID算法子程序、语音播报及显示等子程序几个部分。结构框图如图12。
图12 程序结构图
主控程序模块在整个结构中充当管理者,管理所有子程序的调用,就相当于个人计算机的操作系统。它主要负责初始化各个I/O口,等待键盘事件的发生,并作出相应的处理。并在适当的时候调用数据采样程序,并将采样到的数据与键盘设定值比较。再通过PID计算后用以控制继电器的开断,从而控制电炉的输出功率,来达到水温的调整,并调用语音播报程序,播放水的温度。
3.2 程序流程图及部分程序
3.2.1 主程序
程序按照模块化设计,所有功能都可通过调用子程序完成,主程序较简单,流程图如图13所示。SPCE061A单片机A口的IOA0~IOA7用作输入口时具有唤醒功能,即具有输入电平变化中断功能(当输入的电平发生变化,电平由高变低或由低变高时),唤醒处于睡眠状态的CPU。对于用电池供电的追求低能耗的应用场合,可以通过软件设置应用CPU的睡眠模式以降低功耗,需要时用按键来唤醒CPU使其进入工作状态。
图13 主程序流程图
在程序编写过程中,首先还有一系列的准备工作。在这个程序中涉及到了许多的库和组成文件,主要有:main.c 、isr.asm、 key.asm、hardware.asm、 led.asm、system.asm 、sacm_user_a2000.h。
由于篇幅原因,在这篇文章中只给出了部分程序。
//=====================================================================
//函数: 主程序
//语法:int main(void)
//描述:语音播报、键盘扫描、温度控制
//参数:无
//返回:无
//=====================================================================
int main(void){
int iKeyValue;
status = system_temperature_set;
guifgSpeechPlay = 0;
System_Initial();
PIDinit();
while(1){
System_ServiceLoop(); //键盘扫描、去抖动处理
iKeyValue = SP_GetCh(); //取键值
key_value_process(iKeyValue); //键值处理
if(guifgSpeechPlay)
temperature_speech_play( ); //语音播放
if(status == system_temperature_control)
display_speech_ADC_temperature(); //测量温度显示、温度播报、PID计算
Clear_WatchDog(); //清看门狗
System_ServiceLoop(); //键盘扫描
if(fOut<=0) turn_off_timerB();
}
}
从主程序中可以看出,在进行一系列程序调用之前对系统进行初始化,然后再对键盘程序有所反应。进而判断是否有温度采集到,有就进行A/D转换和PID计算,将其结果用来控制继电器。
SPCE061A内置的看门狗监视器,其作用就是监测系统是否正常运行。它实际上是一个计数器,它每隔一段时间必须被人为清除(SPCE061A提供的清除周期为0.75s),否则,将产生计数溢出,使系统运行异常,导致系统复位且重新开始执行程序。看门狗监视器可以通过指令设置或屏蔽。看门狗清除寄存器P_Watchdog_Clear在SPCE061A系统正常运行时,只要每隔小于0.75s 向P_Watchdog_Clea单元写入XXXX XXXX XXXX XX01B即可清除看门狗计数器,这样便不会发生看门狗计数溢出,在正常运行时就不会导致系统被复位了。本程序中使用了Clear_WatchDog()函数,其目的就是屏蔽它的定时复位,而造成重新从开始执行程序。
3.2.2 系统初始化
系统的初始化主要包括I/O口的初始化、键盘初始化、A/D初始化等。对端口的初始化,就是对端口寄存器的相应位进行设置。在前面已经说过,要定义相应I/O口位的输入、输出状态和工作方式,就要对三个基本项设置:数据向量Data、属性向量Attribution和方向控制向量Direction。其控制组合如表1所示。
表1 I/O端口控制器设置
Dir
Attrib
Data
功能
唤醒功能
功能描述
0
0
0
下拉
是
带下拉电阻的输入管脚
0
0
1
上拉
是
带上拉电阻的输入管脚
0
1
0
悬浮
是
悬浮式输入管脚
0
1
1
悬浮
否
悬浮式输入管脚
1
0
反相输出
否
Data数据位反相输出
1
1
同相输出
否
Data数据位同相输出
根据本系统端口A、B的不同运用,A口的高八位都是作为高电平输出与显示部分的数据端相连,低八位的IOA0~IOA3用于键盘输入端,IOA4为输出端。B口只用到了低几位作为LED的片选输入端。由此可以得出下列设置:
IOA15-IOA12 IOA11-IOA8 IOA7-IOA4 IOA3-IOA0
Dir: 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 FF10
Attr: 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 FF10
data : 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 FF00
IOA15-IOA12 IOA11-IOA8 IOA7-IOA4 IOA3-IOA0
Dir: 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 000F
Attr: 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 000F
data : 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 000F
由此有以下I/O口初始化程序:
//=====================================================================
//函数: L_User_Init_IO
//语法:L_User_Init_IO()
//描述:初始化A口低八位为下拉电阻输入,高八位为同相高电平输出
// 初始化B口低四位为同相高电平输出,
//参数:无
//返回:无
//=====================================================================
.PUBLIC L_User_Init_IO;
L_User_Init_IO: .PROC
r1 = 0xff10;
[P_IOA_Attrib] = r1;
[P_IOA_Dir] = r1;
r1 = 0xff00;
[P_IOA_Data] = r1;
r1 = 0x000F;
[P_IOB_Attrib] = r1;
[P_IOB_Dir] = r1;
[P_IOB_Data] = r1;
RETF
.ENDP;
3.2.3 键盘程序
⑴ 键盘扫描
由于机械触点有弹性,在按下或弹起按键时会出现抖动,从最初按下到接触稳定要经过数毫秒的弹跳时间,如图所示。为了保证探险键识别的准确性,必须消除抖动。消抖处理有硬件和软件两种方法:硬件消抖是利用加支抖动电路滤避免产生抖动信号;软件消抖是利用数字滤波技术来消除抖动。我们采用软件的方法,利用主程序循环扫描,主程序每循环一次扫描到的键值相同时,则说明是某键按下。
图14 键按下的过程
SPCE061A提供了丰富的键盘API函数,在程序编写的过程中,我们可以直接调用这些函数来完成键盘的初始化、扫描、防拌动处理和获取键值。常用的键盘API函数如下:
CallF_Key_Scan_initial //键初始化
CallF_Key_Scan_ServiceLoopl //键盘扫描
CallF_Key_DebounceCnt_Down //键盘防抖动处理
CallF_SP_GetCh() //获取键值
由于SPCE06A单片机提供了一个系统资源模块,,这是建立在上述诸多模块之上的一个模块,其中许多子程序都调用了在它之下模块中的子程序,为了让上一级的程序调用本模块System.asm文件中的子程序,设有一个接口文件System.inc ,一般只需要三条调用语句。具体实现可参考图15。
图15 System.asm模块框图
//========================================================================
// 函数: System_ServiceLoop();
// 语法: System_ServiceLoop();
// 描述: 程序扫描键盘、按键去抖调度
// 参数: 无
// 返回: 无
//========================================================================
.PUBLIC _System_ServiceLoop;
_System_ServiceLoop: .PROC
call F_Key_Scan_ServiceLoop; //扫描键盘
call F_Key_DebounceCnt_Down; //按键去抖
RETF;
.ENDP
⑵ 键值处理
图16 键值处理
3.2.4 A/D转换值处理
如图17可知,当有温度数据采样到时,调用温度均值处理程序,以防在采样过程中外界干扰而造成采样数据的不准确。然后确定温度系数,使采样转换得到的电压信号转换成温度值,并进行十进制转换,用于显示、语音播报和PID计算。其中均值处理是一个比较重要的过程,是A/D转换前必须进行的工作。下面是A/D处理子程序。
//========================================================================
//函数:void display_speech_ADC_temperature(void)
//语法:void display_speech_ADC_temperature(void)
//描述:整理温度显示值、语音播放资源、PID控制
//参数:无
//返回:无
//========================================================================
void display_speech_ADC_temperature(void)
{ float fT,K;
图17 A/D转换流程图
int adc_data;
static int siTlast = 0;
if(G_ADC_flag){ //判断是否有温度采样 1,有 0,无
G_ADC_flag = 0;
adc_data = adc_data_cmp();
adc_data /= SET_ADC_TIME; //计算温度平均值
if(adc_data >0x0255) K = 0.079; //确定温度系数
else K = 0.076;
fT = adc_data * K; //换算成温度值 //将温度值转换成十进制用于LED显示
guiLED_Value[0] = (int)fT/10;
guiLED_Value[1] = (int)fT%10;
guiLED_Value[2] = (int)(fT*10)%10;
if((int)fT != siTlast){ //判断温度的整数值是否变化
temperature_speech_index(guiLED_Value); //温度整数值语音播放排序
SACM_A2000_Initial(0); //非自动方式播放的初始化
SACM_A2000_InitDecoder(DAC2); //开始对A2000的语音数据以非自动方式解码
SP_INT_IRQ6();
iAddrSpeech = speech_start_address(iaSpeech_index[0]);//语音播放始地址
guifgSpeechPlay = 1; //设置语音为播放状态
siTlast = (int)fT;
}
stPID.Proportion = 1; // 设置PID比例值
stPID.Integral = 0.5; // 设置PID积分值
stPID.Derivative = 0.0; // 设置PID微分值
fOut = 100*PIDCalc ( &stPID,(int)(fT*10) ); // PID计算
active();
}
}
下图是数据采样的中断服务程序,此中断程序采用的是2Hz中断定时0.5秒钟采样一次。
图18 数据采样的中断程序
//========================================================================
//函数: int adc_data_cmp()
//语法: int adc_data_cmp()
//描述: ADC采样数据的均值处理,抗干扰作用
//参数: 无
//返回: 无
//========================================================================
int adc_data_cmp()
{ int max;
int min;
int Sum;
int i;
max = giADC_DataSave[0];
for(i=0;i<10;i++){
if(giADC_DataSave[i]>max)
max = giADC_DataSave[i]; //取出最大值
}
min = giADC_DataSave[i];
for(i=0;i<10;i++){
if(giADC_DataSave[i]<min)
min = giADC_DataSave[i]; //取出最小值
}
for(i=0;i<10;i++)
Sum += giADC_DataSave[i]; //累计值
Sum = Sum - max-min;
展开阅读全文