news 2026/4/16 12:03:22

学习笔记——GPIO按键与中断系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学习笔记——GPIO按键与中断系统

嵌入式开发笔记:GPIO按键与中断系统

一、课前回顾要点

(1) volatile关键字的作用

作用:防止编译器优化,确保每次访问变量时都从内存中读取

  • 对编译器:禁止对该变量进行优化

  • 对程序:确保变量值的实时性

  • 应用场景:

    • 多线程共享变量

    • 硬件寄存器访问

    • 中断服务程序中的变量

(2) 链接脚本的作用

作用:控制程序在内存中的布局和组织

  • 指定各段(section)的存储位置

  • 定义程序的入口点

  • 管理内存分配(RAM/ROM)

  • 控制符号的地址和顺序

二、按键驱动实验(轮询方式)

1. 硬件介绍

2. 按键代码编写(轮询方式)

(1) 查阅手册

参考文档

  • IMX6ULL_MINI_V2.2(Mini底板原理图).pdf

  • IMX6ULL参考手册.pdf

(2) 初始化步骤
/* 步骤1:复用功能配置 */ // 引脚:UART1_CTS_B (GPIO1_IO18) // 寄存器:IOMUXC_SW_MUX_CTL_PAD_UART1_CTS_B // 配置:ALT5模式 → GPIO1_IO18 IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0); /* 位域说明: [0] SION: 0 (DISABLED) - 输入路径由功能决定 [3:0] MUX_MODE: 0101 (ALT5) - GPIO1_IO18 */ /* 步骤2:电气特性配置 */ // 寄存器:IOMUXC_SW_PAD_CTL_PAD_UART1_CTS_B IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF080); /* 位域详解(16位): [16] HYS: 0 - 禁用迟滞 [15:14] PUS: 11 - 22K上拉电阻 [13] PUE: 1 - 选择上拉/下拉 [12] PKE: 1 - 使能上拉/下拉 [11] ODE: 0 - 禁用开漏 [7:6] SPEED: 10 - 中速(100MHz) [5:3] DSE: 000 - 输出驱动禁用(输入模式) [0] SRE: 0 - 慢转换速率 */ /* 步骤3:GPIO方向设置 */ // 寄存器:GPIO1_GDIR GPIO1->GDIR &= ~(1 << 18); // 设置为输入模式 /* GDIR位说明: 0 - INPUT (输入模式) 1 - OUTPUT (输出模式) */ /* 步骤4:使能GPIO时钟 */ // 寄存器:CCM_CCGR1 // GPIO1组所有引脚共用该时钟门控 CCM->CCGR1 |= (3 << 26); // 使能GPIO1时钟
(3) 运行时开关检测
/* 读取按键状态 */ // 寄存器:GPIO1_DR int key_value = (GPIO1->DR >> 18) & 0x1; /* 状态说明: 1 - 开关断开(高电平) 0 - 开关按下(低电平) */

3. 轮询方式的问题

void main_task(void) { while(1) { // 复杂业务处理(耗时) process_complex_task(); // 可能执行很长时间 // 按键检测(可能被漏掉) check_key_status(); // 轮询间隔可能很长 } } // 模拟复杂业务 void delay(unsigned int count) { while(count--); // 简单延时模拟 }

问题分析

  1. 响应延迟:主循环中的复杂任务会延迟按键检测

  2. 漏检风险:快速按键可能被完全错过

  3. 实时性差:不适用于紧急响应场景(如汽车刹车)

三、中断方式解决方案

1. 中断基本概念

中断:CPU能打断当前工作,处理紧急任务,处理完后返回原处继续工作

2. 中断处理流程

┌─────────────────────────────────┐ │ 中断处理流程 │ ├─────────────────────────────────┤ │ 1. 中断源发出中断请求 │ │ 2. CPU检查是否响应中断 │ │ 3. 检查中断优先级 │ │ 4. 保护现场(保存寄存器) │ │ 5. 执行中断服务函数(ISR) │ │ 6. 恢复现场(恢复寄存器) │ │ 7. 返回原程序继续执行 │ └─────────────────────────────────┘

3. 中断控制器GIC详解

(1) GIC架构概览

参考文档ARM Generic Interrupt Controller V2.0.pdf

GICv2架构(单核IMX6ULL): ┌─────────────────────────────────┐ │ GIC Distributor │ │ ┌─────────────────────────┐ │ │ │ 中断源管理 (0-1019) │ │ │ │ • SGI (0-15): 软件中断 │ │ │ │ • PPI (16-31): 私有中断 │ │ │ │ • SPI (32-1019):共享中断 │ │ │ └─────────────────────────┘ │ │ │ │ └──────────────┼──────────────────┘ ▼ ┌─────────────────────────────────┐ │ CPU Interface (Processor0) │ │ ┌─────────────────────────┐ │ │ │ • 中断优先级屏蔽 │ │ │ │ • 中断确认 │ │ │ │ • 中断完成通知 │ │ │ └─────────────────────────┘ │ └─────────────────────────────────┘
(2) 中断类型说明
  • SGI (0-15):软件生成中断,用于核间通信

  • PPI (16-31):私有外设中断,每个核独有

  • SPI (32-1019):共享外设中断,所有核可见

(3) IMX6ULL中断映射

参考IMX6ULL参考手册.pdf- Table 3-1

  • 总中断号:0-128

  • GPIO中断属于SPI类型

4. 协处理器CP15

(1) 功能概述

位置:Cortex-A7技术参考手册第4章
作用:系统控制与配置

  • 系统控制与配置

  • MMU配置与管理

  • Cache配置与管理

  • 虚拟化与安全

  • 系统性能监控

(2) 关键寄存器组
/* c1寄存器:SCTLR (System Control Register) */ mrc p15, 0, r0, c1, c0, 0 // 读取SCTLR bic r0, r0, #(1 << 13) // 清除bit13 (V) orr r0, r0, #(1 << 12) // 设置bit12 (I Cache使能) mcr p15, 0, r0, c1, c0, 0 // 写回SCTLR /* SCTLR关键位: bit13 [V]: 异常向量表基地址 0 - 正常异常向量,基地址0x00000000 1 - 高异常向量,基地址0xFFFF0000 bit12 [I]: I Cache使能 0 - 禁用指令Cache 1 - 使能指令Cache */ /* c12寄存器:VBAR (Vector Base Address Register) */ __get_VBAR(0x87800000); // 设置异常向量表基地址 /* c15寄存器:CBAR (Configuration Base Address Register) */ mrc p15, 4, r0, c15, c0, 0 // 读取GIC寄存器物理基地址

5. 中断代码实现架构

(1) 模块化设计
/* 层次结构 */ ┌─────────────────┐ │ 应用层 │ ← 用户接口 ├─────────────────┤ │ 中断管理层 │ ← 中断注册/分发 ├─────────────────┤ │ GPIO驱动层 │ ← 硬件操作 ├─────────────────┤ │ 硬件寄存器 │ ← 直接硬件访问 └─────────────────┘
(2) GPIO模块封装
/* gpio.h */ typedef struct { int direction; // 方向:输入/输出 int pull; // 上拉/下拉 int speed; // 速度 int drive_strength; // 驱动能力 } gpio_config_t; /* 函数声明 */ void gpio_init(GPIO_Type *gpio, int pin, gpio_config_t *config); int gpio_read(GPIO_Type *gpio, int pin); void gpio_write(GPIO_Type *gpio, int pin, int value); void gpio_set_interrupt(GPIO_Type *gpio, int pin, int edge_type, void (*callback)(void));
(3) 中断模块设计(OCP原则)
/* interrupt.h */ typedef void (*irq_handler_t)(int irq, void *data); /* 中断控制器接口 */ void interrupt_init(void); int register_irq(int irq_num, irq_handler_t handler, void *data); void unregister_irq(int irq_num); void enable_irq(int irq_num); void disable_irq(int irq_num); /* 应用示例 */ void key_interrupt_handler(int irq, void *data) { // 处理按键中断 printf("Key pressed! IRQ: %d\n", irq); } int main() { // 初始化 interrupt_init(); // 注册中断处理函数(开放扩展) register_irq(GPIO1_IRQn, key_interrupt_handler, NULL); // 使能中断 enable_irq(GPIO1_IRQn); while(1) { // 主任务(不会被中断打断的业务逻辑) // 按键处理已在中断中完成 } }

6. 代码优化原则

(1) 满足用户基本需求
  • 可靠的按键检测

  • 实时响应

  • 易于使用

(2) 程序稳定可靠
  • 中断嵌套处理

  • 临界区保护

  • 错误处理机制

(3) OCP原则(开放封闭原则)
  • 对修改封闭:核心中断框架稳定,不轻易修改

  • 对扩展开放:可以轻松添加新的中断处理函数

四、总结对比

特性轮询方式中断方式
响应速度慢(依赖轮询间隔)快(立即响应)
CPU占用高(持续检查)低(事件驱动)
实时性优秀
代码复杂度简单较复杂
适用场景简单应用实时系统

五、实践建议

  1. 调试技巧

    • 使用LED指示灯辅助调试

    • 添加串口打印调试信息

    • 逐步验证每个配置步骤

  2. 常见问题

    • 中断未触发:检查GIC配置、GPIO中断使能

    • 中断频繁触发:检查消抖处理

    • 系统卡死:检查中断服务函数执行时间

  3. 性能优化

    • 中断服务函数尽量简短

    • 使用中断下半部处理耗时任务

    • 合理设置中断优先级

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 20:06:44

9 款 AI 写论文哪个好?实测见真章!虎贲等考 AI 凭硬核实力登顶 C 位

毕业季的论文写作战场&#xff0c;AI 工具已成 “标配武器”&#xff0c;但市面上五花八门的选择&#xff0c;到底谁才是真正的 “学术利器”&#xff1f;作为深耕论文写作科普的测评博主&#xff0c;我耗时两周&#xff0c;围绕文献真实性、功能全面性、数据可视化、学术合规性…

作者头像 李华
网站建设 2026/4/13 10:28:18

告别绘图内卷!虎贲等考 AI:一键生成期刊级科研图表的秘密武器

还在为 Origin 调参两小时只出一张图抓狂&#xff1f;还在因 PPT 示意图太丑被导师吐槽 “不像学术成果”&#xff1f;辛辛苦苦画的图表&#xff0c;却因格式不规范被期刊审稿人打回修改&#xff1f;作为深耕论文写作科普的博主&#xff0c;我实测多款绘图工具后发现&#xff0…

作者头像 李华
网站建设 2026/4/11 2:57:52

学术 PPT 告别熬夜!虎贲等考 AI PPT:10 分钟搞定答辩级演示文稿

还在为学术汇报 PPT 熬秃脑袋&#xff1f;辛辛苦苦写完几万字论文&#xff0c;提炼核心观点要耗掉半天&#xff0c;排版调整又费一天&#xff0c;最后做出来的 PPT 要么逻辑混乱、重点模糊&#xff0c;要么配色辣眼、格式不规范&#xff0c;答辩时被导师点名 “没抓住研究亮点”…

作者头像 李华
网站建设 2026/4/11 23:29:35

拒稿退修拜拜!虎贲等考 AI:期刊论文投稿的高效通关密钥

投出去的期刊论文石沉大海&#xff1f;精心撰写的稿件被反复打回修改&#xff1f;不少科研人都在经历 “写稿三月&#xff0c;拒稿三分钟” 的尴尬。明明研究成果有价值&#xff0c;却因选题不符期刊定位、文献引用不规范、格式细节不达标错失发表机会。作为深耕学术写作科普的…

作者头像 李华
网站建设 2026/3/31 0:07:24

手把手教 - opencpu 开发环境搭建

一、python 安装 1.1 下载 1.2 安装 1.3 验证安装是否成功 1.4 手动配置环境变量(若安装时未勾选PATH) 1.5 注意事项 二、 pip 工具升级到最新版本 2.1 命令分析 2.2 举例 2.3 注意 三、安装 scons 工具 3.1 基础安装命令 3.2 验证 3.3 常见问题解决办法 3.3.1 权限不足报错(…

作者头像 李华