• IMX6ULL—汇编LED灯


    I.MX6U IO 命名

    参考手册的第 32 章:
    在这里插入图片描述
    分为SNVS域和通用的,本质上都是一样的。

    “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.MX6U IO 复用

    以“IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00”这个 IO 为例:
    在这里插入图片描述
    可以看到有个名为:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 的寄存器,寄存器地址为 0X020E005C,这个寄存器是 32 位的,但是只用到了最低 5 位,其中bit0 - bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的。GPIO1_IO00 一共可以复用为 9种功能 IO,分别对应 ALT0~ALT8,其中 ALT5 就是作为 GPIO1_IO00。GPIO1_IO00 还可以作为 I2C2_SCL、GPT1_CAPTURE1、ANATOP_OTG1_ID 等。这个就是 I.MX6U 的 IO 复用。

    如果只想看每个 IO 能复用什么外设的话可以直接查阅《IMX6ULL 参考手册》的第 4 章“Chapter 4 External Signals and Pin Multiplexing”。如果要编写代码,设置某个 IO 的复用功能的话就需要查阅第 32 章“Chapter 32: IOMUX Controller(IOMUXC)”,第 32 章详细的列出了所有 IO 对应的复用配置寄存器。

    I.MX6U IO 配置

    GPIO1_IO00 有如下两个书签:

    IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00
    IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00
    
    • 1
    • 2

    在这里插入图片描述
    IOMUX_SW_MUX_CTL_PAD_GPIO1_IO00 是用来配置GPIO1_IO00 复用功能的。

    IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00 是用来配置 GPIO1_IO00 的,包括速度设置、驱动能力设置、压摆率设置等等。

    I.MX6U GPIO 配置

    在这里插入图片描述
    如上图左 下 角 的 IOMUXC 框 图 里 面 就 有 SW_MUX_CTL_PAD_* 和SW_PAD_CTL_PAD_*两种寄存器。这两种寄存器前面说了用来设置 IO 的复用功能和 IO 属性配置。左上角部分的 GPIO 框图就是,当 IO 用作 GPIO 的时候需要设置的寄存器,一共有八个:DR、GDIR、PSR、ICR1、ICR2、EDGE_SEL、IMR 和 ISR

    DR 寄存器

    输出:0或者1
    在这里插入图片描述
    此寄存器是 32 位的,一个 GPIO 组最大只有 32 个 IO,因此 DR 寄存器中的每个位都对应
    一个 GPIO。

    要设置 GPIO1_IO00 输出高电平,那么就应该设置 GPIO1.DR=1。

    当 GPIO被配置为输入模式以后,此寄存器就保存着对应 IO 的电平值,每个位对对应一个 GPIO,例如,当 GPIO1_IO00 这个引脚接地的话,那么 GPIO1.DR 的 bit0 就是 0。

    GDIR 寄存器

    在这里插入图片描述
    设置 GPIO 为输入,就设置相应的位为 0,如果要设置为输出的话就设置为 1。比如要设置 GPIO1_IO00 为输入,那么 GPIO1.GDIR=0;

    PSR 寄存器

    在这里插入图片描述
    同样的 PSR 寄存器也是一个 GPIO 对应一个位,读取相应的位即可获取对应的 GPIO 的状态,也就是 GPIO 的高低电平值。功能和输入状态下的 DR 寄存器一样。

    ICR1和ICR2寄存器

    ICR1用于配置低16个GPIO,ICR2 用于配置高 16 个 GPIO。
    在这里插入图片描述
    ICR1 用于 IO0-15 的配置, ICR2 用于 IO16~31 的配置。ICR1 寄存器中一个 GPIO 用两个位,这两个位用来配置中断的触发方式,和 STM32 的中断很类似,可配置的选线如表。
    在这里插入图片描述

    IMR 寄存器—中断屏蔽寄存器

    在这里插入图片描述
    IMR 寄存器也是一个 GPIO 对应一个位,IMR 寄存器用来控制 GPIO 的中断禁止和使能,如果使能某个 GPIO 的中断,那么设置相应的位为 1 即可,反之,如果要禁止中断,那么就设置相应的位为 0 即可。例如,要使能 GPIO1_IO00 的中断,那么就可以设置 GPIO1.MIR=1。

    ISR寄存器—中断状态寄存器

    在这里插入图片描述
    ISR 寄存器也是 32 位寄存器,一个 GPIO 对应一个位,只要某个 GPIO 的中断发生,那么ISR 中相应的位就会被置 1。所以,可以通过读取 ISR 寄存器来判断 GPIO 中断是否发生,相当于 ISR 中的这些位就是中断标志位。当处理完中断以后,必须清除中断标志位,清除方法就是向 ISR 中相应的位写 1,也就是写 1 清零。

    EDGE_SEL 寄存器—边沿选择寄存器

    在这里插入图片描述

    EDGE_SEL 寄存器用来设置边沿中断,这个寄存器会覆盖 ICR1 和 ICR2 的设置,同样是一个 GPIO 对应一个位。如果相应的位被置 1,那么就相当与设置了对应的 GPIO 是上升沿和下降沿(双边沿)触发。例如,设置 GPIO1.EDGE_SEL=1,那么就表示 GPIO1_IO01 是双边沿触发中断,无论 GFPIO1_CR1 的设置为多少,都是双边沿触发。

    关于 GPIO 的寄存器就讲解到这里,因为 GPIO 是最常用的功能,详细的讲解了 GPIO的 8 个寄存器。 I.MX6U 的 IO 是需要配置和输出的、是可以设置输出高低电平,也可以读取 GPIO 对应的电平。

    I.MX6U GPIO 时钟使能

    CCM_CCGR0 结构体如图:
    在这里插入图片描述
    CCM_CCGR0 是个 32 位寄存器,其中每 2 位控制一个外设的时钟,比如 bit31:30 控制着GPIO2 的外设时钟,两个位就有 4 种操作方式,如表所示:
    在这里插入图片描述
    如果要打开 GPIO2 的外设时钟,那么只需要设置CCM_CCGR0 的 bit31 和 bit30 都为1即可,也就是CCM_CCGR0=3 << 30。反之,如果要关闭GPIO2 的外设时钟,那就设置 CCM_CCGR0 的 bit31和bit30都为0即。

    总结一下,要将 I.MX6U 的 IO 作为 GPIO 使用,需要以下几步:
    ①、使能 GPIO 对应的时钟。

    ②、设置寄存器 IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置 IO 的复用功能,使其复用为 GPIO 功能。

    ③、设置寄存器 IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置 IO 的上下拉、速度等等。

    ④、第②步已经将 IO 复用为了 GPIO 功能,所以需要配置 GPIO,设置输入/输出、是否使用中断、默认输出电平等。

    汇编点灯实例

    在这里插入图片描述

    1、使能 GPIO1 时钟

    GPIO1 的时钟由 CCM_CCGR1 的 bit27 和 bit26 这两个位控制,将这两个位都设置位 11 即可。

    2、设置 GPIO1_IO03 的复用功能

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

    3、配置 GPIO1_IO03

    找到 GPIO1_IO03 的配置寄存器“IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03”的地址为0X020E02F4,根据实际使用情况,配置此寄存器。

    4、设置 GPIO

    将 GPIO1_IO03 复用为了 GPIO 功能,所以需要配置 GPIO。找到 GPIO3 对应的 GPIO 组寄存器地址,在《IMX6ULL 参考手册》的 1357 页,如图所示:
    在这里插入图片描述
    实验中 GPIO1_IO03 是作为输出功能的,因此 GPIO1_GDIR 的 bit3 要设置为 1,表示输出。

    5、控制 GPIO 的输出电平

    经过前面几步,GPIO1_IO03 已经配置好了,只需要向 GPIO1_DR 寄存器的 bit3 写入 0 即可控制 GPIO1_IO03 输出低电平,打开 LED,向 bit3 写入 1 可控制 GPIO1_IO03 输出高电平,关闭 LED。

    .global _start  /* 全局标号 */
    //定义了一个全局标号_start,代码就是从_start 这个标号开始顺序往下执行的。
    /*
     * 描述:	_start函数,程序从此函数开始执行此函数完成时钟使能、
     *		  GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
     */
    _start:
    	/* 例程代码 */
    	/* 1、使能所有时钟 */
    	//CCGR0 
    	ldr r0, =0X020C4068 	/* 使用 ldr 指令向寄存器 r0 写入 0X020C4068,也就是 r0=0X020C4068,这个是CCM_CCGR0 寄存器的地址*/
    	ldr r1, =0XFFFFFFFF /*使用 ldr 指令向寄存器 r1 写入 0XFFFFFFFF,也就是 r1=0XFFFFFFFF。因为要开启所有的外设时钟,因此 CCM_CCGR0~CCM_CCGR6 所有寄存器的 32 位都要置 1,也就是写入 0XFFFFFFFF。*/ 
    	str r1, [r0]		/*使用 str 将 r1 中的值写入到 r0 所保存的地址中去,也就是给 0X020C4068 这个地址写入 0XFFFFFFFF,相当于 CCM_CCGR0=0XFFFFFFFF,就是打开 CCM_CCGR0 寄存器所控制的所有外设时钟。*/
    	
    	//开启CCGR1的时钟
    	ldr r0, =0X020C406C  	/* CCGR1 */
    	str r1, [r0]
    	//开启CCGR2的时钟
    	ldr r0, =0X020C4070  	/* CCGR2 */
    	str r1, [r0]
    	//开启CCGR3的时钟
    	ldr r0, =0X020C4074  	/* CCGR3 */
    	str r1, [r0]
    	//开启CCGR4的时钟
    	ldr r0, =0X020C4078  	/* CCGR4 */
    	str r1, [r0]
    	//开启CCGR5的时钟
    	ldr r0, =0X020C407C  	/* CCGR5 */
    	str r1, [r0]
    	//开启CCGR6的时钟
    	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死循环
     */
    loop:
    	b loop 				
    
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    编译命令

    arm-linux-gnueabihf-gcc -g -c led.s -o led.o
    arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
    arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
    arm-linux-gnueabihf-objdump -D led.elf > led.dis
    
    • 1
    • 2
    • 3
    • 4

    makefile文件

    led.bin:led.s
    	 arm-linux-gnueabihf-gcc -g -c led.s -o led.o
    	 arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
    	 arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
    	 arm-linux-gnueabihf-objdump -D led.elf > led.dis
    clean:
    	rm -rf *.o led.bin led.elf led.dis
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    连接脚本文件

    arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf $^
    
    • 1
    示例代码 10.4.2.2 imx6ul.lds 链接脚本代码
    1 SECTIONS{
    2 . = 0X87800000;
    	3 .text :
    	4 {
    	5 start.o 
    	6 main.o 
    	7 *(.text)
    	8 }
    	9 .rodata ALIGN(4) : {*(.rodata*)} 
    	10 .data ALIGN(4) : { *(.data) } 
    	11 __bss_start = .; 
    	12 .bss ALIGN(4) : { *(.bss) *(COMMON) } 
    	13 __bss_end = .;
    14 }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    代码烧写

    烧写格式:

    ./imxdownload <.bin file> <SD Card>
    
    • 1

    其中.bin 就是要烧写的.bin 文件,SD Card 就是要烧写的 SD 卡。

    ./imxdownload led.bin /dev/sdd //不能烧写到/dev/sda 或 sda1 设备里面!那是系统磁盘
    
    • 1

    现象

    在这里插入图片描述

  • 相关阅读:
    LeetCode 练习——剑指 Offer 66. 构建乘积数组
    Unity性能优化分析篇
    SSL OV证书和DV、EV证书的区别
    windows和linux中Nginx常用命令
    百度发布Q3财报:AI原生应用驱动业绩增长 公司股价应声涨超5%
    HTML5页面布局
    Mysql——压缩包方式安装教程
    2 分钟,教你用 Serverless 每天给女朋友自动发土味情话
    余弦相似度算法进行客户流失分类预测
    java毕业设计教师档案管理系统(附源码、数据库)
  • 原文地址:https://blog.csdn.net/m0_46152793/article/details/126240023