类比于其他的MCU或者微处理器来说,首先学习的是操作GPIO点亮一颗LED灯。通过观察原理图找到与LED灯相关的GPIO口,通过控制GPIO的高低电平即可控制LED的亮灭。只需要该IO口输出低电平即可。
硬件连接
一.STM32初始化示例
以下是一段STM32的GPIO初始化程序:
可以看到STM32的初始化流程包括以下几个步骤:
1.使能端口时钟
2.配置需要使用的引脚
3.配置GPIO的输入输出模式
4.配置GPIO口的速度
5.输出高低电平
二、IMX6ULL初始化流程
作为处理器来说,IMX6ULL的初始化与STM32的初始化极为相似。初始化包括以下几个部分
1.使能时钟
2.IO口复用
3.配置IO的电气属性
4.配置GPIO输入输出
2.1时钟使能
要想使用处理器内部的功能首先得使能内部的时钟。
打开imx6ull的数据手册,找到时钟控制器模块。
里面主要有7个控制时钟的寄存器
CCM Clock Gating Register 是时钟控制器的时钟门寄存器,控制系统时钟的通断,主要由
CCM Clock Gating Register 0~6 七个寄存器控制。这里为了简单,可以将七个时钟寄存器全部置
0xFFFFFFFF
表示时钟全部打开
2.2 IO口复用
由上述的硬件原理图可知,控制LED的IO口为IO3
IO口的复用功能主要在参考手册32章
这里将该寄存器的值设置为0x05表示,复用为GPIO1
2.3 IO口功能配置
由上述的硬件原理图可知,控制LED的IO口为IO3
2.4 GPIO功能配置
这节初始化主要参考数据手册28章,配置GPIO的输入输出模式
这节寄存器众多,只需要关注GPIO_DR 、GPIO_GDIR这两个寄存器即可
GPIO_DR寄存器,数据位寄存器,这个寄存器定义GPIO的输出值,当信号被配置在寄存器中。
读取该寄存器也能获取GPIO电平值。
这里可以将第三位设置为低电平,但是其他的io口都用不上,于是可以全部置0
GPIO方向位,该32位的寄存器,可以控制寄存器的位数,从而控制寄存器的方向。当某一个的值位0时,表示是输出模式,数据为1时表示时输出模式。
输入输出模式的话要设置成输出模式,输出模式才能控制io口的电平
三、汇编程序编写
创建一个名为led.s的文件,在文件中输入以下代码
.global _start @全局标号
_start:
ldr r0, =0x020c4068 /* 向寄存器CCM_CCGR0中写入数据 */
ldr r1, =0xffffffff
str r1, [r0]
ldr r0, =0x020c406c /* 向寄存器CCM_CCGR1中写入数据 */
str r1 , [r0]
ldr r0, =0x020c4070 /* 向寄存器CCM_CCGR2中写入数据 */
str r1 , [r0]
ldr r0, =0x020c4074 /* 向寄存器CCM_CCGR3中写入数据 */
str r1 , [r0]
ldr r0, =0x020c4078 /* 向寄存器CCM_CCGR4中写入数据 */
str r1 , [r0]
ldr r0, =0x020c407c /* 向寄存器CCM_CCGR5中写入数据 */
str r1 , [r0]
ldr r0, =0x020c4080 /* 向寄存器CCM_CCGR6中写入数据 */
str r1 , [r0]
/*配置GPIO1——IO3 */
ldr r0, =0x02e00068
ldr r1, =0x00000005
str r1, [r0]
/* 配置GPIO1_IO03的电气属性
* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
* 寄存器地址 020e02f4
* bit 0 0 低
* bit 5-3 驱动能力
* bit 7-6 速度
* bit 11 ODMODE
* bit 12 1
* bit 13 0
* bit 15-14 上下拉电阻
* bit 16: 0
*/
ldr r0, =0x020e02f4
ldr r1, =0x10b0
str r1, [r0]
ldr r0, =0x0209c004 /*控制GDTR寄存器为输出模式*/
ldr r1, =0x8
str r1, [r0]
ldr r0, =0x0209c000 /*控制DR寄存器输出低电平*/
ldr r1, =0
str r1, [r0]
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-gnueabihf-objdump -D led.elf > led.dis
clean:
rm -rf *.o led.bin led.elf led.dis
Makefile的目标是要生成一个led.bin文件,上述代码中 led.bin为目标文件
led.s为依赖文件。
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
使用交叉编译器编译,其中-g是生成调试信息,-c是编译文件不链接文件。
即 使用交叉编译器编译 led.s文件,产生调试信息,生成led.o文件,且不链接。
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
其中arm-linux-gnueabihf-ld 后面的-ld表示链接文件。-Ttext表示开始的地址。
使用交叉编译器对led.o从0x87800000处开始链接文件,最终生成一个led.elf的链接文件
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
-objcopy表示使用一个objcopy的工具,进行文件格式转换, -O binary 以二进制格式输出
-S 去掉符号表和调试信息 -g保留调试信息。
arm-linux-gnueabihf-objdump -D led.elf > led.dis
-objdump,是一个可以进行反汇编的工具 -D表示所有部分进行反汇编。最终会生成一个led.dis反汇编文件。
五、烧录代码
给烧录器权限
chmod 777 imxdownload
查看是否有SD卡设备
ls /dev/sd*
这样可以看到文件目录下的所有的磁盘信息
我这里的磁盘为sdb,如果不知道磁盘是哪个,可以拔插读卡器来确定。
向sd卡中烧录bin文件,这里要根据自己的sd卡识别的磁盘区域进行读写
./imxdownload led.bin /dev/sdb
烧写完成后,可以看到以下烧录信息
给板子上电后,可以看到led灯亮