MX6ULL 的 GPIO 操作方法(保姆级教程)

张开发
2026/5/19 23:50:04 15 分钟阅读
MX6ULL 的 GPIO 操作方法(保姆级教程)
目录一、点亮 LED 的三步法二、看原理图LED 怎么连到芯片的2.1 LED 在原理图中的抽象2.2 两种最基本的驱动方式2.3 引脚驱动能力不足怎么办—— 三极管驱动三、GPIO 通用操作方法3.1 GPIO 模块的五大要素3.2 寄存器操作的两种方式方式A读-改-写Read-Modify-Write方式Bset-and-clear 协议硬件原子操作四、实战i.MX6ULL 的 GPIO 操作4.1 总体流程4.2 步骤详解 如何查手册步骤1使能 GPIO1 时钟步骤2将引脚复用为 GPIO 功能步骤3设置方向为输出步骤4输出高/低电平4.3 完整代码示例裸机风格五、怎么查手册我教你方法5.1 必备的两份文档5.2 查手册的典型路径5.3 小技巧六、为了更好的阅读体验建议你贴出这些图七、总结学习 C 语言时第一个程序是 “Hello World”。学习 ARM 裸机编程时第一个程序就是点亮 LED。这篇文章带你从看原理图开始一步步掌握 i.MX6ULL 的 GPIO 操作顺便学会怎么查芯片手册。一、点亮 LED 的三步法点亮一个 LED 只需要三步看原理图– 找到控制 LED 的引脚是哪个。看芯片手册– 确定如何设置这个引脚时钟、复用、方向、电平。写程序– 配置寄存器点亮或熄灭 LED。下面我们就按这三步展开。二、看原理图LED 怎么连到芯片的2.1 LED 在原理图中的抽象实际 LED 长得五花八门插脚、贴片原理图中统一抽象成下图的样子text3.3V │ ╭┴╮ │ │ 电阻限流一般 470Ω ~ 1kΩ ╰┬╯ │ ┌┴┐ │▼│ LED箭头指向GND表示正极接电源 └┬┘ │ GND重点LED 需要正向电压才能点亮阳极 阴极。必须串联电阻限制电流否则 LED 会烧坏。2.2 两种最基本的驱动方式方式连接方法芯片引脚动作方式1芯片引脚 → 电阻 → LED → GND引脚输出3.3V点亮输出0V熄灭方式2VCC(3.3V) → 电阻 → LED → 芯片引脚引脚输出0V点亮输出3.3V熄灭方式1也叫“高电平点亮”方式2是“低电平点亮”。很多开发板喜欢用低电平点亮因为芯片引脚的灌电流能力通常比拉电流强。2.3 引脚驱动能力不足怎么办—— 三极管驱动有些芯片引脚输出电流很小比如 5mA直接推 LED 可能很暗。这时可以加一颗三极管或MOSFET来驱动方式3NPN 三极管基极接芯片引脚集电极接 LED 负极。引脚输出 1.2V 左右高电平→ 三极管导通 → LED 亮。方式4PNP 三极管基极接芯片引脚发射极接电源。引脚输出 0V低电平→ 三极管导通 → LED 亮。 在你的学习板原理图上先看清 LED 是接到哪个 GPIO 引脚以及是高电平点亮还是低电平点亮。这是编程的第一步。三、GPIO 通用操作方法GPIO General Purpose Input/Output通用输入输出口。任何芯片的 GPIO 操作都逃不出下面几个步骤3.1 GPIO 模块的五大要素使能时钟/电源– 先打开 GPIO 模块的时钟否则寄存器无法读写。模式Mode– 引脚可能复用为 UART、I2C、SPI 等需要先设为 GPIO 模式。方向Direction– 设为输入还是输出。数值Data– 输出时写高/低电平输入时读电平状态。其他– 中断、防抖、唤醒等后续再学。3.2 寄存器操作的两种方式方式A读-改-写Read-Modify-Write适用于普通的数据寄存器写 1 置位写 0 清零不能只改某一位。c // 设置 bit n 为 1 val *reg; val | (1 n); *reg val; // 清除 bit n 为 0 val *reg; val ~(1 n); *reg val;方式Bset-and-clear 协议硬件原子操作部分芯片提供SET和CLR寄存器向 SET 写 1 就置位向 CLR 写 1 就清零互不影响。c // 设置 bit n *set_reg (1 n); // 清除 bit n *clr_reg (1 n);i.MX6ULL 的 GPIO 数据寄存器GPIOx_DR不支持set-and-clear只能用读-改-写。但它的IOMUXC部分有类似设计后面会见到。四、实战i.MX6ULL 的 GPIO 操作我们以最常见的i.MX6ULL芯片为例演示如何点亮一个 LED。假设 LED 接在GPIO1_IO00引脚且是高电平点亮方式1。4.1 总体流程text 1. 使能 GPIO1 时钟 → 操作 CCM_CCGR1 寄存器 2. 将引脚复用为 GPIO1_IO00 → 操作 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 3. 设置方向为输出 → 操作 GPIO1_GDIR 4. 输出高电平或低电平 → 操作 GPIO1_DR4.2 步骤详解 如何查手册步骤1使能 GPIO1 时钟为什么如果不打开时钟GPIO 模块无法工作寄存器读写无效可能引起总线错误。查手册打开 i.MX6ULL 参考手册找到Chapter 18 Clock Controller Module (CCM)。搜索GPIO1_CLK_ENABLE会看到如下信息时钟信号控制位所在寄存器gpio1_clk_enableCG13CCM_CCGR1gpio2_clk_enableCG15CCM_CCGR0gpio3_clk_enableCG13CCM_CCGR2gpio4_clk_enableCG6CCM_CCGR3gpio5_clk_enableCG15CCM_CCGR1注意每个 CG 位占2 bits编码含义00所有模式下关闭时钟01Run 模式开Wait/Stop 关11所有模式除 Stop开我们一般设为11让时钟一直开着。实际操作c #define CCM_CCGR1 (*(volatile unsigned int *)0x020C406C) // 地址见手册 // 使能 GPIO1 时钟设置 CG13 两位为 11 CCM_CCGR1 | (3 26); // CG13 从 bit26 开始占2位教你找地址手册中搜索 “CCM_CCGR1” 即可看到它的基址和偏移。i.MX6ULL 的 CCM 基址是0x020C4000CCGR1 偏移0x6C所以地址0x020C406C。步骤2将引脚复用为 GPIO 功能一个物理引脚可能有多个功能UART、I2C、GPIO…。我们需要选择GPIO功能。查手册找到Chapter 30 IOMUX Controller (IOMUXC)。搜索引脚名称比如GPIO1_IO00找到IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00寄存器。其中关键字段MUX_MODEMUX_MODE 值功能0101 (5)ALT5 – GPIO1_IO000000I2C2_SCL0001GPT1_CAPTURE1......要设置为 GPIO就写入5。实际操作c #define SW_MUX_GPIO1_IO00 (*(volatile unsigned int *)0x020E005C) // 将 MUX_MODE 设置为 5 (ALT5, GPIO 功能) SW_MUX_GPIO1_IO00 5;地址怎么来的IOMUXC 基址0x020E0000GPIO1_IO00的 SW_MUX 偏移0x005C→0x020E005C。另外这个寄存器里还有一个SION位Software Input On如果希望输入路径一直打开比如读引脚状态可以置1。输出操作一般不需要。步骤3设置方向为输出每个 GPIO 端口有一组GDIR寄存器每 bit 控制一个引脚的方向0 输入1 输出查手册Chapter 28 General Purpose I/O (GPIO)。找到GPIOx_GDIR寄存器描述bit n 对应 GPIO[n] 的方向。实际操作c #define GPIO1_GDIR (*(volatile unsigned int *)0x0209C004) // 设置 bit0 为 1表示 GPIO1_IO00 为输出 GPIO1_GDIR | (1 0);步骤4输出高/低电平输出电平通过数据寄存器GPIOx_DR控制。写 1 则引脚输出高电平3.3V写 0 输出低电平0V。⚠️特别注意当方向为输入时读取GPIOx_DR返回的不是你写入的值而是引脚实际电平等同于GPIOx_PSR状态寄存器。手册原文While the GPIO direction is set to input, a read access to GPIO_DR returns the GPIO_PSR data.实际操作c #define GPIO1_DR (*(volatile unsigned int *)0x0209C000) // 点亮 LED高电平点亮 GPIO1_DR | (1 0); // 熄灭 LED GPIO1_DR ~(1 0);4.3 完整代码示例裸机风格c // 定义寄存器地址 #define CCM_CCGR1 (*(volatile unsigned int *)0x020C406C) #define SW_MUX_GPIO1_0 (*(volatile unsigned int *)0x020E005C) #define GPIO1_GDIR (*(volatile unsigned int *)0x0209C004) #define GPIO1_DR (*(volatile unsigned int *)0x0209C000) void delay(volatile int t) { while(t--); } int main(void) { // 1. 使能 GPIO1 时钟 (CG13 11) CCM_CCGR1 | (3 26); // 2. 复用为 GPIO1_IO00 SW_MUX_GPIO1_0 5; // ALT5 // 3. 设置为输出 GPIO1_GDIR | (1 0); while (1) { // 点亮 GPIO1_DR | (1 0); delay(500000); // 熄灭 GPIO1_DR ~(1 0); delay(500000); } return 0; }五、怎么查手册我教你方法很多初学者觉得手册几百页很恐怖其实你只需要学会有目的地搜索。5.1 必备的两份文档i.MX6ULL 参考手册IMX6ULLRM.pdf – 详细寄存器描述。数据手册IMX6ULLCEC.pdf – 引脚定义、电气特性。5.2 查手册的典型路径任务搜索关键词去哪一章找某个引脚的复用配置GPIO1_IO00或SW_MUX_CTL_PAD_IOMUXC 章节打开 GPIO 时钟GPIO1_CLK_ENABLE或CCM_CCGR1CCM 章节GPIO 方向寄存器GPIOx_GDIRGPIO 章节GPIO 数据寄存器GPIOx_DRGPIO 章节引脚在哪个 GPIO 组查看原理图或数据手册的 Ball Map数据手册5.3 小技巧手册 PDF 的书签是最快导航。善用CtrlF但尽量搜准确的寄存器名或信号名。看到ALT5这样的复用值就在附近找表格里面列出了所有复用功能。七、总结步骤寄存器类别作用1CCM_CCGRx使能 GPIO 模块时钟2IOMUXC_SW_MUX把引脚切换为 GPIO 功能3GPIOx_GDIR设置方向输入/输出4GPIOx_DR输出高低电平 / 读取输入掌握了这套“时钟 → 复用 → 方向 → 数据”的套路任何 Cortex-A 芯片的 GPIO 你都能轻松驾驭。下一步你可以试试读取按键输入、控制蜂鸣器甚至用 GPIO 模拟 I2C 协议。动手是学会的唯一途径。现在就去打开你的开发板把第一个 LED 点起来吧

更多文章