3. 外部中断控制LED
任务说明
本案例基于中微CMS32系列车规MCU,实现外部中断控制LED翻转。使用板载按键(连接至外部中断引脚)作为触发源,每次按下按键触发一次外部中断,在中断服务函数中翻转LED的亮灭状态。通过本案例掌握CMS32的GPIO外部中断配置流程、中断服务函数编写方法以及中断标志的清除操作。
硬件连接
- LED:连接至PB5引脚(输出模式,高电平点亮)
- 按键:连接至PA2引脚(外部中断输入,下降沿触发)
代码实现
#include "CMS32L051.h"
/* 中断服务函数声明 */
void EXTI2_IRQHandler(void);
/* LED引脚定义 */
#define LED_PORT GPIOB
#define LED_PIN GPIO_PIN_5
/* 按键中断引脚定义 */
#define KEY_EXTI_PORT GPIOA
#define KEY_EXTI_PIN GPIO_PIN_2
#define KEY_EXTI_LINE EXTI_LINE_2
/* 简单延时函数 */
void delay_ms(uint32_t ms)
{
uint32_t i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 8000; j++);
}
/* GPIO初始化 */
void GPIO_Init(void)
{
/* 使能GPIOA和GPIOB时钟 */
CGC->PERCLKEN |= CGC_PERCLKEN_GPIOA_MASK | CGC_PERCLKEN_GPIOB_MASK;
/* 配置PB5为推挽输出,用于驱动LED */
GPIOB->CFG &= ~(0xF << (5 * 4)); /* 清除PB5配置 */
GPIOB->CFG |= (0x3 << (5 * 4)); /* 设置为推挽输出 */
/* 配置PA2为输入模式,用于外部中断 */
GPIOA->CFG &= ~(0xF << (2 * 4)); /* 清除PA2配置 */
GPIOA->CFG |= (0x0 << (2 * 4)); /* 设置为浮空输入 */
/* 初始LED为熄灭状态 */
GPIOB->ODR |= (1 << 5); /* 输出高电平,LED灭 */
}
/* 外部中断初始化 */
void EXTI_Init(void)
{
/* 使能SYSCFG时钟(用于外部中断配置) */
CGC->PERCLKEN |= CGC_PERCLKEN_SYSCFG_MASK;
/* 选择PA2作为EXTI2的输入源 */
SYSCFG->EXTICR[0] &= ~(0xF << (2 * 4));
SYSCFG->EXTICR[0] |= (0x0 << (2 * 4)); /* 选择GPIOA */
/* 配置下降沿触发 */
EXTI->FTSR |= (1 << 2); /* 使能下降沿触发 */
EXTI->RTSR &= ~(1 << 2); /* 禁用上升沿触发 */
/* 清除中断标志 */
EXTI->PR |= (1 << 2);
/* 使能EXTI2中断 */
EXTI->IMR |= (1 << 2);
/* 配置NVIC优先级并使能中断 */
NVIC_SetPriority(EXTI2_IRQn, 2);
NVIC_EnableIRQ(EXTI2_IRQn);
}
/* 外部中断2服务函数 */
void EXTI2_IRQHandler(void)
{
/* 检查EXTI2中断标志 */
if (EXTI->PR & (1 << 2))
{
/* 翻转LED状态 */
GPIOB->ODR ^= (1 << 5);
/* 清除中断标志 */
EXTI->PR |= (1 << 2);
}
}
/* 主函数 */
int main(void)
{
/* 系统时钟初始化(默认使用内部RC) */
SystemInit();
/* 初始化GPIO */
GPIO_Init();
/* 初始化外部中断 */
EXTI_Init();
while (1)
{
/* 主循环空操作,等待中断触发 */
__NOP();
}
}
代码说明
代码首先完成GPIO初始化:PB5配置为推挽输出驱动LED,PA2配置为浮空输入作为外部中断引脚。外部中断初始化部分选择PA2作为EXTI2的输入源,配置为下降沿触发(按键按下时产生下降沿),并使能中断线和NVIC中断通道。中断服务函数中检测EXTI2标志位后翻转LED输出状态,最后清除中断标志以准备下一次触发。主循环为空操作,系统在中断驱动下工作。
编译与烧录
/* 使用Keil MDK或IAR打开工程,编译生成hex文件 */
/* 通过CMS32-Link调试器烧录至目标板 */
验证方法
将程序烧录至开发板后,观察LED初始状态为熄灭。每次按下按键,LED状态应翻转一次(亮→灭或灭→亮)。连续快速按键时,每次按键都应产生一次中断并翻转LED。若LED状态未变化,可通过调试器在中断服务函数中设置断点,检查是否进入中断以及中断标志是否被正确清除。
判定标准
- LED初始为熄灭状态
- 每次按下按键,LED状态翻转一次
- 中断服务函数中标志位检测与清除逻辑正确
- 松开按键(上升沿)不触发中断