一、概念概要
1、LED原理图
2、内核中对应的引脚 — GPIO
(1)概念
GPIO(通用输入/输出)详解
GPlO(General-PurposeInput/Output)是嵌入式系统和微控制器中最基本的外设接口,用于
实现数字信号的输入和输出控制。它通过软件配置引脚功能,灵活连接外部设备,如传感器、LE
D、按键等。
以默认功能命名规则 ->复用功能,使用前要明白引脚最初默认引脚
(2)GPIO 3控制器的起始地址
3、 IOMUX6ULL 引脚功能复用原理
类似于单刀多掷开关,(内部控制寄存器)实现多路复用开关,单刀多掷开关一般在多路复用时,默认一次仅连接一个功能通道,其他通道处于断开状态

控制led灯一般在推挽模式,对于复杂SOC,对于一个引脚,需要进行交叉复用功能设置,对于一个引脚。可能有多种功能,同一时刻只能使用一种,需要提前配置。
4、引脚电器配置
5、GPIO 参考手册
使用时:GPIOx : x是几,使用时就将几号bit位置1
例如:GPIO3 -> orr r1, r1, #(1 << 3)
- 数据相关:
- GPIOx_DR:数据寄存器,直接读写引脚电平状态
- 当引脚作为输出时,向对应的位写1使引脚为高电平,写0引脚为低电平
- 当引脚作为输入时,读取到1表示引脚为高电平,读取到0表示引脚低电平
- GPIOx_PSR:引脚状态寄存器,实时读取物理引脚电平(可能与DR存在差异)
- GPIOx_DR:数据寄存器,直接读写引脚电平状态
- 方向控制:
- GPIOx_GDIR:方向寄存器,设置引脚为输入/输出模式(1=输出,0=输入)
- 中断控制:
- GPIOx_IMR:中断屏蔽,决定哪些引脚中断有效
- GPIOx_ISR:中断状态,标志哪些引脚触发了中断
- GPIOx_ICR1/ICR2:中断清除,写1清除对应位的中断标志
- GPIOx_EDGE_SEL:边沿选择,配置中断触发条件(上升/下降/双边沿)
6、IO复用功能 目标寄存器的地址
7、引脚电器配置
8、引脚方向
9、延时设置
led_delay:
ldr r0, = 0x7FFFF
loop:
sub r0, r0, #1
cmp r0, #0
bgt loop
bx lr
二、基本流程
1、代码书写
.global _start
_start:
//异常向量表
ldr pc, = _start_handler
ldr pc, = _undefined_handler
ldr pc, = _supervisor_handler
ldr pc, = _prefetch_handler
ldr pc, = _data_handler
ldr pc, = _notused_handler
ldr pc, = _irq_handler
ldr pc, = _fiq_handler_undefined_handler:
b _undefined_handler_supervisor_handler:
b _supervisor_handler_prefetch_handler:
b _prefetch_handler_data_handler:
b _data_handler_notused_handler:
b _notused_handler_irq_handler:
b _irq_handler
_fiq_handler:
b _fiq_handler_start_handler:
//古老的方法
/*
//进入irq
mrs r0, cpsr
bic r0, r0, #(0x1F << 0)
bic r0, r0, #(1 << 7)
orr r0, r0, #(0x12 << 0) //irq
msr cpsr, r0
ldr sp, = 0x82000000//进入irq
mrs r0, cpsr
orr r0, r0, #(0x1F << 0) //sys
msr cpsr, r0
ldr sp, = 0x84000000
*///新方法
cpsid i //关闭软中断,保证模式转换过程中不被打断cps #0x12
ldr sp, = 0x82000000cps #0x1F
ldr sp, = 0x84000000cpsie i //开启软中断
//调用部分
bl led_init
b finishfinish:
bl led_on
bl led_delaybl led_off
bl led_delayb finish
//led初始化
led_init:
//IO复用功能配置
ldr r0, = 0x020E0068
ldr r1, = 0x05
str r1, [r0] //将r1的内容写入r0地址//引脚电器配置
ldr r0, = 0x020E02F4
ldr r1, = 0x10B0
str r1, [r0]//引脚方向
ldr r0, = 0x0209C004 //写
ldr r1, [r0] //读
orr r1, r1, #(1 << 3)
str r1, [r0]bx lr
led_on:
ldr r0, = 0x0209C000
ldr r1, [r0]
bic r1, r1, #(1 << 3)
str r1, [r0]
bx lrled_off:
ldr r0, = 0x0209C000
ldr r1, [r0]
orr r1, r1, #(1 << 3)
str r1, [r0]
bx lr//延时设置
led_delay:
ldr r0, = 0x7FFFF
loop:
sub r0, r0, #1
cmp r0, #0
bgt loop
bx lr
2、编译
(1)汇编(.S → .o)
将汇编代码转为目标文件
arm-linux-gnueabihf-gcc -c start.S -o start.o -g //-c 只汇编不链接,-g 保留调试信息
(2)链接(.o → .elf)
将目标文件链接到指定地址(i.MX6ULL 从 SD 卡启动时,代码加载地址为 0x87800000)
arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf //-Ttext 指定代码段起始地址
(3)格式转换(.elf → .bin)
ELF 文件包含调试信息,需转为纯二进制文件(开发板才能识别)
arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin
//-O binary 指定输出格式,-S/-g 去除符号/调试信息
(4)反汇编(.elf → .dis)
将 ELF 文件转为汇编代码(可选)
arm-linux-gnueabihf-objdump -D start.elf > start.dis // -D 反汇编所有段
3、烧录
(1)连接SD卡到Ubuntu
(2)拷贝下载工具imxdownload到Ubuntu工程目录下
(3)修改权限:改为可执行文件
chmod +777 imxdownload
(4)烧写程序到SD卡
./imxdownload start.bin /dev/sdb
注:注意烧写速率,如果上M的速度是不成功的,必须拔掉USB读卡器,重启Ubuntu
如下:
makefile
COPLITE=arm-linux-gnueabihf-
CC=$(COPLITE)gcc
LD=$(COPLITE)ld
OBJCOPY=$(COPLITE)objcopy
OBJDUMP=$(COPLITE)objdump
TAGRET=start$(TAGRET).bin:$(TAGRET).S
$(CC) -c -g $(TAGRET).S -o $(TAGRET).o
$(LD) -Ttext 0x87800000 $(TAGRET).o -o $(TAGRET).elf
$(OBJCOPY) -O binary -S -g $(TAGRET).elf $(TAGRET).bin
$(OBJDUMP) -D $(TAGRET).elf > $(TAGRET).disclean:
rm $(TAGRET).o $(TAGRET).elf $(TAGRET).bin $(TAGRET).dis -f
load:
./imxdownload $(TAGRET).bin /dev/sdb
4、测试
(1)将BOOT按照MicroSD进行操作
将sd卡插入IMAXULL板子上,开启电源
