如何触发 MSP430 的中断?
How do you trigger interrupts for an MSP430?
我需要一些帮助来编程 MSP430。它用于 class 作业。我需要生成一个正弦波,我正在尝试通过使用 TimerA 每 1/50 个周期更改一次输出来实现。我正在使用以下设置:
int main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
TACCTL0 = CCIE;
TACTL = TASSEL_2 + MC_1 + ID_3 + TAIE; //CLK(1MHz) /8
TACCR0 = 25; //25-100 Hz 250-10Hz
P1DIR = 0x00;
P2DIR = 0xFF; //DAC Ouptut
P3DIR = 0x00; //ADC Input
P4DIR = 0x00; //Digital Input
P3SEL |= BIT6 + BIT7;
ADC10CTL0 = SREF_0 + ADC10SHT_3 + MSC + ADC10ON + ADC10IE;
ADC10CTL1 = INCH_7 + ADC10DIV_3 + CONSEQ_1;
ADC10AE0 |= 0xC0; //Turn on ADC of 3.6 and 3.7
ADC10DTC1 = 2;
double amp = 0;
double freq = 0;
unsigned int ADC[2];
for(;;)
{
wave_sel =P4IN;
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY);
ADC10SA = (unsigned int)ADC;
ADC10CTL0 |= ENC + ADC10SC;
freq = (double)ADC[0]/1023;
amp = (double)ADC[1]/1023;
TACCR0 = 25 + (freq*225);
dout *= amp;
dac_write(dout);
}
}
以及具有以下标题的中断:
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
但是当我运行程序时,我无法让中断触发。我可以看到定时器在调试器中计数,并且一旦它像应该的那样命中 TACCR0 就会重置,但中断中没有任何事情发生。我放了一个断点,它从来没有击中过它。我是在声明 ISR 错误吗?
确保通用中断已启用。要启用它们,请设置状态寄存器的 GIE
位。
一个常见的习惯用法是在初始化代码的末尾启用低功耗模式和中断。为此,将此行放在 TACCR0 = 25
:
之后
_BIS_SR(LPM0_bits + GIE);
您似乎使用了两个中断:一个用于定时器 A0 (CCIE
) 上的捕获比较,另一个用于定时器 A 溢出 (TAIE
)。如果您陷入 ISR_trap 那么这可以解释为您没有定时器 A 溢出中断的处理程序。
如果你不打算使用定时器溢出那么你需要改变这一行:
TACTL = TASSEL_2 + MC_1 + ID_3 + TAIE; //CLK(1MHz) /8
对此:
TACTL = TASSEL_2 + MC_1 + ID_3; //CLK(1MHz) /8
如果您确实打算将第二个中断用于定时器 A 溢出,那么您需要确保每次进入中断时都读取 TAIV
寄存器。有多个来源会导致该中断,该寄存器会告诉您是哪个来源引起的。但是,在您阅读它之前它不会被清除(请参阅《MSP430 F2xx 系列用户指南》中的第 12.2.6.2 节 TAIV,中断向量发生器)。
我需要一些帮助来编程 MSP430。它用于 class 作业。我需要生成一个正弦波,我正在尝试通过使用 TimerA 每 1/50 个周期更改一次输出来实现。我正在使用以下设置:
int main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
TACCTL0 = CCIE;
TACTL = TASSEL_2 + MC_1 + ID_3 + TAIE; //CLK(1MHz) /8
TACCR0 = 25; //25-100 Hz 250-10Hz
P1DIR = 0x00;
P2DIR = 0xFF; //DAC Ouptut
P3DIR = 0x00; //ADC Input
P4DIR = 0x00; //Digital Input
P3SEL |= BIT6 + BIT7;
ADC10CTL0 = SREF_0 + ADC10SHT_3 + MSC + ADC10ON + ADC10IE;
ADC10CTL1 = INCH_7 + ADC10DIV_3 + CONSEQ_1;
ADC10AE0 |= 0xC0; //Turn on ADC of 3.6 and 3.7
ADC10DTC1 = 2;
double amp = 0;
double freq = 0;
unsigned int ADC[2];
for(;;)
{
wave_sel =P4IN;
ADC10CTL0 &= ~ENC;
while (ADC10CTL1 & BUSY);
ADC10SA = (unsigned int)ADC;
ADC10CTL0 |= ENC + ADC10SC;
freq = (double)ADC[0]/1023;
amp = (double)ADC[1]/1023;
TACCR0 = 25 + (freq*225);
dout *= amp;
dac_write(dout);
}
}
以及具有以下标题的中断:
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0(void)
{
但是当我运行程序时,我无法让中断触发。我可以看到定时器在调试器中计数,并且一旦它像应该的那样命中 TACCR0 就会重置,但中断中没有任何事情发生。我放了一个断点,它从来没有击中过它。我是在声明 ISR 错误吗?
确保通用中断已启用。要启用它们,请设置状态寄存器的 GIE
位。
一个常见的习惯用法是在初始化代码的末尾启用低功耗模式和中断。为此,将此行放在 TACCR0 = 25
:
_BIS_SR(LPM0_bits + GIE);
您似乎使用了两个中断:一个用于定时器 A0 (CCIE
) 上的捕获比较,另一个用于定时器 A 溢出 (TAIE
)。如果您陷入 ISR_trap 那么这可以解释为您没有定时器 A 溢出中断的处理程序。
如果你不打算使用定时器溢出那么你需要改变这一行:
TACTL = TASSEL_2 + MC_1 + ID_3 + TAIE; //CLK(1MHz) /8
对此:
TACTL = TASSEL_2 + MC_1 + ID_3; //CLK(1MHz) /8
如果您确实打算将第二个中断用于定时器 A 溢出,那么您需要确保每次进入中断时都读取 TAIV
寄存器。有多个来源会导致该中断,该寄存器会告诉您是哪个来源引起的。但是,在您阅读它之前它不会被清除(请参阅《MSP430 F2xx 系列用户指南》中的第 12.2.6.2 节 TAIV,中断向量发生器)。