MSP430G2553 定时器间隔
MSP430G2553 Timer Intervals
阅读文本大约五遍并使用谷歌搜索后,我决定寻求帮助。我目前正在使用 Timer_A 中断以 1 second/10 seconds/1 分钟的间隔一次打开 on/off 两个 LED。默认程序每秒会打开 on/off LED,但我找不到在 10 秒零一分钟后关闭它们的方法。我可以使用 __delay_cycles(xxxx) 来实现这一点,但显然这样做会破坏计时器的目的。这是我的代码。
#include <msp430.h>
#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 ++;
}
}
很简单,\
你有一个 1 秒的定时器,它每 1 秒产生一次中断。
您的其他时间是该 1 秒的倍数。
因此,在程序开始时将 10 秒计数器设置为 0,并将 1 分钟计数器设置为 0。
每 1 秒中断一次,增加两个计数器。
每次 10 秒计数器从 9 步进到 10
- 将该计数器重置为 0
- 处理 10 秒 activity
每次 1 分钟计数器从 59 跳到 60
- 将该计数器重置为 0
- 处理 1 分钟 activity
header 定义了 TAIV
值的符号;使用它们。
XxxLEDToggle
定义的是完整的语句;您不应该将它们与 |
.
组合起来视为表达式
可以从多个源调用中断处理程序。
目前,您的程序没有启用任何其他程序,但这很可能会改变,因此您应该 运行 您的 TAIFG-specific 代码仅当 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;
}
}
要实现10秒的中断间隔,需要对定时器应用输入分频器。没有外设支持是不可能达到 1 分钟的(请参阅其他答案,了解如何使用软件计数器实现)。
问题是 msp430 微控制器有 16 位寄存器,不能保存大于 65535 的数值。使用 32768 Hz 的低频振荡器 运行(这是典型的 - 你不提供有关系统硬件时钟源的任何详细信息,如果它们具有不同的频率,请说明)除非应用输入分频器,否则寄存器每 2 秒溢出一次。 MSP430x2xxx 系列 MCU 上输入分频器的最大值为 8,因此以后不可能将硬件定时器设置为超过 8 * 2 = 16 秒。有关详细信息,请参阅 MSP430x2xxx family user's guide。
此代码每 10 秒调用一次中断:
#include <msp430.h>
#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;
}
}
阅读文本大约五遍并使用谷歌搜索后,我决定寻求帮助。我目前正在使用 Timer_A 中断以 1 second/10 seconds/1 分钟的间隔一次打开 on/off 两个 LED。默认程序每秒会打开 on/off LED,但我找不到在 10 秒零一分钟后关闭它们的方法。我可以使用 __delay_cycles(xxxx) 来实现这一点,但显然这样做会破坏计时器的目的。这是我的代码。
#include <msp430.h>
#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 ++;
}
}
很简单,\
你有一个 1 秒的定时器,它每 1 秒产生一次中断。
您的其他时间是该 1 秒的倍数。
因此,在程序开始时将 10 秒计数器设置为 0,并将 1 分钟计数器设置为 0。
每 1 秒中断一次,增加两个计数器。
每次 10 秒计数器从 9 步进到 10
- 将该计数器重置为 0
- 处理 10 秒 activity
每次 1 分钟计数器从 59 跳到 60
- 将该计数器重置为 0
- 处理 1 分钟 activity
header 定义了 TAIV
值的符号;使用它们。
XxxLEDToggle
定义的是完整的语句;您不应该将它们与 |
.
可以从多个源调用中断处理程序。 目前,您的程序没有启用任何其他程序,但这很可能会改变,因此您应该 运行 您的 TAIFG-specific 代码仅当 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;
}
}
要实现10秒的中断间隔,需要对定时器应用输入分频器。没有外设支持是不可能达到 1 分钟的(请参阅其他答案,了解如何使用软件计数器实现)。
问题是 msp430 微控制器有 16 位寄存器,不能保存大于 65535 的数值。使用 32768 Hz 的低频振荡器 运行(这是典型的 - 你不提供有关系统硬件时钟源的任何详细信息,如果它们具有不同的频率,请说明)除非应用输入分频器,否则寄存器每 2 秒溢出一次。 MSP430x2xxx 系列 MCU 上输入分频器的最大值为 8,因此以后不可能将硬件定时器设置为超过 8 * 2 = 16 秒。有关详细信息,请参阅 MSP430x2xxx family user's guide。
此代码每 10 秒调用一次中断:
#include <msp430.h>
#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;
}
}