MSP430单片机那些事儿(5)中断函数编写方法 了解多种单片机的电子工程师都知道,基本上每一种单片机都有中断,关于中断的优点不多说了,具体到MSP430单片机,由于其超低功耗特性,所以它的中断系统更是非常强大,因为要实现超低功耗,最重要的一点就是让单片机大部分时间处于休眠状态,利用中断来唤醒单片机,中断执行完后,再尽快再次进入休眠状态。 MSP430单片机的中断是如此强大:种类多、功能强。正因为中断种类多,中断函数的编写就要特别注意。
单片机中断函数的编写一般有三种方法: 1、对于单源中断(或者多源中断中只启用了一种中断),其中断函数可以如下面例子所示。
- #include <msp430.h>
- int main(void)
- {
- WDTCTL = WDTPW | WDTHOLD; // Stop WDT
- // Setup P1.0 output
- P1DIR |= BIT0; // Set P1.0 to output direction
- P1OUT &= ~BIT0; // Clear P1.0
- // Setup TA0
- TA0CCTL0 = CCIE; // CCR0 interrupt enabled
- TA0CCR0 = 50000;
- TA0CTL = TASSEL_2 | MC_1 | TACLR; // SMCLK, upmode, clear TAR
- __bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupt
- __no_operation(); // For debugger
- }
- // Timer0_A0 interrupt service routine
- #pragma vector=TIMER0_A0_VECTOR
- __interrupt void TIMER0_A0_ISR(void)
- {
- P1OUT ^= BIT0; // Toggle P1.0
- }
复制代码
2、多源中断,方法一是采用查询中断标志的方法编写中断函数。如下面例子所示
- #pragma vector=USCI_A0_VECTOR
- __interrupt void USCI_A0_ISR(void)
- {
- // 接收中断
- if( ( UCA0IFG & UCRXIFG ) != 0 )
- {
-
- }
- // 发送中断
- if( ( UCA0IFG & UCTXIFG ) != 0 )
- {
-
- }
- }
复制代码
3、多源中断,方法二是采用IAR库函数推荐的switch-case方法。如下面例子所示。
// Timer0_A1 Interrupt Vector (TAIV) handler #pragma vector=TIMER0_A1_VECTOR __interrupt void TIMER0_A1_ISR(void) { switch (__even_in_range(TA0IV, 14)) { case TA0IV_NONE: break; // No interrupt case TA0IV_TA0CCR1: break; // TA0CCR1_CCIFG case TA0IV_TA0CCR2: break; // TA0CCR2_CCIFG case 6: break; // Reserved case 8: break; // Reserved case 10: break; // Reserved case 12: break; // Reserved case TA0IV_TA0IFG: // TA0IFG P1OUT ^= BIT0; // Toggle P1.0 break; default: break; } }
我们今天重点说说这第三种方法。 这里有几个需要说明的地方。第一是__even_in_range(TA0IV, 14),这个函数是什么意思? __even_in_range的原型在intrinsic.h文件里,关于这个函数的解释是这样的 第二:__value的值从哪里得来?我们来看看msp430x5xx,6xx的用户指南,找到TimerA的寄存器TAxIV。如下图所示,这样不但明白这个值是怎么来的,也很清楚为什么这个值必须是偶数了。
第三:__bound的值如何确定,有什么讲究? 上面说了__bound必须是偶数,至于它的值是多少,首先要根据它的数据类型unsigned short,取值必须在这个类型的范围之内,其次,如果对于这个中断里面中断向量比较高的中断不想响应,那就可以把这个值取低一点,就可以完美的解决这个问题。
“在msp430里经常被用在多源中断的查询中,如 switch( __even_in_range(TAIV,10)
只有在TAIV的值是在0--10内的偶数时才会执行switch函数内的语句其作用是提高switch语句的效率”
|