7
西门子6ES7231-7PD22-0XA8产品信息
MSP430是**低功耗16位单片机,越来越受到电子工程师亲睐并得到广泛应用。因此,上海正伟就此解析MSP430的软硬件C延时程序设计,C程序直观,可读性好,易于移植和维护,已被很多单片机编程人员所采用。MSP430集成开发环境(如IAR bbbbbded Workbench和AQ430)都集成了C编译器和C语言级调试器C—SPY。但是C语言难以实现精确延时,这一直困扰着很多MSP430单片机程序员。笔者在实际项目开发过程中,遇到很多需要严格时序控制的接口器件,如单总线数字温度传感器DSl8820、实时时钟芯片PCF8563(需要用普通]/o模拟12C总线时序)、三线制数字电位器AD8402、CF卡(Compact Flash Card)等都需要μs级甚至纳ns级精确延时;而一些慢速设备只需要ms到s级的延时。为此,笔者提出了适合于不同延时级别需要的软件或硬件精确延时方法,并已实际应用,效果良好,大大缩短了开发周期。
1 . 硬件延时,
MSP430单片机系统程序多采用事件驱动机制,即在没有外部事件触发的情况下CPU休眠于低功耗模式中。当外部事件到来时,产生中断CPU,进入相应的中断服务程序(ISR)中。中断响应程序只完成两个任务,一是置位相应事件的标志,二是使MCU退出低功耗模式。主程序负责使MCU在低功耗模式和事件处理程序之间切换,即在主程序中设一个无限循环,系统初始化以后直接进入低功耗模式。MCU被唤醒后,判断各标志是否置位。如果是单一标志置位,那么MCU执行相应的事件处理程序,完成后转入低功耗模式;若是有多个标志同时置位,主程序按照事先排好的消息队列对它们依次判别并进行处理,所有事件处理完毕以后MCU休眠,系统进入低功耗状态(该消息队列的顺序是按照任务的重要性设定的**级)。在这种前后台系统中,由于主程序是无限循环,就必须关闭,与其闲置,不如用其定时器的功能作硬件延时。使用MSP430单片机定时器实现任意时长精确延时,既满足了系统实时低功耗的要求,也弥补了使用无限循环延时的时间难确定和占用CPU时间长的缺点。通过下例,讲解在同一WDT ISR中完成不同时长延时的技巧。
#pragma vector=WD_r_VECTOR
interrupt void WDT_Delay(void){
//中断服务程序
if((DelayTime&Delay500ms)==Delay500ms){
//判断需要500 ms延时的标志是否置位
static unsigned int n250MS=O;
n250MS++;
if(n250MS==2){ //延时250ms×2=500ms
n250MS=0; //清零计数器
DelayTime&=~Delay500ms;//复位标志位
WDTCTL=WDTHOLD+WDTPW;
1El&=~WDTlE;//关闭定时器并禁止其中断
}
}
if((DelayTime&Delay30s)==Delay30s){
//判断需要的30 s延时标志是否置位
static unsigned int nS=0;
nS++;
if(nS==30){ //延时1 s×30=30 s
nS=0; //清零计数器
DelayTime&=~Delay30s;//复位标志位
WDTCTL=WDTHOLD+WDTPW;
IEl&=~WDTlE; //关闭定时器并禁止其中断
}
}
}
如果任务1需要500 ms的延时,只需在需要延时处执行如下语句:
WDTCTL=WDT_ADLY_250;
IE┃ =WDTIE; //①
DelayTime┃=Delay500ms //②
while((DelayTime&Delay500ms)==Delay500ms); //③
①处是配置工作在定时器模式,WDT每隔250 ms产生一次中断请求。可以根据需要改变时钟节拍,在使用32768 Hz晶振作为时钟源时,可以产生1.9ms、16 ms、250 ms和1000 ms的延时基数。在头文件msp430xl4x.h中,将这4种翻转时间的WDT配置宏定义为:WDT_ADLY_1_9、WDT_ADLY_16、WDT_ADLY_250和WDT_ADLY_1000。如果用DCOCLK作为SMCLK的时钟源,WDT选择SMCLK=1 MHz为时钟源,这样可以有O.064 ms、0.5 ms、8 ms和32 ms延时基数可供使用。
②处设置一个标志位,方便WDT ISR判别并进入相应的延时分支。
③处一直判别DelayTime标志组中的Delay500ms位,如果处于置位状态,说明所需的延时未到,执行空操作,直到延时时间到,在WDTISR中将Delay500ms复位,跳出while()循环,执行下一条指令。
同理,如果任务2需要30 s延时,通过WDTCTL=WDT_ADLY_1000WDT中断,每隔1 s进中断一次,在WDT ISR中判别标志发现是Delay30s置位而不是Delay500ms执行30 s延时程序分支。每中断一次,计数器nS加l,直到计到30,说明30 s延时完成,清零计数器,停止(WETCTL=WE)THOLD+WDTPW;)可停止产生中断,并复位该延时标志,以通知任务延时时间到,可以执行下面的指令了。
在WDT ISR中可以根据延时基数和计数器的搭配实现任意长度的时间延时。在系统程序设计时,先确定所需的不同延时时间,然后在WDT。ISR中添加相应的延时分支即可。嵌入式实时操作系统μC/OS—II移植于MSP430单片机就是使用定时器产生时钟节拍的。
对于系统比较简单,只需要单一时长的延时.而又要考虑系统功耗时,介绍另一种使用定时器中断完成延时的方法。若要延时1 s,则设定WDT每250 ms中断一次。在需要延时处,启动定时器并允许其中断,系统进入低功耗模式3(共有5种.模式)休眠。在中断服务程序中对延时时间累加,当达到1 s时唤醒CPU,并停止定时器中断。实例代码如下:
vold main(vold){
WDTCTL=WDT_ADT_ADLY_250)
//启动WDT,每250 ms中断一次
IEII=WDTIE)//使能定时器中断
_BIS_SR(LPM3_bitS+GIE);
//系统休眠于低功耗模式3,开总中断
}
#pragrna vector=WDT_VECTOR
—interrupt void WDT_Delay(void){ //中断服务程序
statlc unsigned charn=4;
if(一一n==O){ //延时4×250 ms=1 s
—BlC_SR_IRQ(LPM3_blts);
//将CPU从低功耗模式3唤醒
WDTCTL=WDTHOLD+WDTPW:
IEl&=~WDTIE;)
//关闭定时器并禁止其中断
}
这种方法充分发挥了MSP430系列的**低功耗特性,在等待延时的过程中,CPU不需要一直判断标志位以得知延时结束,而是进入省电模式。等待过程中,只有较短的时间会在中断服务程序中累计时间并进行判断。可以根据需要设置CPU进入不同的低功耗模式LPMx。如果系统使用了多种外设中断,并在其他中断服务程序中也有唤醒CPU的语句,这种方法便不再适用了。
μs级延时不宜使用硬件延时,因为频繁的进出中断会使CPU用大量时间来响应中断和执行中断返回等操作。硬件延时的方法适用于ms级以上的长时间延时。
2 . 软件延时
在对数字温度传感器DS18820的操作中,用到的延时有:15 μs、90μs、270 μs、540 μs等。这些延时短暂,占用CPU时间不是太多,所以比较适合软件延时的方法。通过汇编语言编写的程序,很容易控制时间,我们知道每条语句的执行时间,每段宏的执行时间及每段子程序加调用的语句所消耗的时间。因此,要用C语言编制出较为精确的延时程序,就必须研究该段C程序生成的汇编代码。
循环结构延时:延时时间等于指令执行时间与指令循环次数的乘积,举例来讲,对如下延时程序进行实验分析。
void delay(unsigned int time){
while(time一一){};
在main()中调用延时函数delayr(n);得到的延时时间是多少,需要在MSP430单片机的集成编译环境IAR Em—bedded Wclrkbeneh IDE 3.10A中编制测试。
使用C430写好一段可执行代码,在其中加入延时函数,并在主函数中调用,以delay(1OO)为例。设置工程选项Options,在Debugger栏中将Drivet选为Simulator,进行软件。在环境C—SPY Debugger中,从菜单View中调出Disassembly和Register窗口,前者显示编程软件根据C语言程序编译生成的汇编程序,在后者窗口中打开CPU Register子窗体,观察指令周期计数器CYCLE—COUNTER。可以看到,delay()编译得到如下代码段:
delav:
001112 OF4C mov.w R12,R15
OOlll4 0C4F mov.w R15.R12
001116 3C53 add.w #0xFFFF.R12
001118 0F93 tst.w R15
00111A FB23 jne deIay
单步执行,观察CYCI正COUNTER,发现每执行一条指令,CYCLECOUNTER的值加1,说明这5条指令各占用1个指令周期,循环体while()每执行一次需要5个指令周期,加上函数调用和函数返回各占用3个指令周期,delay(100)延时了5×100+6—506个指令周期。只要知道指令周期,就能容易的计算出延时时长了。延时函数因循环语句和编译器的不同,执行时间也有所不同,依照上述方法具体分析,可以达到灵活编程的目的。
MSP430的指令执行速度即指令所用的周期数,这里的时钟周期指主系统时钟MCLK的周期。单片机上电后,如果不对时钟系统进行设置,默认800 kHz的DCOCLK为MCLK和SMCLK的时钟源,LFXTl接32768 Hz晶体,工作在低频模式(XTS=O)作为ACLK的时钟源。CPU的指令周期由MCLK决定,所以默认的指令周期就是1/800 kHz=1.25μs。要得到lμs的指令周期需要调整DCO频率,即MCLK=1 MHz,只需进行如下设置:BCSCTLl=XT20FF+RSEL2;
//关闭XT2振荡器,设定DCO频率为1 MHz
DCOCTL=DCO2
//使得单指令周期为lμs
并不是说MSP430单片机软件延时较小的延时基准是lμs,当开启XT2=8 MHz高频振荡器,指令周期可以达到125 ns。MSP430F4XX系列的单片机由于采用了增强型锁频环技术FLL+,可以将DCO频率倍增到40MHz,从而得到较快25 ns的指令周期。
调用延时函数的方法适合于100 μs~1 ms之间的延时,100μs以下的短延时较好通过空操作语句_NoP()或其任意个组合来实现。可使用宏定义实现需要的延时,如要延时3 μs,则:
#define DELAY5US{_NOP();_NOP();_NOP();}


1.2可编程控制器基本特点
从讨论PLC的工作原理知,PLC的输入与输出在物理上是彼此隔开的,其间的联系是靠运行存储于它的内存中的程序实现。它的入出相关,不是靠物理过程,不是用线路;而是靠信息过程,用软逻辑联系。它的工作基础是用好信息。
信息不同于物质与能量,有自身的规律。信息便于处理,便于传递,便于存储;信息还可重用,等等。正是由于信息的这些特点,决定了PLC的基本特点。
下面介绍PLC的四个特点:
1.2.1功能丰富
PLC的功能非常丰富。这主要与它具有丰富的处理信息的指令系统及存储信息的内部器件有关。
它的指令多达几十条、几百条,可进行各式各样的逻辑问题的处理,还可进行各种类型数据的运算。凡普通计算机能做到的,它也都可作到。
它的内部器件,即内存中的数据存储区,种类繁多,容量宏大。I/O继电器,可以用以存储入、出点信息的,少的几十、几百,多的可达几千、几万,以至10几万。这意味着它可进行这么多I/O点的入出信息变换,进行这么大规模的控制。
它的内部种种继电器,相当于中间继电器,数量更多。内存中一个位就可作为一个中间继电器,怎么不多!
它的计数器、定时器也很多,是继电电路所望尘莫及的。小小的箱体或模块,其内部定时器、计数器可达成百、成千。这也是因为只要用内存中的一个字,再加一些标志位,即可成为定时器、计数器,所以才那么多。
而且,这些内部器件还可设置成丢电保持的,或丢电不保持的,即上电后予以清零的。以满足不同的使用要求。这些也是继电器件所难以做到的。
它的数据存储区还可用以存储大量数据,几百、几千、几万字的信息都可以存,而且,掉电后还不丢失。
PLC还有丰富的外部设备,可建立友好的人机界面,以进行信息交换。可送入程序,送入数据,可读出程序,读出数据。而且读、写时可在图文并茂的画面上进行。数据读出后,可转储,可打印。数据送入可键入,可以读卡入,等等。
PLC还具有通讯接口,可与计算机链接或联网,与计算机交换信息。自身也可联网,以形成单机所不能有的更大的、地域更广的控制系统。
PLC还有强大的自检功能,可进行自诊断。其结果可自动记录。这为它的维修增加了透明度,提供了方便。
丰富的功能为PLC的广泛应用提供了可能;同时,也为工业系统的自动化、远动化及其控制的智能化创造了条件。
像PLC这样集丰富功能于一身,是别的电控制器所没有的;更是传统的继电控制电路所无法比拟的。
1.2.2使用方便用PLC实现对系统的控制是非常方便的。这是因为:首先PLC控制逻辑的建立是程序,用程序代替硬件接线。编程序比接线,更改程序比更改接线,当然要方便得多!
其次PLC的硬件是高度集成化的,已集成为种种小型化的模块。而且,这些模块是配套的,已实现了系列化与规格化。种种控制系统所需的模块,PLC厂家多有现货供应,市场上即可购得。所以,硬件系统配置与建造也非常方便。
正因如此,用可编程序控制器才有这个"可"字。对软件讲,它的程序可编,也不难编。对硬件讲,它的配置可变,而且也易于变。
具体地讲,PLC有五个方面的方便:
(1)配置方便:可接控制系统的需要确定要使用哪家的PLC,那种类型的,用什么模块,要多少模块,确定后,到市场上定货购买即可。
(2)安装方便:PLC硬件安装简单,组装容易。外部接线有接线器,接线简单,而且一次接好后,更换模块时,把接线器安装到新模块上即可,都不必再接线。内部什么线都不要接,只要作些必要的DIP开关设定或软件设定,以及编制好用户程序就可工作。
(3)编程方便:PLC内部虽然没有什么实际的继电器、时间继电器、计数器,但它通过程序(软件)与系统内存,这些器件却实实在在地存在着。其数量之多是继电器控制系统难以想象的。即使是小型的PLC,内部继电器数都可以千计,时间继电器、计数也以百计。而且,这些继电器的接点可无限次地使用。PLC内部逻辑器件之多,用户用起来已不感到有什么限制。一考虑的只是入出点。而这个内部入出点即使用得再多,也无关紧要。大型PLC的控制点数可达万点以上,哪有那么大的现实系统?若实在不够,还可联网进行控制,不受什么限制。PLC的指令系统也非常丰富,可毫不困难地实现种种开关量,以及模拟量的控制。PLC还有存储数据的内存区,可存储控制过程的所有要保存的信息。……总之,由于PLC功能之强,发挥其在控制系统的作用,所受的限制已不是PLC本身,而是人们的想象力,或与其配套的其它硬件设施了。
PLC的外设很丰富,编程器种类很多,用起来都较方便,还有数据监控器,可监控PLC的工作。使用PLC的软件也很多,不仅可用类似于继电电路设计的梯形图语言,有的还可用BASIC语言、C语言,以至于自然语言。这些也为PLC编程提供了方便。
PLC的程序也便于存储、移植及再使用。某定型产品用的PLC的程序完善之后,凡这种产品都可使用。生产一台,拷贝一份即可。这比起继电器电路台台设备都要接线、调试,要省事及简单得多。
(4)维修方便:这是因为:
①PLC工作可靠,出现故障的情况不多,这大大减轻了维修的工作量。这在讲述PLC的*三个特点时,还将进一步介绍。
②即使PLC出现故障,维修也很方便。这是因为PLC都设有很多故障提示信号,如PLC支持内存保持数据的电池电压不足,相应的就有电压低信号指示。而且,PLC本身还可作故障情况记录。所以,PLC出了故障,很易诊断。同时,诊断出故障后排故也很简单。可按模块排故,而模块的备件市场可以买到,进行简单的更换就可以。至于软件,调试好后不会出故障,再多只要依据使用经验进行调整,使之完善就是了。
(5)改用方便:PLC用于某设备,若这个设备不再使用了,其所用的PLC还可给别的设备使用,只要改编一下程序,就可办到。如果原设备与新设备差别较大,它的一些模块还可重用。