历史上的今天
返回首页

历史上的今天

今天是:2025年03月14日(星期五)

正在发生

2020年03月14日 | MSP430的软硬件C延时程序设计

2020-03-14 来源:eefocus

MSP430是超低功耗16位单片机,越来越受到电子工程师亲睐并得到广泛应用。C程序直观,可读性好,易于移植和维护,已被很多单片机编程人员所采用。MSP430集成开发环境(如IAR Embedded 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_1000激活WDT中断,每隔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();}

推荐阅读

史海拾趣

Electrolube公司的发展小趣事

在电子行业的激烈竞争中,Electrolube公司始终坚持以客户需求为导向,不断创新和拓展产品线。除了UVCL涂层外,公司还推出了一系列树脂、涂料和热管理解决方案的产品组合,为EV电池提供全面保护。

这些产品不仅具有优异的性能表现,而且能够满足不同客户的需求。例如,某些产品具有优异的耐高温性能,适用于高温环境下的电子设备;而另一些产品则具有出色的耐化学腐蚀性能,能够在恶劣的工作环境中保持稳定的性能。

Electrolube公司通过不断的技术创新和产品优化,成功拓展了市场份额,并在电子行业中树立了良好的品牌形象。同时,公司还积极与各大汽车制造商合作,共同推动电动汽车产业的发展。

Denyo Europa Gmbh公司的发展小趣事

随着技术的成熟,Denyo Europa Gmbh公司开始将目光投向国际市场。公司利用自身的技术优势,结合对目标市场的深入调研,制定了一系列市场拓展策略。通过与当地合作伙伴的紧密合作,公司成功将产品打入多个国家和地区,实现了业务的全球化布局。这一过程中,公司不仅积累了宝贵的国际市场经验,也为公司的持续发展奠定了坚实基础。

诚润电子(CHEVRON)公司的发展小趣事

随着公司业务的不断发展,诚润电子开始积极拓展海外市场。他们通过参加国际展会、与海外客户建立合作关系等方式,逐渐将产品推向全球。在这个过程中,诚润电子不仅提升了自身的品牌知名度,还积累了丰富的国际市场经验。如今,诚润电子的产品已经出口到多个国家和地区,成为了全球电子保护元件领域的重要供应商之一。

EXXELIA Group公司的发展小趣事

在电子行业中,创新是企业持续发展的动力。诚润电子一直保持着对新技术、新产品的敏锐洞察力。他们不断投入研发资金,引进先进的生产设备和技术人才,致力于研发出更加先进、更加符合市场需求的产品。正是这种不断创新的精神,使得诚润电子在电子保护元件领域始终保持领先地位。

DuPont公司的发展小趣事

随着半导体技术的兴起,DuPont公司敏锐地捕捉到了这一领域的发展潜力。公司投入大量资源,致力于半导体材料的研发和生产。通过不断的技术创新,DuPont成功开发出了一系列高性能的半导体材料,如高纯度硅材料、光刻胶等。这些材料在半导体制造过程中发挥着至关重要的作用,极大地推动了半导体技术的进步和产业的发展。

东通电子公司的发展小趣事

东通电子深知人才是企业发展的关键因素。因此,公司一直致力于引进和培养人才,建立了一支高素质、专业化的团队。公司现有员工550人,其中技术人员31人,质量管理人员27人,研发团队12人。这些人才为公司的发展提供了有力的支持,也为公司的技术创新和品质提升奠定了基础。

以上是关于东通电子在电子行业中发展起来的相关故事概述。这些故事展示了东通电子在品质、技术创新、生产规模、环保和人才建设等方面的努力和成就。

问答坊 | AI 解惑

海地地震中 亲身经历证明中国设备最抗震(转)

海地地震中 我的亲身经历证明中国的设备最抗震   (转载自新浪博客—海地通讯日记)   距离海地地震已经9天了,在这9天里,我经历了无数次余震,也通过网络深深感受到祖国的关怀。但是由于忙于抢修和维护通讯设备,所以一直没有时间来和大 ...…

查看全部问答>

我们入职前必备书--video demystified 5th edition

我们的要求的通读前7章。针对显示器开发的必备基础。…

查看全部问答>

三极管的直流放大系数的困惑

1.网上经常看到有人说设三极管的直流放大系数为多少多少    怎么直流放大系数还能自己设置的?不是固定的吗? 2.三极管数据手册上的hfe怎么会有最大最小值?我要取值的话   该取多大的hfe? 望各位兄弟进来探讨探讨 &nb ...…

查看全部问答>

ADS指定地址问题(菜鸟级别问题)

我很久前买了个44B0开发板,没怎么动,现在拿出来玩玩。 想请教一个简单的问题,我想把ADS生成的HEX文件烧写FLASH后,重新启动,能够让程序跳转到SDRAM里运行,跟设置RO BASE 和RW BASE 有关系吗?怎么去实现FLASH程序到SDRAM的跳转?我运行的是跑 ...…

查看全部问答>

COM-1273板卡的CAN总线编程

不知道有没有哪位网友做过COM-1273板卡的CAN总线编程?实在没有办法了,教教小弟如何编程实现。先行谢过。…

查看全部问答>

windriver中用wdreg.exe装驱动的问题

我们的设备驱动是用windriver写的,在没有安装过windriver的机器上发布的话要用其提供的wdreg这个工具来安装windriver核心的驱动以及设备的驱动。 可是在XP下,设备连上PC后,设备管理器中显示是USB mass storage,这时如果用wdreg装驱动的话是装不 ...…

查看全部问答>

针对Intel® Atom处理器N270的电源参考设计

此参考设计旨在给Intel® Atom N270处理器供电。…

查看全部问答>

win7 32 系统安装不了quartus ii

我在不同的网站上下载了quartus10.0 和11.0版本,安装时点击setup.exe后一点反应也没!!防火墙也关过,也试过以管理员省份运行都是一样的效果!!!    那位朋友知道这是咋回事 ???/…

查看全部问答>

c8051F340怎么接收一串数据?

c8051F340怎么接收一串数据?数据由PC上的串口助手发送,波特率19200 我的串口接收中断函数如下,8个字节的数据,一个一个的发,接收正常,但是8个数据一次全发给单片机,接收到数据就错了,要正常一次接收8字节该怎么整呢?      ...…

查看全部问答>