按键中断的一个小尝试
@Board: MSP-EXP430F5529
@Keys: S1(P1.7) S2(P2.2)
@LEDs: LED2(P8.1) LED3(P8.2)
-
电路原理图如下
- 关于MSP430的GPIO
- 在所有GPIO中,仅有P1.x和P2.x可以被配置为GPIO中断
- 所有GPIO均可被独立配置为输出/输入模式,以及高低电平等
- 实验中用的硬件配置
- 若P1.7和P2.2为高电平输出,则按键按下后,其电平瞬间被拉低,可据此检测按键是否按下
- 中断触发方式可选上升沿触发和下降沿触发,这里选择下降沿触发,即按键按下触发而非按下弹起触发
- LED2和LED3需要P8.1和P8.2输出高电平才能点亮,故设置P8.x为高电平输出
- 中断向量
- MSP430的所有中断向量均可在"MSP430xxxx.h"中找到,这里使用PORT1_VECTOR和PORT2_VECTOR
- 当进入中断时,P8.x的输出电平被反转,实现LED的闪动
- 中断函数的一般形式和注意事项
//module interrput vector
#pragma vector = xxxx_VECTOR
__interrupt void my_function(void)
{
//Some operations
//end
}
- 进入中断函数后默认关闭总中断,此时可以使用
__enable_interrupt()
函数再次开启总中断以便进行中断嵌套 - 中断函数前必须有
__interrupt
标识,否则会被当成普通函数处理 - MSP430的中断优先级和中断向量的大小有关
- 其他模块的中断函数的设置类似于GPIO中断
- 这里用的中断向量在"msp430f5529.h"头文件中均有定义
- 实验代码
#include "driverlib.h"
int main(void)
{
//Enable all of interrupts
__enable_interrupt();
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
//Enable the GPIO interrupt
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN7);
GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN2);
//Set GPIO which keys use as out & high level
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN7);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
//Set GPIO which LEDs use as out & high level
GPIO_setAsOutputPin(GPIO_PORT_P8, GPIO_PIN1 + GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P8, GPIO_PIN1 + GPIO_PIN2);
//Select interrupt trigger as high level to low level
GPIO_selectInterruptEdge(GPIO_PORT_P1, GPIO_PIN7, GPIO_HIGH_TO_LOW_TRANSITION);
GPIO_selectInterruptEdge(GPIO_PORT_P2, GPIO_PIN2, GPIO_HIGH_TO_LOW_TRANSITION);
//Clear the flag of GPIO interrupt
GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN7);
GPIO_clearInterrupt(GPIO_PORT_P2, GPIO_PIN2);
}
/*******************************************************************************************
* @brief interrupt(P1.7) for toggle LED(P8.1)
* @vector PORT1_VECTOR
* @func PORT1()
* @param None
* @return None
*******************************************************************************************/
#pragma vector = PORT1_VECTOR
__interrupt void PROT1(void)
{
GPIO_toggleOutputOnPin(GPIO_PORT_P8, GPIO_PIN1);
GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN7);
}
/*******************************************************************************************
* @brief interrupt(P2.2) for toggle LED(P8.2)
* @vector PORT2_VECTOR
* @func PORT2()
* @param None
* @return None
*******************************************************************************************/
#pragma vector = PORT2_VECTOR
__interrupt void PORT2(void)
{
GPIO_toggleOutputOnPin(GPIO_PORT_P8, GPIO_PIN2);
GPIO_clearInterrupt(GPIO_PORT_P2, GPIO_PIN2);
}