I.MX6ULL裸机LED驱动实验过程

查看资料,编写驱动

首先查看底板资料找到led硬件资料,看到LED需要GPIO3

在这里插入图片描述

GPIO3对应着GPIO1_IO03.

查看芯片的参考手册可以看的GPIO03有两个寄存器分别为复用寄存器:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03和配置寄存器:IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03。

但在此之前需要使能GPIO1时钟。

何为使能时钟?

我们在进行STM32编程时,会发现这样一个事实:不管你要干嘛,你首先要做的一件事就是使能时钟。随着电子产品集成度越来越高,功耗和发热越来越严重,芯片厂商非常无奈也在开始想办法避免这个问题,而最直接的思路当然就是用多少功能就使能多少功能,对每个外设的时钟都设置了开关,让用户可以精确地控制,关闭不需要的设备,达到节省供电的目的。如果不用的就完全关闭,尽可能降低芯片功耗,所以就出现了这么多的时钟和IO配置。说白了,时钟的功能就好像是一个小开关,你要用什么寄存器就先对应的打开开关,即:使能对应的时钟。

在这里插入图片描述

在时钟寄存器里寻找gpio1找到GOIO1的时钟由CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即可。


在这里插入图片描述


找到了复用寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03”的地址为
0X020E0068,然后设置此寄存器,将 GPIO1_IO03 这个 IO 复用为 GPIO 功能,也就是 ALT5。

找到 GPIO1_IO03 的配置寄存器“IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03”的地址为
0X020E02F4,配置LED硬件信息。

本实验中 GPIO1_IO03 是作为输出功能的,因此 GPIO1_GDIR 的 bit3 要设置为 1,表示输出。


接着创建led.s文件编写驱动,代码如下:


.global _start @全局标号

_start:
    /*使能所有外设时钟 */
    ldr r0, =0x020c4068 @CCGR0
    ldr r1, =0xffffffff @要向CCGR0写入的数据
    str r1, [r0]        @将0xffffffff写入到CCGR0中

    ldr r0, =0x020c406c @CCGR1
    str r1, [r0]        

    ldr r0, =0x020c4070 @CCGR2
    str r1, [r0]  

    ldr r0, =0x020c4074 @CCGR3
    str r1, [r0]  

    ldr r0, =0x020c4078 @CCGR4
    str r1, [r0]  

    ldr r0, =0x020c407c @CCGR5
    str r1, [r0]  

    ldr r0, =0x020c4080 @CCGR6
    str r1, [r0]  

    /* 配置 GPIO1_IO03 PIN的复用为GPIO,也就是设置
     * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03=5
     * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器地址为0X020E0068
     */
    ldr r0, =0x020E0068 @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
    ldr r1, =0x5        @要写入的数据
    str r1, [r0]        @将5写入到IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03中

    /* 配置GPIO1_IO03的电气属性 也就是寄存器:
     * IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
     * IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03寄存器地址为0x020e02f4
     *
     * bit0:    0 低速率
     * bit5:3: 110 R0/6驱动能力
     * bit7:6: 10 100MHz速度
     * bit11:  0 关闭开路输出
     * bit12:  1 使能pull/kepper
     * bit13:  0 kepper
     * bit15:14:00 100K下拉
     * bit16: 0 关闭hys
     */
    ldr r0, =0x020e02f4
    ldr r1, =0x10b0
    str r1, [r0]

    /* 设置GPIO 
     * 设置GPIO1_GDIR寄存器,设置GPIO1_GPIO03为输出
     * GPIO1_GDIR寄存器地址为0x0209c004,设置GPIO1_GDIR寄存器bit3为1,
     * 也就是设置GPIO1_IO03为输出。
     */
     ldr r0, = 0x0209c004
     ldr r1, = 0x8
     str r1, [r0]

     /* 打开LED,也就是设置GPIO1_IO03为0 
      * GPIO1_DR寄存器地址为0x0209c000
      */
      ldr r0, =0x0209c000
      ldr r1, =0
      str r1, [r0]

loop:
    b loop 

第 2 行定义了一个全局标号_start,代码就是从_start 这个标号开始顺序往下执行的。

第 11 行使用 ldr 指令向寄存器 r0 写入 0X020C4068,也就是 r0=0X020C4068,这个是CCM_CCGR0 寄存器的地址。

第 12 行使用 ldr 指令向寄存器 r1 写入 0XFFFFFFFF,也就是 r1=0XFFFFFFFF。因为我们要开启所有的外设时钟,因此 CCM_CCGR0~CCM_CCGR6 所有寄存器的 32 位都要置 1,也就是写入 0XFFFFFFFF。

第 13 行使用 str 将 r1 中的值写入到 r0 所保存的地址中去,也就是给 0X020C4068 这个地址写入 0XFFFFFFFF,相当于 CCM_CCGR0=0XFFFFFFFF,就是打开 CCM_CCGR0 寄存器所控制的所有外设时钟。

第 15~31 行都是向 CCM_CCGRX(X=1~6)寄存器写入 0XFFFFFFFF。这样我就通过汇编代码使能了 I.MX6U 的所有外设时钟。

第35~37行是设置GPIO1_IO03的复用功能, GPIO1_IO03的复用寄存器地址为0X020E0068,寄 存 器 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 的 MUX_MODE 设 置 为 5 就 是 将GPIO1_IO03 设置为 GPIO。

第 49~51 行 是 设 置 GPIO1_IO03 的 配 置 寄 存 器 , 也 就 是 寄 存 器IOMUX_SW_PAD_CTL_PAD_GPIO1_IO03 的值,此寄存器地址为 0X020E02F4,代码里面已经
给出了这个寄存器详细的位设置。

第 54~63 行是设置 GPIO 功能,经过上面几步操作, GPIO1_IO03 这个 IO 已经被配置为了GPIO 功能,所以还需要设置跟 GPIO 有关的寄存器。第 54~56 行是设置 GPIO1->GDIR 寄存器,将 GPIO1_IO03 设置为输出模式,也就是寄存器的 GPIO1_GDIR 的 bit3 置 1。

第 61~63 行设置 GPIO1->DR 寄存器,也就是设置 GPIO1_IO03 的输出,我们要点亮开发板上的 LED0,那么 GPIO1_IO03 就必须输出低电平,所以这里设置 GPIO1_DR 寄存器为 0。

第 68~69 行是死循环,通过 b 指令, CPU 重复不断的跳到 loop 函数执行,进入一个死循环

编译程序

①、使用arm-linux-gnueabihf-gcc,将.c .s文件变为.o
②、将所有的.o文件连接为elf格式的可执行文件。
③、将elf文件转为bin文件。
④、将elf文件转为汇编,反汇编。

arm-linux-gnueabihf-gcc -g -c led1.s -o led1.o
arm-linux-gnueabihf-ld -Ttext 0x87800000 led1.o -o led1.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led1.elf led1.bin
arm-linux-gnueabihf-objdump -D led1.elf > led1.dis

本教程所有裸机例程的链接地址都在 DDR
中,链接起始地址为 0X87800000。 I.MX6U-ALPHA 开发板的 DDR 容量有两种: 512MB 和256MB,起始地址都为 0X80000000,只不过 512MB 的终止地址为 0X9FFFFFFF,而 256MB 容量的终止地址为 0X8FFFFFFF。之所以选择 0X87800000 这个地址是因为后面要讲的 Uboot 其链接地址就是 0X87800000,这样我们统一使用 0X87800000 这个链接地址,不容易记混。

代码烧写

将自带的烧写工具imxdownload放在工程目录下给予可执行权限

找到TF卡格式化为FAT32格式连接到虚拟机上。通过命令/dev/sd*查看节点,插入后多的一个节点就是TF卡的设备节点

运行./imxdownload led.bin /dev/sdb(我的节点是sdb)

生成load.imx说运行成功。

将TF卡插到sd卡槽里将拨码开关设置为1和7开,插上电源打开开关就可以看到红灯亮

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值