**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。

编写代码前我们需要理清楚代码的逻辑,也就是我们需要在代码中干嘛,才能点亮某个led灯。
整体的代码在最后面

1. 原理分析

首先看我们想要点亮的led在开发板底板原理图上的位置,找到我们需要操作的IO
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第1张图片上图中有led的电路图我们仔细看
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第2张图片 **汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第3张图片
看来只要把LED0设置低电平0,这样就亮了!
继续找LED0发现右图,LED0与GPIO3公用一个引脚,也就是说,在这个引脚悬空的状态下,我们将GPIO3拉低,就能够做到点亮小灯!

那GPIO3对应的是芯片上的哪个东西呢!是GPIO1_IO03也就是第一组GPIO的03个GPIO口,因此 我们想要修改这个GPIO口的高低电平,需要以下几个步骤:
(也就是I.MX6ULL IO初始化)

  1. 使能时钟 CCGR0-CCGR6这7个寄存器控制着6ULL所有外设时钟的使能。为了简单,设置CCGR0~CCGR6这7个寄存器全部为0XFFFFFFFF,相当于使能所有外设时钟。
  2. IO复用 将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3~0设置为0101=5,这样GPIO1_IO03就复用为GPIO。
  3. 寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO1_IO03的电气属性 包括压摆率、速度、驱动能力、开漏、上下拉等。
  4. 配置GPIO功能,设置输入输出 设置GPIO1_DR寄存器bit3为1,也就是设置为输出模式。设置GPIO1_DR寄存器的bit3,为1表示输出高电平,为0表示输出低电平。
  5. 打开LED 也就是设置相应GPIO1_IO03数据寄存器的相应位为低电位
    下面根据这些步骤一步一步进行:

1.1 使能时钟

CMM 有 CCM_CCGR0~CCM_CCGR6 这 7 个寄存器,这 7 个寄存
器控制着 I.MX6U 的所有外设时钟开关,为了方便我们将这些全都打开(在查手册的过程中发现似乎是ccgr2控制着GPIO1组的时钟使能)
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第4张图片**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第5张图片
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第6张图片

 ldr r0, =0x020c4068 @CCGR0的地址
 ldr r1, =0xffffffff @要向CCGR0写入的值
 str r1,[r0]         @将0xffffffff这个值 写入到 r0中存储的值代表的地址中去,就是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]

2. IO复用

**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第7张图片**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第8张图片
从上图看出配置 GPIO1_IO03 的pin为GPIO 也就是设置这个寄存器的IO复用功能
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器的 MUX_MODE 为 0101也就是5
其地址为 20E_0068h

ldr r0, =0x020E0068
ldr r1, =0x5
str r1, [r0]

3.设置GPIO1_IO03的电气属性

在这里插入图片描述
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第9张图片**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第10张图片

/* 配置电气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   keeper保持
 * bit15-14 00  默认100K下拉
 * bit16    0   关闭HYS
 */
@用计算器把上面的数按一下,换算为0x10b0  把它写入到上面的地址值中
ldr r0, =0x020E02F4
ldr r1, =0x10B0
str r1,[r0]

4. 配置GPIO功能,设置输入输出

肯定是输出的了,因为我们要让这个引脚输出低电平呀
这里需要控制另一个寄存器GPIO1_GDIR
**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第11张图片**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第12张图片**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第13张图片

/* 设置GPIO的输入或是输出  通过修改GPIO1_GDIR寄存器的值来搞定 0为输入 1为输出,
 * 该寄存器共有32位,控制着GPIO1组中32个GPIO口,我们要要GPIO1_IO03,也就是设置第三位
 * 查数据手册中的GPIO章节中,GPIO Memery Map/Register Definition 找到
 * GPIO0_GDIR寄存器的地址值为:209_C004  将这个地址值中的第三位值设置为1(1000 = 8)
 */
ldr r0,=0x0209c004
ldr r1,=0x8
str r1,[r0]

5. 修改GPIO口的电平

**汇编版**led灯实验01(I.MX6ULL):代码编写逻辑。_第14张图片

/* 打开LED,也就是设置GPIO1_IO03为0
 * 设置GPIO1_DR寄存器(data register数据寄存器)中的第三位设置为0,低电平
 * 这个寄存器同GPIO1_GDIR差不多,都是1位控制一个GPIO口:地址是:0x0209c000
 */
ldr r0,=0x0209c000
ldr r1,=0
str r1,[r0]

所以整体的程序如下所示

.global _start  @全局标号

_start:
/*第一步: */
    /*使能所有外设时钟 */
    @通过参考手册查到各个时钟的地址
    ldr r0, =0x020c4068 @CCGR0的地址
    ldr r1, =0xffffffff @要向CCGR0写入的值
    str r1,[r0]         @将0xffffffff这个值 写入到 r0中存储的值代表的地址中去,就是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 也就是设置这个寄存器的IO复用功能
     * IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器的 MUX_MODE 为 0101也就是5
     * 其地址为 20E_0068h
     */
    ldr r0, =0x020E0068
    ldr r1, =0x5
    str r1, [r0]
/*第三步: */
    /* 配置电气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   keeper保持
     * bit15-14 00  默认100K下拉
     * bit16    0   关闭HYS
     */
    @用计算器把上面的数按一下,换算为0x10b0  把它写入到上面的地址值中
    ldr r0, =0x020E02F4
    ldr r1, =0x000010B0
    str r1,[r0]
/*第四步: */
    /* 设置GPIO的输入或是输出  通过修改GPIO1_GDIR寄存器的值来搞定 0为输入 1为输出,
     * 该寄存器共有32位,控制着GPIO1组中32个GPIO口,我们要要GPIO1_IO03,也就是设置第三位
     * 查数据手册中的GPIO章节中,GPIO Memery Map/Register Definition 找到
     * GPIO0_GDIR寄存器的地址值为:209_C004  将这个地址值中的第三位值设置为1(1000 = 8)
     */
    ldr r0,=0x0209c004
    ldr r1,=0x8
    str r1,[r0]
/*设置结束!开灯! */
    /* 打开LED,也就是设置GPIO1_IO03为0
     * 设置GPIO1_DR寄存器(data register数据寄存器)中的第三位设置为0,低电平
     * 这个寄存器同GPIO1_GDIR差不多,都是1位控制一个GPIO口:地址是:0x0209c000
     */
    ldr r0,=0x0209c000
    ldr r1,=0
    str r1,[r0]
loop:           @ 保持状态 持续调用loop函数 b表示跳转到loop函数。
    b loop



你可能感兴趣的:(嵌入式相关)