按照前面的介绍,我们需要对GPIO1_IO03做如下的设置:
1.使能GPIO1的时钟
GPIO1的时钟由CCM_CCGR1寄存器的bit27和26控制,我们把这两位设置成1,就会使能GPIO1的时钟了。
2.配置GPIO1_IO03的复用功能
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器是GPIO1_IO03的复用寄存器,地址是0x20e0068,把这个寄存器设置成GPIO功能。
3.配置GPIO1_IO03上下拉
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03寄存器是GPIO1_IO03的配置寄存器,通过该寄存器配置GPIO1_IO03为GPIO的上下拉。
4.设置GPIO1_IO03输出
在第二步骤我们已经把GPIO1_IO03复用成GPIO了,然后我们需要配置GPIO为输出,以及输出时候的高低电平,在《IMX6ULL 参考手册》的1357页我们可以看到GPIO1_IO03对应的GPIO寄存器组,如图 1所示:
通过设置寄存器GPIO1_GDIR的bit3为1,可以设置GPIO1_IO03为输出。然后通过设置GPIO1_DR寄存器的bit3为0,可以控制GPIO1_IO03输出低电平,LED会亮。GPIO1_DR的bit3设置为1,可以控制GPIO1_IO03输出高电平,LED会灭。
本实验的源码在开发板光盘资料的"i.MX6UL终结者光盘资料\04_裸机例程源码\1_leds\1_leds"目录下,我们可以把这个文件夹拷贝到UBuntu下,使用交叉编译器编译。
下面我们开始一步步的实现LED这个实验。首先登录Ubuntu系统,在用户的根目录下的work文件夹创建led文件夹然后在led目录下新建“led.s”的汇编文件,如图 2所示:
然后使用“vi led.s”命令打开led.s文件,在led.s文件输入如下代码:
1 .global _start /* 全局标号 */
2 /*
3 * _start函数,程序从此函数开始执行此函数完成时钟使能、
4 * GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
5 */
6 _start:
7 /* 1、使能所有时钟 */
8 ldr r0, =0X020C4068 /* CCGR0 */
9 ldr r1, =0XFFFFFFFF
10 str r1, [r0]
11 ldr r0, =0X020C406C /* CCGR1 */
12 str r1, [r0]
13 ldr r0, =0X020C4070 /* CCGR2 */
14 str r1, [r0]
15 ldr r0, =0X020C4074 /* CCGR3 */
16 str r1, [r0]
17 ldr r0, =0X020C4078 /* CCGR4 */
18 str r1, [r0]
19 ldr r0, =0X020C407C /* CCGR5 */
20 str r1, [r0]
21 ldr r0, =0X020C4080 /* CCGR6 */
22 str r1, [r0]
23 /* 设置GPIO1_IO03为GPIO模式 */
24 ldr r0, =0X020E0068 /* 把寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */
25 ldr r1, =0X5 /* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */
26 str r1,[r0]
27 /* 配置GPIO1_IO03的IO属性
28 *bit 16:0 HYS关闭
29 *bit [15:14]: 00 默认下拉
30 *bit [13]: 0 kepper功能
31 *bit [12]: 1 pull/keeper使能
32 *bit [11]: 0 关闭开路输出
33 *bit [7:6]: 10 速度100Mhz
34 *bit [5:3]: 110 R0/6驱动能力
35 *bit [0]: 0 低转换率
36 */
37 ldr r0, =0X020E02F4 /*寄存器SW_PAD_GPIO1_IO03_BASE */
38 ldr r1, =0X10B0
39 str r1,[r0]
40 /* 设置GPIO1_IO03为输出 */
41 ldr r0, =0X0209C004 /*寄存器GPIO1_GDIR */
42 ldr r1, =0X0000008
43 str r1,[r0]
44 /* 点亮LED0
45 * 设置GPIO1_IO03输出低电平
46 */
47 ldr r0, =0X0209C000 /*寄存器GPIO1_DR */
48 ldr r1, =0
49 str r1,[r0]
50 /*
51 * 描述: loop死循环
52 */
53 loop:
54 b loop
第2行我们定义了全局标号_start,程序就是从_start标号处开始顺序往下执行的。
第8行使用ldr向寄存器r0写入 0x020c4068,这是CCM_CCGR0的寄存器地址。
第9行使用ldr向寄存器r1写入0xffffffff,开启所有外设的时钟。
第10行使用str命令把r1中的值写到r0所保存的地址中,相当于给0x20c4068这个地址写入0xffffffff,也就是CCM_CCGR0寄存器设置成0xffffffff,使能CCM_CCGR0寄存器控制的所有外设时钟。
第11行到第22行是向CCM_CCGR1-CCM_CCGR6寄存器写入0xffffffff,使能所有的外设时钟。
第24行到第26行是设置GPIO1_IO03这个IO为GPIO模式,GPIO1_IO03的复用寄存器是0x20e0068,把该寄存器的MUX_MODE设置为5(GPIO模式)
第37行到第39行设置GPIO1_IO03的IOMUX_SW_PAD_CTL_PAD_GPIO1_IO03配置寄存器
第40行到第43行是设置GPIO为输出功能。
第47到第49是设置GPIO输出0(低电平)
第53到第54行是死循环,使用b跳转指令,程序不断的跳转到loop执行。