主题 | 内容 | 教学目的/扩展视频 |
---|---|---|
4x4阵列键盘 | 电路连接,电路原理,驱动程序,调用函数。 | 能用程序读出按键值。 |
师从洋桃电子,杜洋老师
📑文章目录
▲ 回顾上期🔍矩阵键盘原理与单片机驱动设计详解(上) | 零基础入门STM32第七十七步
▲ 回顾上期🔍矩阵键盘原理与单片机驱动设计详解—端口反转法(下) | 零基础入门STM32第七十八步
一、中断机制的核心概念
1.1 中断的定义与作用
中断是嵌入式系统中的“紧急呼叫”机制。当CPU执行主程序时,若检测到特定事件(如按键按下、传感器信号变化),会暂停当前任务,优先处理该事件,完成后恢复原任务。其核心价值体现在:
- 实时响应:毫秒级响应外部事件
- 高效资源利用:避免轮询消耗CPU资源
- 多任务协调:通过优先级管理实现任务调度
1.2 中断处理全流程
二、STM32外部中断关键技术解析
2.1 外部IO中断特性
特性 | 说明 |
---|---|
全GPIO支持 | STM32F1系列所有GPIO均可配置中断输入 |
灵活触发方式 | 支持上升沿、下降沿、双沿触发 |
硬件级事件联动 | 可触发DMA传输等操作无需CPU干预 |
中断线复用 | 16条外部中断线(EXTI0-15)共享GPIO端口 |
2.2 中断触发方式详解
触发类型 | 触发条件 | 典型应用场景 | 配置代码示例 |
---|---|---|---|
上升沿触发 | 低→高电平跳变 | 按键释放检测 | EXTI_Trigger_Rising |
下降沿触发 | 高→低电平跳变 | 按键按下检测 | EXTI_Trigger_Falling |
双沿触发 | 任意电平跳变 | 旋转编码器检测 | EXTI_Trigger_Rising_Falling |
电平触发 | 持续指定电平 | 紧急停止信号 | EXTI_Trigger_High/Low |
2.3 中断与事件本质区别
维度 | 中断(Interrupt) | 事件(Event) |
---|---|---|
CPU参与度 | 必须执行ISR程序 | 纯硬件操作,无需CPU介入 |
响应目标 | 软件逻辑处理 | 直接触发外设操作(如DMA) |
延迟 | 微秒级(依赖代码效率) | 纳秒级(纯硬件响应) |
典型应用 | 数据接收处理 | ADC触发、定时器同步 |
三、NVIC:中断系统的指挥官
3.1 NVIC架构原理
嵌套向量中断控制器(NVIC) 是ARM Cortex-M内核的中断管理核心,具有:
- 可编程优先级(抢占式/子优先级)
- 自动保存/恢复上下文
- 低延迟中断响应
3.2 优先级配置实战
// 设置优先级分组(4位优先级)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 配置EXTI0中断
NVIC_InitTypeDef NVIC_InitStruct = {
.NVIC_IRQChannel = EXTI0_IRQn,
.NVIC_IRQChannelPreemptionPriority = 0x01, // 抢占优先级
.NVIC_IRQChannelSubPriority = 0x02, // 子优先级
.NVIC_IRQChannelCmd = ENABLE
};
NVIC_Init(&NVIC_InitStruct);
四、外部中断开发全流程
4.1 GPIO中断配置四步法
时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO模式设置
GPIO_InitTypeDef GPIO_InitStruct = { .GPIO_Pin = GPIO_Pin_0, .GPIO_Mode = GPIO_Mode_IPU, // 上拉输入 .GPIO_Speed = GPIO_Speed_50MHz }; GPIO_Init(GPIOA, &GPIO_InitStruct);
EXTI线路映射
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI参数配置
EXTI_InitTypeDef EXTI_InitStruct = { .EXTI_Line = EXTI_Line0, .EXTI_Mode = EXTI_Mode_Interrupt, .EXTI_Trigger = EXTI_Trigger_Falling, .EXTI_LineCmd = ENABLE }; EXTI_Init(&EXTI_InitStruct);
4.2 中断服务函数模板
void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0) != RESET) {
// 处理逻辑(如翻转LED)
GPIO_WriteBit(GPIOB, GPIO_Pin_0,
(BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0)));
EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志
}
}
五、高级应用:矩阵键盘中断驱动
5.1 硬件连接方案
/* 4x4矩阵键盘配置 */
行线:PA0-PA3 -> 推挽输出
列线:PA4-PA7 -> 中断输入(下降沿触发)
按键映射表:
+-----+-----+-----+-----+
| PA4 | PA5 | PA6 | PA7 |
+-----+-----+-----+-----+
| PA0 | 1 | 2 | 3 | A |
| PA1 | 4 | 5 | 6 | B |
| PA2 | 7 | 8 | 9 | C |
| PA3 | * | 0 | # | D |
+-----+-----+-----+-----+
5.2 中断扫描优化
// 列线中断配置
void Keypad_Interrupt_Init() {
for(uint8_t i=0; i<4; i++) {
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4+i);
EXTI_InitStruct.EXTI_Line = EXTI_Line4+i;
EXTI_Init(&EXTI_InitStruct);
}
}
// 中断服务函数
void EXTI4_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line4)) {
uint8_t key = MatrixKey_Scan();
if(key) OLED_ShowNum(6, 8, key, 2);
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
六、调试与优化技巧
6.1 常见问题排查
现象 | 可能原因 | 解决方案 |
---|---|---|
中断不触发 | GPIO模式配置错误 | 检查GPIO输入/输出模式设置 |
多次重复触发 | 未清除中断标志 | 在ISR末尾添加清除标志代码 |
优先级冲突 | NVIC分组设置不当 | 重新配置优先级分组 |
6.2 性能优化策略
- 中断合并:多个GPIO共用同一中断线
- DMA联动:配置事件触发自动数据传输
- 低功耗模式:在__WFI()等待中断期间降低功耗
// 进入停机模式等待中断
void Enter_LowPower_Mode() {
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
}
七、相关资源
[1] 洋桃电子B站课程-STM32入门100步
[2] STM32官方文档手册
[3] STM32F103固件函数库用户手册(中文)
[4] 键盘中断测试程序
[5] 外部中断原理与驱动.pptx
💬 技术讨论(请在评论区留言~)
📌 下期预告:下一期将探讨键盘中断程序分析,欢迎持续关注!
点击查阅🔍往期【STM32专栏】文章
版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志:
- v1.0 初始版本(2025-03-23)