I.MX6UL:汇编LED驱动实验

发布于:2025-09-11 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、前言

        I.MX6UL 使用的是 Cortex-A7 架构,Cortex-A 芯片一上电 SP 指针还没初始化,C 环境还没准备好,所以肯定不能运行 C 代码,必须先用汇编语言设置好 C 环境,比如初始化 DDR、设置 SP指针等等,当汇编把 C 环境设置好了以后才可以运行 C 代码。所以Cortex-A 一开始肯定是汇编代码,其实STM32也一样的,一开始也是汇编,以 STM32F103 为例,启动文件startup_stm32f10x_hd.s 就是汇编文件,只是这个文件ST已经写好了,我们根本不用去修改。

二、硬件原理

        从可以看出,LED0 接到了 GPIO_3 上,GPIO_3 就是 GPIO1_IO03。

三、IMX6U GPIO学习

STM32 IO 初始化流程:

        (1)使能GPIO时钟

        (2)配置IO复用,将其复用为GPIO

*      (3)配置GPIO的电气属性

        (4)使能GPIO,输出高低电平 

IMX6ULL IO初始化:

(1)使能时钟,CCGR0--CCGR6这7个寄存器控制着IMX6ULL所有外设时钟的使能。为了简单,设置CCGR0--CCGR6这7个寄存器全部为0XFFFFFFFF,相当于使能所有外设时钟。

(2)IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3-0设置为0x5,复用GPIO1_IO03为GPIO。

(3)寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO1_IO03的电气属性,包括压摆率、速度、驱动能力、开漏,上下拉等等。

(4)配置GPIO功能,设置输入输出。设置 GPIO1_GDIR 寄存器bit3位为1,也就是设置为输出模式。向 GPIO1_DR 寄存器的 bit3位来控制 GPIO1_IO03 输出高低电平。

3.1 I.MX6UL的外设时钟

        IMX6ULL参考手册699页中( 手册中有:此字段保留(未用到的意思)),CCGR0-CCGR6这七个寄存器控制着所有外设时钟的使能。

3.2 I.MX6UL的IO复用

        从图可以看出,I.MX6ULL的IO分为两类:SNVS域的和通用的,这两类IO本质上都是一样的。图中的形如“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00”的就是GPIO命名,命名形式就是“IOMUXC_SW_MUC_CTL_PAD_XX_XX”,后面的“XX_XX”就是GPIO命名,比如:GPIO1_IO01、UART1_TX_DATA、JTAG_MOD等等。I.MX6ULL的GPIO并不像STM32一样以PA0~15这样命名,他是根据某个IO所拥有的功能来命名的。比如我们一看到GPIO1_IO01就知道这个肯定能做GPIO。

        

        手册中1571页,IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 的寄存器,这个寄存器是32位的,但是只用到了最低5位,其中bit0~bit3(MUX_MODE)就是设置 GPIO1_IO03 的复用功能的。GPIO1_IO03 一共可以复用为9种功能 IO,分别对应 ALT0~ALT8,其中 ALT5 就是作为 GPIO1_IO03。

3.3 I.MX6UL的IO配置

        如图所示,手册中1793页展示了寄存器 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03

(1)HYS(bit16): 用来使能迟滞比较器,当 IO 作为输入功能的时候有效,用于设置输入接收器的施密特触发器是否使能。如果需要对输入波形进行整形的话可以使能此位。此位为 0 的时候禁止迟滞比较器,为 1 的时候使能迟滞比较器。(暂时用不到)

(2)PUS(bit15:14): 用来设置上下拉电阻的,一共有四种选项可以选择,如图所示。

(3)PUE(bit13):当 IO 作为输入的时候,这个位用来设置 IO 使用上下拉还是状态保持器。当为 0 的时候使用状态保持器,当为 1 的时候使用上下拉。状态保持器在IO 作为输入的时候才有用,就是当外部电路断电以后此 IO 口可以保持住以前的状态。

(4)PKE(bit12):此位用来使能或者禁止上下拉/状态保持器功能,为 0 时禁止上下拉/状态保持器,为 1 时使能上下拉和状态保持器。
(5)ODE(bit11): 当 IO 作为输出的时候,此位用来禁止或者使能开路输出,此位为 0 的时候禁止开路输出,当此位为 1 的时候就使能开路输出功能。

(6)SPEED(bit7:6):当 IO 用作输出的时候,此位用来设置 IO 速度,设置如图所示。

(7)DSE(bit5:3):当 IO 用作输出的时候用来设置 IO 的驱动能力,总共有 8 个可选选项,如图所示,电阻越小驱动能力越强。

(8)SRE(bit0):设置压摆率,当此位为 0 的时候是低压摆率,当为 1 的时候是高压摆率。这里的压摆率就是 IO 电平跳变所需要的时间,比如从 0 到 1 需要多少时间,时间越小波形就越陡,说明压摆率越高;反之,时间越多波形就越缓,压摆率就越低。如果你的产品要过 EMC 的话那就可以使用小的压摆率,因为波形缓和,如果你当前所使用的 IO做高速通信的话就可以使用高压摆率。

3.4 MX6U GPIO 配置

        手册1358页,此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应一个 GPIO。当 GPIO 被配置为输出功能以后,向指定的位写入数据那么相应的 IO 就会输出相应的高低电平,比如要设置 GPIO1_IO00 输出高电平,那么就应该设GPIO1.DR=1。当 GPIO被配置为输入模式以后,此寄存器就保存着对应 IO 的电平值,每个位对对应一个GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的 bit0 就是 0。

        GDIR 寄存器,这是方向寄存器,用来设置某个 GPIO 的工作方向的,即输入/输出,GDIR 寄存器结构如图所示。GDIR 寄存器也是 32 位的,此寄存器用来设置某个 IO 的工作方向,是输入还是输出。同样的,每个 IO 对应一个位,如果要设置 GPIO 为输入的话就设置相应的位为 0,如果要设置为输出的话就设置为 1。比如要设置 GPIO1_IO00 为输入,那么 GPIO1.GDIR=0;

四、汇编程序编写

        下图来自IMX6ULL参考手册699页,可查询到CCM_CCGR0的地址。


.global_start @全局标号

_start:

    ldr r0, =0X020C4068 /* 寄存器 CCGR0 */
    ldr r1, = 0xffffffff
    str r1 ,[r0];

    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、设置 GPIO1_IO03 复用为 GPIO1_IO03 */
    ldr r0, =0X020E0068 /* 将寄存器 SW_MUX_GPIO1_IO03_BASE 加载到 r0 中 */
    ldr r1, =0X5        /* 设置寄存器 SW_MUX_GPIO1_IO03_BASE 的 MUX_MODE 为 5 */
    str r1,[r0]

/* 3、配置 GPIO1_IO03 的 IO 属性
    *bit 16:0 HYS 关闭
    *bit [15:14]: 00 默认下拉
    *bit [13]: 0 kepper 功能
    *bit [12]: 1 pull/keeper 使能
    *bit [11]: 0 关闭开路输出
    *bit [7:6]: 10 速度 100Mhz
    *bit [5:3]: 110 R0/6 驱动能力
    *bit [0]: 0 低转换率
 */
    ldr r0, =0X020E02F4 /*寄存器 SW_PAD_GPIO1_IO03_BASE */
    ldr r1, =0X10B0
    str r1,[r0]
 
    /* 4、设置 GPIO1_IO03 为输出 */
 
    ldr r0, =0X0209C004 /*寄存器 GPIO1_GDIR */
    ldr r1, =0X0000008
    str r1,[r0]
 
    /* 5、打开 LED0
    * 设置 GPIO1_IO03 输出低电平
    */
    ldr r0, =0X0209C000 /*寄存器 GPIO1_DR */
    ldr r1, =0
    str r1,[r0]

loop:
    b loop


网站公告

今日签到

点亮在社区的每一天
去签到