第八章 汇编LED灯实验
IO控制初始化所需要用到的寄存器
1. SW_MUX_CTL Register
Address:20E_0000h base+5Ch offset=20E_005Ch
2. SW_PAD_CTL Register
Address:20E_0000h base+2E8h offset=20E_02E8h
从上图中可以看出,该寄存器只用到了低17位:
HYS(Bits16):用来使能迟滞比较器,输入有效时,需要对输入波形进行整形可以使用此使能位,0禁止,1使能。
PUS(Bits15:14):用来设置上下拉电阻,
位设置 | 含义 |
---|---|
00 | 100K下拉 |
01 | 47K上拉 |
10 | 100K上拉 |
11 | 22K上拉 |
PUE(Bits13):用来设置IO使用上下拉还是状态保持器,0为状态保持器,1为使用上下拉,状态保持器在IO作为输入时才有效。
PKE(Bits12):用来使能或者禁止上下拉/状态保持器功能,为0禁止上下拉/状态保持器,为1使能上下拉和状态保持器。
SPEED(Bits7:6):当IO用作输出时,设置IO速度。
位设置 | 速度 |
---|---|
00 | 低速50M |
01 | 中速100M |
10 | 中速100M |
11 | 最大速度200M |
DSE(Bits5:3):用来设置IO的驱动能力。
位设置 | 速度 |
---|---|
000 | 输出驱动关闭 |
001 | R0(3.3V下 R0是 260Ω, 1.8V下 R0是 150Ω,接 DDR的时候是 240ΩΩ) |
010 | R0/2 |
011 | R0/3 |
100 | R0/4 |
101 | R0/5 |
110 | R0/6 |
111 | R0/7 |
DSE(Bits5:3):设置压摆率,压摆率指的是IO电平跳变所需要的时间,时间越短压摆率越高,反之越低。过EMC需要低压摆率,高速通信需要高压摆率。
3.GPIO的配置
IOMUXC_SW_MUX_CTL_PAD_XX_XX和 IOMUXC_SW_PAD_CTL_PAD_XX_XX这两种寄存器都是配置 IO的,注意以下IO与GPIO的区别,GPIO是IO众多复用的其中一种。
当IO用作GPIO时需要设置的寄存器共有8个:DR、GDIR、PSR、ICRC、ICR2、EDGE_SEL、IMR和ISR…
DR寄存器
一个GPIO组最大只有32个IO,DR寄存器的每一个位对应一个GPIO,当GPIO被设置成输出功能后,相应的IO就会输出相应的高低电平,置1为高电平,置0为低电平。当GPIO被设置成输入功能后,该寄存器将会保存对应IO的电平值,1为高电平,0为低电平。
GDIR寄存器
GDIR也是32位,用来设置某个IO的工作方向,是输入还是输出,一个IO对应一个位,置0为输入,置1为输出。
PSR寄存器
PSR是GPIO状态寄存器,一个GPIO对应一个位,读取相应的位即可获取GPIO的状态,也就是GPIO的高低电平。功能和输入状态下的DR寄存器一样。
ICR1和ICR2寄存器
ICR1和ICR2是中断控制寄存器,ICR1用于配置低16位GPIO,ICR2用于配置高16位。配置选线如下表:
位设置 | 速度 |
---|---|
00 | 低电平触发 |
01 | 高电平触发 |
10 | 上升沿触发 |
11 | 下降沿触发 |
IMR寄存器
IMR寄存器是中断屏蔽寄存器,也是一个GPIO对应一个位,使能GPIO中断置1,反之禁止。
ISR寄存器
ISR寄存器是中断状态存器,也是一个GPIO对应一个位,某个GPIO中断发生了,相应的位将会被置1,我们可以通过读取ISR来判断GPIO是否发生中断,当中断处理完成之后,必须清除中断标志位,清除方法是向ISR相应的位写1,也就是清零。
EDGE_SEL寄存器
EDGE_SEL寄存器用来设置边沿中断,这个寄存器会覆盖ICR1和ICR2的设置,同样是一个GPIO对应一个位,置1表示双边沿触发中断,无论GPIO_CR1设置的是多少,都是双边沿触发。
### 时钟使能 I.MX6U的系统时钟参考 《 I.MX6UL参考手册》的第 18章“ Chapter 18: Clock Controller Module(CCM)”,这一个章主要将时钟系统。目前不研究,只看CMM的外设时钟使能寄存器。CMM有CCM_CCGR0~CCM_CCGR6这7个寄存器, ##### CCM_CCGR0 寄存器 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20191126172527689.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI1OTM1MTY5,size_16,color_FFFFFF,t_70)
CCM_CCGR0是32位寄存器,其中每2位控制一个外设时钟,比如bit31:30控制着GPIO2的外设时钟,两个位有4种操作方式。
位设置 | 时钟控制 |
---|---|
00 | 所有模式下都关闭外设时钟 |
01 | 只有在运行模式下打开外设时钟,等待模式和停止模式均关闭外设时钟 |
10 | 未使用(保留) |
11 | 除了停止模式以外,其他所有模式下时钟都打开 |
I.MX6U的IO作为GPIO使用,初始化步骤如下:
1. 使能GPIO对应时钟。
2. 设置寄存器IOMUXC_SW_MUX_CTL_PAD_XX_XX,设置IO复用功能,使其复用位GPIO功能。
3. 设置寄存器IOMUXC_SW_PAD_CTL_PAD_XX_XX,设置IO的上下拉、速度等等。
4. 第2步已经将IO复用为GPIO功能,所以需要配置GPIO,设置输入/输出、是否使能中断、默认输出电平等。
示例代码:
.global _start
_start:
/*
*1.使能所有的时钟(CCGR0~CCGR1)
*/
ldr r0,=0x020C4068 /*打开CCM_CCGR0寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C406C /*打开CCM_CCGR1寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C4070 /*打开CCM_CCGR2寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C4074 /*打开CCM_CCGR3寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C4078 /*打开CCM_CCGR4寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C407C /*打开CCM_CCGR5寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
ldr r0,=0x020C4080 /*打开CCM_CCGR6寄存器的所有时钟*/
ldr r1,=0xFFFFFFFF
str r1,[r0]
/*
*2.设置复用
*/
ldr r0,=0x02E00068
ldr r1,=0x00000005
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
*低转换率 48
*/
ldr r0,=0x020E02F4
ldr r1,=0x000010B0
ldr r1,[r0]
/*
*4.设置GPIO1_IO3为输出
*/
ldr r0,=0x0209C004 /*配置GDIR寄存器*/
ldr r1,=0x00000008 /*默认电平为1*/
str r1,[r0]
/*
*5.打开LED0,设置GPIO1_IO03为高电平
*/
ldr r0,=0x0209C0000 /*配置DR寄存器*/
ldr r1,=0x000000000 /*默认电平为1*/
str r1,[r0]
/*
*loop死循环
*/
loop:
b loop
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-guneabihf-objdump -D led.elf > led.dis
clean:
rm -rf *.o led.bin led.elf led.dis
arm-linux-gnueabihf-gcc -g -c led.s -o led.o(编译文件)
arm-linux-gnueabihf-gcc :表示编译文件;
-g:选项表示产生调试信息;
-c:选项表示编译源文件,但是不链接;
-o:选项表示指定编译产生的文件名字。
arm-linux-gnueabihf-ld -Ttext 0x87800000 led.o -o led.elf(链接文件)
arm-linux-gnueabihf-ld:表示将众多的.o文件链接到一个指定的链接位置;
-Ttext:表示连接时将初始地址重定向为0x87800000;
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin(格式转换)
arm-linux-gnueabihf-objcopy 表示将led.elf文件转换成led.bin文件;
-O:选项表示指定以什么格式输出;
binary:表示以二进制格式输出;
-S:表示不要复制源文件的重定位信息和符号信息;
-g:表示不要复制源文件中的调试信息。
arm-linux-guneabihf-objdump -D (-m arm)led.elf > led.dis(反汇编)
arm-linux-gnueabihf-objdump:表示进行反汇编,用来查看其汇编代码来调试代码;
-D:表示反汇编所有的段;
-m:表示后面跟CPU架构;
>:表示将这个程序的反汇编程序写入到led.dis这个文件中,在终端中不显示出来。