历史上的今天
返回首页

历史上的今天

今天是:2025年02月28日(星期五)

正在发生

2020年02月28日 | MSP430系列嵌入式实验教程---定时器

2020-02-28 来源:eefocus

定时器模块是MSP430单片机中非常重要的资源,可以用来实现定时控制、频率测量、脉宽测量以及PWM等信号产生。MSP430单片机定时器资源包括看门狗定时器(WDT)、通用定时器(timer)和实时时钟(RTC)。这一节则主要讲述普通定时器。

定时器

由图可知,Timer_A定时器主要分为两个部分:主计数器和捕获/比较模块。主计数器负责定时、计时或计数,计数器的值被送到各个捕获比较模块中,它们可以在无CPU干预的情况下根据触发条件与计数器值自动完成某些测量和输出功能。只需定时、计数功能时,可以只使用主计数器部分。在PWM调制、利用捕获测量脉宽、频率等应用中,还需要捕获/比较模块的配合。


16位定时器原理

16位定时器的计数值寄存器TAR在每个时钟信号的上升沿进行增加/减少,可利用软件读取TAR寄存器的计数值。此外,当定时时间到,产生溢出时,定时器可产生中断。置位定时器控制寄存器中的TACLR控制位,可自动清除TAR寄存器的计数值,同时,在增/减计数模式下,清除了时钟分频器和计数方向。


时钟源选择和分频器

定时器的参考时钟源可以来自内部时钟ACLK、SMCLK或者来自TACLK引脚输入,可通过TASSEL控制位进行选择。选择的时钟源首先通过ID控制位进行1、2、4、8分频,对于分频后的时钟,可通过TAIDEX控制位进行1、2、3、4、5、6、7、8分频。


Timer_A工作模式

Timer_A共有4种工作模式:停止模式、增计数模式、连续计数模式和增/减计数模式,具体工作模式可以通过MC控制位进行选择。

MC控制位配置值 Timer_A工作模式 描述

00 停止模式 Timer_A停止

01 增计数模式 Timer_A从0到TAxCCR0重复计数

10 连续计数模式 Timer_A从0到0FFFFh重复计数

11 增/减计数模式 Timer_A从0增计数到TAxCCR0之后减计数到0,循环往复


停止模式。停止模式用于定时器暂停,并不发生复位,所有寄存器现行的内容在停止模式结束后都可用。当定时器暂停后重新计数时,计数器将从暂停时的值开始以暂停前的计数方向计数。例如,停止模式前,Timer_A定时器工作于增/减计数模式并且处于下降计数方向,停止模式后,Timer_A仍然工作于增/减计数模式下,从暂停前的状态开始继续沿着下降方向开始计数。若不想这样,则可通过TAxCTL中的TACLR控制位来清除定时器的计数及方向记忆特性。


增计数模式。比较寄存器TAxCCR0用作Timer_A增计数模式的周期寄存器。由于TAxCCR0为16位寄存器,所以在该模式下,定时器A连续计数值应小于0FFFFh。TAxCCR0的数值定义了定时的周期,计数器TAR可以增计数到TAxCCR0的值,当计数值与TAxCCR0的值相等(或定时器值大于TAxCCR0的值)时,定时器复位并从0开始重新计数。


增计数

当定时器计数值计数到TAxCCR0时,置位CCR0中断标志位CCIFG。

增计数

当定时器从TAxCCR0计数到0时,置位Timer_A中断标志位TAIFG。增计数模式下中断标志位设置过程如图所示。

中断标志

示例

利用TA0定时器,使其工作在增计数模式,采用SMCLK作为其计数参考时钟,并启用TA0CCR0计数中断,在TA0中断服务程序中反转P1.0口状态,以便于用示波器进行观察。

#include

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD;                // 关闭看门狗

  P1DIR |= 0x01;                            // P1.0设为输出

  TA0CCTL0 = CCIE;                          // CCR0中断使能

  TA0CCR0 = 50000;

  TA0CTL = TASSEL_2 + MC_1 + TACLR;  // SMCLK, 增计数模式, 清除TAR计数器

  _ _bis_SR_register(LPM0_bits + GIE);  // 进入LPM0,使能中断

}

// TA0中断服务程序

#pragma vector=TIMER0_A0_VECTOR

_ _interrupt void TIMER0_A0_ISR(void)

{

  P1OUT ^= 0x01;                            // 反转P1.0口输出状态

}


连续计数模式。在连续计数模式下,Timer_A定时器增计数到0FFFFh之后从0开始重新计数,如此往复。

增计数

当定时器计数值从0FFFFh计数到0时,置位Timer_A中断标志位,连续计数模式下的中断标志位设置过程如图所示。

中断标志

连续计数模式的典型应用如下:


产生多个独立的时序信号:利用捕获比较寄存器捕获各种其他外部事件发生的定时器数据。


产生多个定时信号:在连续计数模式下,每完成一个TAxCCRn(其中n取值为0~6)计数间隔,将产生一个中断,在中断服务程序中,将下一个时间间隔计数值赋给TAxCCRn,下图表示了利用两个捕获比较寄存器TAxCCR0和TAxCCR1产生两个定时信号t0和t1。在这种情况下,定时完全通过硬件实现,不存在软件中断响应延迟的影响,具体实现示意图如下图所示。

多个定时信号

示例

利用TA1定时器,使其工作在连续计数模式下,采用SMCLK作为其计数参考时钟,使能TAIFG中断。在TA1中断服务程序中反转P1.0口状态,以便于用示波器进行观察。


#include

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD;              // 关闭看门狗

  P1DIR |= 0x01;                           // P1.0设为输出

  TA1CTL = TASSEL_2 + MC_2 + TACLR + TAIE;  

// SMCLK,连续计数模式,清除TAR,并使能TAIFG中断

  _ _bis_SR_register(LPM0_bits + GIE); // 进入LPM0, 并启动中断

}

// TA1中断服务程序

#pragma vector=TIMER1_A1_VECTOR

_ _interrupt void TIMER1_A1_ISR(void)

  switch(_ _even_in_range(TA1IV,14))

  {

    case  0: break;                          // 无中断

    case  2: TACCR1 += 500; break;                          // TA1CCR1 CCIFG中断

    case  4: TACCR2 += 300; break;                          // TA1CCR2 CCIFG中断

    case  6: break;                        // TA1CCR3 CCIFG中断

    case  8: break;                        // TA1CCR4 CCIFG中断

    case 10: break;                        // TA1CCR5 CCIFG中断

    case 12: break;                      // TA1CCR6 CCIFG中断

    case 14: P1OUT ^= 0x01;              // TAIFG中断

             break;

    default: break; 

  }

}


增/减计数模式,需要对称波形的情况往往可以使用增/减计数模式。在该模式下,定时器先增计数到TAxCCR0的值,然后反方向减计数到0。计数周期仍由TAxCCR0定义,它是TAxCCR0值的2倍。增/减计数模式下的计数过程如图所示。

增减

在增/减计数模式下,TAxCCR0中断标志位CCIFG和Timer_A中断标志位TAIFG在一个周期内仅置位一次。当定时计数器增计数从TAxCCR0-1计数到TAxCCR0时,置位TAxCCR0中断标志位CCIFG,当定时计数器减计数从0001h到0000h时,置位Timer_A中断标志位TAIFG。增/减计数模式下中断标志位的设置过程如图所示。

中断标志

捕获/比较模块

除了主计数器外,Timer_A定时器还具有7个(不同系列模块数量有差异)相同的捕获/比较模块,任何一个捕获/比较模块都可以用于捕获事件发生的时间或产生的时间间隔。每个捕获/比较模块都可有单独的模式控制寄存器及捕获/比较值寄存器。


在比较模式下,每个捕获/比较模块将不断地将自身的比较值寄存器与主计数器的计数值TAR进行比较,一旦相等,就将自动改变定时器输出引脚的输出电平。Timer_A有八种输出模式,从而可以无须CPU干预的情况下输出PWM波,可变单稳态脉冲、移向方波、相位调制等常用波形。


在捕获模式下,用定时器输入引脚电平跳变触发捕获电路,将此刻主计数器值TAR自动保存在相应的捕获值寄存器TACCRx下。这可以用于测频率、测周期、测脉宽、测占空比等需要获得波形精确时间量的场合。


捕获/比较模块的逻辑结构如图所示,在此以捕获/比较模块TAxCCR6为例进行介绍。捕获比较模块

比较模式

当CAP控制位设为0时,捕获/比较模块工作在比较模式。比较模式用来产生PWM输出信号或者在特定的时间间隔产生中断。此时TAxCCRn的值可由软件写入,并通过比较器与主计数器的计数值TAR进行比较,当TAR计数到TAxCCRn时,将依次产生以下事件:


置位中断标志位CCIFG;

产生内部信号EQUn=1;

EQUn信号根据不同的输出模式触发输出逻辑;

输入信号CCI被锁存到SCCI。


每个捕获/比较模块都包含一个输出单元,用于产生输出信号,例如PWM信号等。每个输出单元都有8种工作模式,可产生EQUx的多种信号。输出模式可通过OUTMOD控制位进行定义增计数

增计数

利用定时器TA0,使其工作在增计数模式下,选择ACLK作为其参考时钟。将P1.2和P1.3引脚配置为定时器输出,且使CCR1和CCR2工作在比较输出模式7下,最终使P1.2引脚输出75%占空比的PWM波形,使P1.3引脚输出25%占空比的PWM波形,可通过示波器进行观察。


#include

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD;            // 关闭看门狗

  P1DIR |= BIT2+BIT3;                   // P1.2和P1.3设为输出

  P1SEL |= BIT2+BIT3;                   // P1.2和P1.3引脚功能选为定时器输出

  TA0CCR0 = 512-1;                  // PWM周期定义

  TA0CCTL1 = OUTMOD_7;                // CCR1比较输出模式7:复位/置位

  TA0CCR1 = 384;                        // CCR1 PWM 占空比定义

  TA0CCTL2 = OUTMOD_7;                // CCR2 比较输出模式7:复位/置位

  TA0CCR2 = 128;                        // CCR2 PWM 占空比定义

  TA0CTL = TASSEL_1 + MC_1 + TACLR; // ACLK,增计数模式,清除TAR计数器

  _ _bis_SR_register(LPM3_bits);    // 进入LPM3

}


捕获模式。

当CAP控制位置为1时,捕获/比较模块配置为捕获模式。捕获模式被用于捕获事件发生的时间。捕获输入CCIxA和CCIxB可连接外部引脚或内部信号,这需通过CCIS控制位进行配置。可通过CM控制位将捕获输入信号触发沿配置为上升沿触发、下降沿触发或两者都触发。捕获事件在所选输入信号触发沿产生,如果产生捕获事件,定时器将完成以下工作:


主计数器计数值复制到TAxCCRn寄存器中;

置位中断标志位CCIFG。


输入信号的电平可在任意时刻通过CCI控制位进行读取。捕获信号可能会和定时器时钟不同步,并导致竞争条件的产生,将SCS控制位置位可在下一个定时器时钟使捕获同步。


如果第二次捕获在第一次捕获的值被读取之前发生,捕获/比较寄存器就会产生一个溢出逻辑,在此情况下,将置位COV标志位。注意COV标志位必须通过软件消除。


利用TA1定时器,使其工作在捕获模式,上升沿触发捕获,参考时钟选择SMCLK,通过中断读取定时器捕获值。将ACLK通过P1.0引脚输出,并与P2.0引脚相连,P2.0配置为定时器捕获输入。


#include

int i=0;

int Cycle[2];

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD;              // 关闭看门狗

  P1DIR |= BIT0;

  P1SEL |= BIT0;                            // 将P1.0引脚配置为ACLK输出

  P2DIR &=~BIT0;

  P2SEL |= BIT0;                            // 将P2.0引脚配置为定时器捕获输入

  TA1CTL = TASSEL_2 + MC_2 + TACLR ; 

 //TA1主计数器时钟选择SMCLK,连续计数模式,清除TAR

  TA1CCTL1 = CM0 + SCS + CAP + CCIE; // CCR1工作于捕获模式,上升沿触发

  _ _bis_SR_register(LPM0_bits + GIE); // 进入LPM0并使能全局中断

}



// TA1中断服务程序

#pragma vector=TIMER1_A1_VECTOR

_ _interrupt void TIMER0_A1_ISR(void)

{

switch( _ _even_in_range(TAIV,14) )

  {

    case  0: break;                      // 无中断产生

    case  2: 

    Cycle[i]=TA1CCR1;               //读取捕获值

    i++;

    if(i==2) i=0;

    break;                      // CCR1中断

    case  4: break;                    // CCR2中断

    case  6: break;                        // CCR3中断

    case  8: break;                      // CCR4中断

    case 10: break;                      // CCR5中断

    case 12: break;                      // CCR6中断

    case 14:  break;            // TAIFG溢出中断

    default: break;

  }

}


中断

TAxCCR0的中断向量具有最高的中断向量CCIFG0

优先级最高,单独一个中断服务函数,不需要手动清除CCIFG0


其余的TAxCCRn的中断标志CCIFGn及TAIFG的中断向量是TAIV

TAxIV包含TAxCCRn的中断标志CCIFGn和TAIFG,因此可用TAxIV判断中断源,每次访问TAxIV时都会自动清除最高优先级的中断标志位。

推荐阅读

史海拾趣

ETA-USA公司的发展小趣事

进入XXXX年代,ETA-USA开始将重心转向CAE(计算机辅助工程)软件的开发。公司投入大量资源进行研发,成功推出了一系列创新的CAE软件解决方案,如Dynaform,这些软件在覆盖件冲压成形、汽车碰撞模拟等领域取得了显著的应用效果。这一突破不仅巩固了ETA-USA在电子工程领域的地位,也为其后续发展奠定了坚实的基础。

成都振芯/国腾(CORPRO)公司的发展小趣事

2010年,CORPRO在深交所创业板成功上市,成为当时国内“卫星导航第一股”。这一里程碑事件不仅提升了CORPRO的品牌知名度和市场影响力,也为公司后续的发展提供了更为广阔的资金来源和市场空间。上市后,CORPRO继续加大研发投入,推动技术创新和产品升级。

ALTERA(阿尔特拉)公司的发展小趣事

2003年,成都国腾微电子有限公司(后更名为成都振芯科技股份有限公司)正式成立,标志着CORPRO的起点。公司由成都国腾电子集团投资设立,创始人团队汇聚了来自中国物资储运集团、电子科技大学等单位的精英。在成立之初,CORPRO就致力于集成电路、微波组件及相关电子器件的设计、开发与销售,奠定了其在电子行业的基础。

ANOVA公司的发展小趣事

ANOVA公司的成功并非偶然,它始终站在技术创新的前沿。公司积极推动新通信技术、电池寿命和移动应用等方面的创新,不断推动电子行业的发展。ANOVA的研发团队不断探索新技术,致力于为客户提供最先进的解决方案,帮助客户在激烈的市场竞争中保持领先地位。

Eaton公司的发展小趣事

伊顿公司起源于1911年,由Viggo Torbensen和年轻商人Joseph Eaton共同创建的Torbensen齿轮轴承公司,这是伊顿的前身。Joseph Eaton坚信战略收购是拓展业务的最佳方法,因此在公司的发展过程中,他积极推动了一系列重要的收购活动。随着时间的推移,公司的产品逐渐多元化,从最初的齿轮轴承扩展到更广泛的能源管理领域。到1932年,公司更名为伊顿制造公司,进一步彰显了其向多元化发展的决心。

Frequency Electronics Inc公司的发展小趣事

高频电子在精确时间和频率生成技术方面一直处于世界领先地位。公司不断投入研发,推出了一系列高精度、高性能的定时和频率控制产品,如铷蒸气原子振荡器、温度稳定的石英晶体振荡器等。这些产品被广泛应用于商业、政府、军事等多个领域,包括卫星通信、指挥控制系统、电子战系统等。高频电子的技术创新不仅提升了自身竞争力,还推动了整个行业的发展。

问答坊 | AI 解惑

2.4G天线信号传输损耗

损耗是指在传输过程中因传输介质等因素引起的能力损失。…

查看全部问答>

二极管her307能不能用her308代替

望高手解答一下,在此先谢谢了!!!…

查看全部问答>

pdu usc-2 中文编码

我在linux下开发短信,使用开源的smstools来开发。 使用pdu模式时,发现对英语与数字可以很简单地实现。 但使用中文信息时,发现移动发过来的pdu报文解不正确。 如报文:测试 =“6D4B8BD5” 将两位一组转换为16进制数值,再转换为无符号字符。 ...…

查看全部问答>

寻求指引:不知如何问起的问题,关于和PC通讯方面(软硬驱动都需要)

(我一直做软件,虽然对Windows核心也有所了解,但却从未真正写过驱动,也未写过单片机软件,提的问题可能很不专业,请多包涵,多给点指引) 简单的说,可能这样:公司安排我项任务,改进一些旧的仪器。以前所有的仪器都是用RS232跟电脑连接的,我 ...…

查看全部问答>

各位大哥,你们好,我的朋友想学习plc但不知道用什么开发工具,希望你们能提供一些信息!谢谢

各位大哥,你们好,我的朋友想学习plc但不知道用什么开发工具,希望你们能提供一些信息!谢谢…

查看全部问答>

wince驱动开发的朋友

wince驱动开发,学了快半年了,想结交同样做wince驱动开发的朋友, QQ:181822723 …

查看全部问答>

想应聘嵌入式软件开发工程师,不知道看些什么书好

对嵌入式系统几乎知道很少知识     但是想应聘嵌入式软件开发工程师,不知道临时补充些什么知识,并且希望大家能推荐出书目来,谢谢 …

查看全部问答>

LM3S9997 J-LINK KEIL

LM3S9997 J-LINK KEIL 这几天做了个LM3S9997的最小系统。。。。 JTAG已经连接上了。。。读到的IDCODE是 0X4BA00477。。。然后用打开LM3S8662的一个LED例程。。。   有个错误。无法下载程序:error :flash DOWNLOAD FAILED - CORTEX-M3 好 ...…

查看全部问答>

STM8S常见问题大杂烩

最近再使用STM8S207RB进行开发,以下是自己使用cosmic时遇到的一些常见问题: 1.printf/sprintf入口参数必须是u16类型,否则打印结果不正确,很奇怪 2.u32位类型的判断if ((val%0x1000) == 0)此判断前必须强制转换,即     if ((u ...…

查看全部问答>

变压器制作知识

本帖最后由 paulhyde 于 2014-9-15 04:02 编辑 变压器制作大家一起学  …

查看全部问答>