IMX6ULL 的 LED 操作方法

IMX6ULL 的 LED 操作方法 ------ 从零开始,点亮你的第一颗灯

无论你是学习裸机开发,还是将来写 Linux 驱动,点亮 LED 都是嵌入式世界的 "Hello World"。

这节课,我们就以 IMX6ULL 芯片为例,手把手教你如何通过操作寄存器,让板子上的 LED 亮起来。


一、LED 为什么会亮?

先看一个最简单的电路图(示意图):

  • 当 GPIO 引脚输出 低电平 (0V) 时,电流从 VCC 流过 LED、再流入 GPIO 引脚,LED 亮。

  • 当 GPIO 引脚输出 高电平 (3.3V) 时,LED 两端电压相等,没有电流,LED 灭。

注意:不同的开发板可能接法不同,有的板子是 高电平点亮 ,有的则是 低电平点亮

我们以 100ASK_IMX6ULL 开发板为例,它的 LED 是 低电平点亮


二、GPIO 是什么?怎么操作它?

GPIO = General Purpose Input/Output,通用输入输出口。

你可以把它理解成芯片上的一个 "开关",通过程序控制它输出高电平或低电平。

操作任何一个 GPIO,都离不开三个步骤:

  1. 使能时钟 ------ 让 GPIO 模块先通上电(不供电无法工作)。

  2. 配置引脚功能 ------ 这个引脚可以是普通 GPIO,也可以是串口、I2C 等,我们要把它设为 GPIO 模式。

  3. 设置方向和数据 ------ 决定它是输入还是输出,再输出高电平或低电平。


三、找到我们要控制的 LED 引脚

打开开发板的原理图(PDF 或纸质),搜索 "LED" 关键字,会看到类似下面的信息:

![LED原理图位置](示意:在原理图中搜 "LED" 会看到 GPIO5_3)

在 100ASK_IMX6ULL 的原理图中,LED 连接到了 GPIO5_IO03

意思是:这个 LED 挂在 GPIO5 组第 3 个引脚 上。


四、一步步操作 IMX6ULL 的寄存器

下面所有的地址和数值,都可以在芯片手册《IMX6ULLRM.pdf》里找到。

4.1 使能 GPIO5 的时钟(其实这一步可以跳过)

在 IMX6ULL 中,GPIO5 的时钟默认就是使能的,但我们还是知道一下它在哪里:
CCM_CCGR1 寄存器,地址 0x020C406C,里面的 bit[31:30] 控制 GPIO5 的时钟。

不过对于我们的板子,不设置它也没问题 ------ 厂家已经在 boot 阶段帮我们开好了。

4.2 配置引脚功能 ------ 让 GPIO5_IO03 变成 GPIO 模式

一个物理引脚可能有多种功能(比如作为 UART 的 TX,或者作为 GPIO)。

我们必须明确告诉芯片:这个引脚,我要当 GPIO 用

对应的寄存器是 IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 ,地址 0x02290000 + 0x14 = 0x02290014

位域 含义
bit[3:0] 0b0101 (5) 选择 ALT5 模式,即 GPIO5_IO03

所以我们要往这个地址写入 0x5

小提示:在芯片手册里,这个引脚的名字是 SNVS_TAMPER3,它的 ALT5 模式就是 GPIO5_IO03。

4.3 设置方向 ------ 输出模式

现在引脚已经是 GPIO 了,但它默认是 输入 模式,我们要改为 输出

方向控制寄存器是 GPIO5_GDIR ,地址 0x020AC004

每一个 bit 对应一个引脚:

  • bit = 0 → 输入

  • bit = 1 → 输出

我们要控制 GPIO5 的第 3 个引脚,所以需要把 bit3 设置为 1。

cs 复制代码
c

*((volatile unsigned int *)0x020AC004) |= (1 << 3);

4.4 输出电平 ------ 点亮或熄灭 LED

数据寄存器是 GPIO5_DR ,地址 0x020AC000

同样,bit3 控制第 3 个引脚的电平:

  • 写入 0 → 输出低电平 → LED 亮

  • 写入 1 → 输出高电平 → LED 灭

cs 复制代码
c

// 点亮 LED
*((volatile unsigned int *)0x020AC000) &= ~(1 << 3);

// 熄灭 LED
*((volatile unsigned int *)0x020AC000) |= (1 << 3);

五、把上面的步骤写成代码(伪代码框架)

cs 复制代码
c

// 定义寄存器地址
#define CCM_CCGR1      (*(volatile unsigned int *)0x020C406C)
#define IOMUX_SNVS_T3  (*(volatile unsigned int *)0x02290014)
#define GPIO5_GDIR     (*(volatile unsigned int *)0x020AC004)
#define GPIO5_DR       (*(volatile unsigned int *)0x020AC000)

void led_init(void)
{
    // 1. 使能 GPIO5 时钟(其实可以省略,但写上也没错)
    // CCM_CCGR1 |= (3 << 30);   // 如果前面没开,就加上这行

    // 2. 设置引脚为 GPIO 模式 (ALT5)
    IOMUX_SNVS_T3 = 5;

    // 3. 设置为输出方向
    GPIO5_GDIR |= (1 << 3);
}

void led_on(void)
{
    GPIO5_DR &= ~(1 << 3);   // 输出低电平
}

void led_off(void)
{
    GPIO5_DR |= (1 << 3);    // 输出高电平
}

实际开发中,我们会把这些地址定义放在一个 regs.h 头文件里,代码会更整洁。


六、上机实验(裸机方式)

  1. 编写完整的 led.cmain.c,在 main 里调用 led_init(),然后循环亮灭。

  2. 使用交叉编译器 arm-linux-gnueabihf-gcc 编译。

  3. mkimage 工具制作 .imx 映像文件。

  4. 通过 USB 或 SD 卡烧写到开发板。

  5. 上电,你会看到 LED 按照你的程序闪烁。

如果不想烧写,也可以直接在 Linux 下写一个简单的 GPIO 驱动(后续会讲到)。


七、总结与延伸

今天我们学到的内容,其实已经涵盖了 嵌入式 Linux 驱动开发 的最底层知识:

  • 看原理图 → 确定引脚

  • 看芯片手册 → 找到对应的寄存器

  • 写程序 → 操作寄存器

以后你写的任何驱动程序(LED、按键、UART、I2C...)都离不开这三步。

在 Linux 下,我们会用 ioremap 映射物理地址,用 device tree 描述引脚资源,但最终落到底层,依然是操作这些寄存器

下一节课,我们将把这个裸机 LED 程序,改造成一个标准的 Linux 字符设备驱动。

到时候你会发现 ------ 框架变了,但点亮 LED 的本质从未改变

相关推荐
三佛科技-134163842122 小时前
家用电子血压计方案开发MCU控制芯片
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
仰泳之鹅2 小时前
【stm32进阶】定时器+ADC+DMA+乒乓缓冲区
stm32·单片机·嵌入式硬件
进击的小头2 小时前
第4篇:嵌入式处理器内核全解析:ARM Cortex-M_R_A系列核心差异与选型指南
arm开发·单片机·嵌入式硬件
Heartache boy13 小时前
野火STM32_HAL库版课程笔记-手动建立工程模板与CubeMX后续用法(重要)
笔记·stm32·单片机·嵌入式硬件
可乐鸡翅好好吃17 小时前
UUID----私有服务与公有服务
嵌入式硬件
Wave84517 小时前
Freertos中PendSV与sysTick
单片机·嵌入式硬件
jghhh0117 小时前
带红外抄板和LCD显示的单相电能表设计
stm32·单片机·嵌入式硬件
wggmrlee18 小时前
GD32 vs STM32
单片机·嵌入式硬件
czhaii18 小时前
STM32 F103 Altium一键下载PCB图
stm32·单片机·嵌入式硬件