当前位置:网站首页>IMX6ULL—汇编LED灯
IMX6ULL—汇编LED灯
2022-08-09 17:06:00 【梅山剑客】
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

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
编译命令
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
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
连接脚本文件
arm-linux-gnueabihf-ld -Ttext 0X87800000 -o ledc.elf $^
示例代码 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 }
代码烧写
烧写格式:
./imxdownload <.bin file> <SD Card>
其中.bin 就是要烧写的.bin 文件,SD Card 就是要烧写的 SD 卡。
./imxdownload led.bin /dev/sdd //不能烧写到/dev/sda 或 sda1 设备里面!那是系统磁盘
现象

边栏推荐
- 【机器学习】回归树生成过程及举例理解
- 艺术与科技的狂欢,云端XR支撑阿那亚2022砂之盒沉浸艺术季
- QoS - ROS2 principle 9 】 【 deadline, activity and life
- Tan Zhongyi: Do you know who the "Queen of Open Source" is?
- 重谈联想5G编码投票事件
- The senior told me that the MySQL of the big factory is connected through SSH
- One-key login principle of local number
- Detailed explanation of JVM memory model and structure (five model diagrams)
- 动态RDLC报表(五)
- 2022秋招面试宝典,啃完面试稳了
猜你喜欢
随机推荐
A carnival of art and technology, cloud XR supports Anaya 2022 Sandbox Immersive Art Season
Ark: Survival Evolved Open Server Port Mapping Tutorial
搭建Zabbix监控系统
ref的使用
动态RDLC报表(五)
The most complete architect knowledge map in history
论如何提升学习的能力
BSN季度版本2022年8月31日迭代更新预告
虚拟补丁备忘单
AI基础环境搭建和设置总文
leetcode300.最长递增子序列(动态规划)
体验远超Hue,这才是技术人员最喜欢的SQL工具
集合框架Collection与Map的区别和基本使用
低代码平台和专业开发人员——完美搭档?
The principle implementation of handwritten flexible.js, I finally understand the multi-terminal adaptation of the mobile terminal
win10 uwp 获得Slider拖动结束的值
为什么修补应用程序漏洞并不容易
ABP详细教程——模块类
JMeter笔记6 | JMeter录制(配置代理)
crm系统哪家好?好用的crm管理系统推荐









