硬件开发(6)—IMX6ULL裸机—led灯

1.LED 模块硬件设计

  • 用户可控 LED:红色 LED,阳极通过 510Ω 限流电阻连接到 GPIO1_IO03 引脚,阴极接地(GND);
  • 电源指示灯:蓝色 LED,直接接电源,上电即亮(无需软件控制,仅用于判断供电)
  • 控制逻辑:GPIO_IO03输出低电平时,LED 两端形成电压差(VCC → 电阻 → LED → GND),电流流过点亮;输出高电平时,两端无压差,LED 熄灭。

2.LED模块软件设计

1.内核初始化:启动代码框架与关键指令
1.异常向量表

.global _start ; 声明入口符号,链接器需识别

_start: ; 异常向量表(地址 0x00000000 开始,对应复位后 PC 初始值)

        ldr pc, =_start_handler //复位异常(唯一会执行的异常入口)

        ldr pc, =_undef_handler //未定义指令异常

        ldr pc, =_svc_handler //SVC 异常(软中断)

        ldr pc, =_prefetch_handler //预取指异常

        ldr pc, =_data_handler//数据异常

        ldr pc, =_reserved_handler //预留异常

        ldr pc, =_irq_handler //IRQ 中断(外设常用)

        ldr pc, =_fiq_handler//FIQ 中断 ; 复位异常处理函数 

        

_undefined_hander:

    b _undefined_hander

_supervisor_hander:

    b _supervisor_hander

   

_prefetch_hander:

    b _prefetch_hander

   

_data_hander:

    b _data_hander

_not_use_hander:

    b _not_use_hander

_irq_hander:

    b _irq_hander  

_fiq_hander:

    b _fiq_hander

2.系统初始化:复位异常处理函数

重点指令:cps

CPS<effect> <iflags>{, #<mode>}

CPS #<mode>

<effect>:

参数值含义说明
ieInterrupt Enable(使能)允许指定类型的中断触发(仅对 IRQ/FIQ 生效)
idInterrupt Disable(禁止)禁止指定类型的中断触发

<iflags>:

参数值对应中断类型说明
iIRQ 中断普通外设中断(如 GPIO 中断、UART 中断、定时器中断),优先级较低
fFIQ 中断快速中断(如高速 ADC、紧急硬件故障),优先级较高,响应速度更快
aAll(所有)同时控制 IRQ 和 FIQ 中断(禁止 a 即禁止所有可屏蔽中断)

<mode>:目标 CPU 工作模式(M 域编码)7种工作模式

_start_hander:   //上电触发

        

    cpsid i         //关闭普通中断,在模式转换过程中不被打扰

    cps #0x12  //irq

    ldr sp, =0x82000000  //分配irq栈地址

    

    cps #0x1F   //sys

    ldr sp, =0x84000000    //分配sys栈地址

    cpsie i        //打开普通中断

2.外设操作核心:GPIO 寄存器配置
1.确定需要配置值
寄存器名称基地址偏移地址完整地址核心功能
PAD_GPIO1_IO030x020E00000x00680x020E0068配置引脚复用功能(切换为 GPIO)
PAD_GPIO1_IO030x020E00000x02F40x020E02F4配置引脚电气特性
GPIO1_GDIR(方向寄存器)0x0209C0000x00040x0209C0004配置 GPIO 为输入 / 输出
GPIO1_DR(数据寄存器)0x0209C0000x00000x0209C0000控制 GPIO 输出
2.LED 初始化函数

led_init: 

        //配置复用功能

        GPIO ldr r0, =0x020E0068 /加载复用控制寄存器地址

        ldr r1, =0x05 //配置值

        str r1, [r0] //将配置值写入寄存器

        //配置引脚电气特性为默认值

        ldr r0, =0x020E02F4 // 加载电气特性寄存器地址

        ldr r1, =0x10B0 //配置值

        str r1, [r0]  //将配置值写入寄存器

        //配置 GPIO 方向:设为输出模式

        ldr r0, =0x0209C004//加载 GPIO1 方向寄存器地址

        ldr r1, [r0] //先读取当前配置(避免覆盖其他引脚设置)

        orr r1, r1, #(1 << 3)// 将 bit3 置 1(GPIO1_IO03 对应 bit3,1=输出)

        str r1, [r0] // 写入生效

        bx lr 

3.LED控制函数

//点亮 LED:GPIO1_IO03 输出低电平

led_on:

        ldr r0, =0x0209C000 ; 加载 GPIO1 数据寄存器地址

        ldr r1, [r0] ; 读取当前电平(避免覆盖其他引脚)

        bic r1, r1, #(1 << 3); 将 bit3 清 0(低电平,点亮 LED)

        str r1, [r0] ; 写入生效

        bx lr ;

//熄灭 LED:GPIO1_IO03 输出高电平

led_off:

        ldr r0, =0x0209C000 ; 加载 GPIO1 数据寄存器地址

        ldr r1, [r0] ; 读取当前电平

        orr r1, r1, #(1 << 3); 将 bit3 置 1(高电平,熄灭 LED)

        str r1, [r0] ; 写入生效

        bx lr ;

// 延时函数

led_delay:

        ldr r0, =0x7FFFFF ; 延时计数(528MHz 主频下,约 500ms)

loop: sub r0, r0, #1 ; 计数器减 1

        cmp r0, #0 ; 比较是否为 0

        bgt loop_delay ; 大于 0 则继续循环

        bx lr ; 主循环:实现 LED 闪烁

主函数:

        bl led_init  //初始化

        b finish

finish: //进行led亮暗变化

    bl led_on

    bl led_delay

    bl led_off

    bl led_delay

    b finish

3.编译、烧录与测试

1.编译
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 反汇编所有段

2.烧录

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).dis

clean:

    rm $(TAGRET).o $(TAGRET).elf $(TAGRET).bin $(TAGRET).dis -f

load:

    ./imxdownload $(TAGRET).bin /dev/sdb

3.测试

1.启动方式选择SD卡,如图

2.插入SD卡

3.开发板上电

4.观察红色LED灯

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值