MSP430G2553定时器间隔

在阅读了大约五次的文字和谷歌搜索后,我决定寻求帮助。 我目前正在使用Timer_A中断以1秒/ 10秒/ 1分钟的间隔打开/关闭两个LED。 默认程序将每秒打开/关闭LED,但我找不到在10秒和1分钟后关闭LED的方法。 我可以使用__delay_cycles(xxxx)来实现这一点,但显然这样做会破坏计时器的目的。 这是我的代码。

#include  #define RedLED BIT0 #define GreenLED BIT6 #define RedLEDToggle (P1OUT ^= RedLED) #define GreenLEDToggle (P1OUT ^= GreenLED) unsigned int counter = 0; void main(void) { WDTCTL = WDTPW | WDTHOLD; //WDTCTL = WDT_MDLY_32; P1DIR = RedLED | GreenLED; P1OUT = RedLED | GreenLED; TACTL = TASSEL_2 | ID_3 | MC_3 | TAIE; TACCR0 = 62500; _enable_interrupts(); LPM1; } #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A(void) { if ( counter == 10) { switch (TAIV) { case 0x02: break; case 0x04: break; case 0x0A: RedLEDToggle | GreenLEDToggle; break; } } else { counter ++; } } 

要实现10秒的中断间隔,需要将输入分频器应用于定时器。 如果没有外围支持,则无法实现1分钟(有关如何使用软件计数器实现该问题,请参阅其他答案)。

问题是msp430微控制器具有16位寄存器,不能保持大于65535的数值。使用32768 Hz的低频振荡器(通常情况下 – 您不提供有关硬件时钟源的任何详细信息)系统,如果它们的频率不同,请注意除非应用输入分频器,否则寄存器每2秒溢出一次。 MSP430x2xxx系列MCU上的输入分频器的最大值为8,因此将来不可能将硬件定时器设置为8 * 2 = 16秒。 有关更多详细信息,请参阅MSP430x2xxx系列用户指南 。

此代码在10秒内调用中断:

 #include  #define RedLED BIT0 #define GreenLED BIT6 #define RedLEDToggle (P1OUT ^= RedLED) #define GreenLEDToggle (P1OUT ^= GreenLED) // 10 seconds, assuming 32768 Hz ACLK source and divider 8 #define TIMER_PERIOD (10u * (32768 / 8)) void main(void) { WDTCTL = WDTPW | WDTHOLD; P1DIR = RedLED | GreenLED; P1OUT = RedLED | GreenLED; // reset timer A config (not strictly needed) TACTL = TACLR; // ACLK as clock source, divider 8, continuous mode, interrupt enabled TACTL = TASSEL_1 | ID_3 | MC_2 | TAIE; // set the period TACCR1 = TIMER_PERIOD; // enable capture/compare interrupts for CCR1 TACCTL1 = CCIE; _enable_interrupts(); LPM1; } #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A(void) { switch (TAIV) { case 0x02: // CCR1 interrupt RedLEDToggle; GreenLEDToggle; // set the time of the next interrupt TACCR1 += TIMER_PERIOD; break; } } 

很简单,

你有1秒的定时器,每1秒钟就会产生一次中断。

你的其他时间是1秒的倍数。

因此,在程序开始时将10秒计数器设置为0并将1分钟计数器设置为0。

在每1秒中断时,递增两个计数器。

每次10秒计数器从9到10步进

  1. 将该计数器重置为0
  2. 处理10秒的活动

每次1分钟计数器从59到60步

  1. 将该计数器重置为0
  2. 处理1分钟的活动

标题定义TAIV值的符号; 使用它们。

XxxLEDToggle定义是完整的语句; 你不应该将它们与|结合起来将它们视为表达式 。

可以从多个源调用中断处理程序。 目前,您的程序不启用任何其他程序,但这可能会更改,因此您应该仅在实际设置TAIFG时运行TAIFG特定代码。

达到限制后,需要将计数器重置为零。

如果有多个计时器间隔,则需要多个计数器。 否则,第一次重置将重置所有间隔的计数。

你需要这样的东西:

 static unsigned int counter_10 = 0; static unsigned int counter_60 = 0; #pragma vector=TIMER0_A1_VECTOR static __interrupt void Timer_A0(void) { switch (TA0IV) { case TA0IV_TACCR1: break; case TA0IV_TACCR2: break; case TA0IV_TAIFG: if (++counter_10 >= 10) { counter_10 = 0; RedLEDToggle; } if (++counter_60 >= 60) { counter_60 = 0; GreenLEDToggle; } break; } }