上一部分我们已经整理出了所需寄存器的基地址、初始值,因为我们要给寄存器赋值,其实就是向指定地址写入内容。下面所有用到的基地址和初始化值都在上一篇总结好了。
目录
一、编写汇编代码
汇编代码对应的是 .s 文件,每个 .s 文件都是以 _start 开头,所以汇编代码的起始模板为:
.global _start
_start:
/* 开始编写汇编代码 */
1、使能外设时钟
上一篇《使能外设时钟》的末尾已经列举了哪些寄存器是需要被初始化的,以及初始化的值是多少,全都一一列举了。一共有 7 个时钟源,每个时钟源的基地址之间相差 4 个字节,初始化的值都是 0xFFFFFFFF。下面给出两种写法

写法一:循环初始化
.global _start
/*
* 描述: _start函数,程序从此函数开始执行此函数完成时钟使能、
* GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
*/
_start:
/* 时钟源初始化 */
ldr r1, =0x020C4068 @ 保存 CCGR0 寄存器基地址到寄存器 r1
ldr r2, =0xFFFFFFFF @ 保存初始值到寄存器 r2
mov r3, #7 @ r3 = 7, 七个时钟源,初始化七次
bl init @ 跳转到 init,lr 寄存器会保存下一条指令的地址
init:
cmp r3, #0 @ 判断 r3 寄存器是否为 0
moveq pc, lr @ lr 寄存器保存了回去的地址,如果 r3 == 0,说明已经初始化了7次
strgt r2, [r1], #4 @ 如果 r3 大于0,将 r2 寄存器的内容保存到 r1,然后 r1 自增4
sub r3, r3, #1 @ r3 寄存器自减
b init
写法二:暴力初始化
.global _start
/*
* 描述: _start函数,程序从此函数开始执行此函数完成时钟使能、
* GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。
*/
_start:
/* 1. 使能所有时钟 */
ldr r1, =0X020C4068 /* CCGR0 */
ldr r2, =0XFFFFFFFF
str r2, [r1]
ldr r1, =0X020C406C /* CCGR1 */
str r2, [r1]
ldr r1, =0X020C4070 /* CCGR2 */
str r2, [r1]
ldr r1, =0X020C4074 /* CCGR3 */
str r2, [r1]
ldr r1, =0X020C4078 /* CCGR4 */
str r2, [r1]
ldr r1, =0X020C407C /* CCGR5 */
str r2, [r1]
ldr r1, =0X020C4080 /* CCGR6 */
str r2, [r1]
2、设置 IO 复用
基地址和初始化值:

/* 2. 设置IO复用 */
ldr r1, =0x20E0068
ldr r2, =0x5 @ 指定为 GPIO 功能
str r2, [r1]
3、初始化复用引脚(设置电气属性)
基地址和初始化值:

/

本文详细介绍了如何使用汇编代码驱动LED,包括使能外设时钟、设置IO复用、初始化GPIO等步骤,并展示了两种不同的时钟源初始化方法。同时,文章还涵盖了编译汇编代码的完整过程,包括生成.o文件、链接、格式转换和反汇编。最后,提到了选择0x87800000作为运行地址的原因,并说明了烧写到SD卡的步骤。
https://blog.youkuaiyun.com/challenglistic/article/details/131047800?spm=1001.2014.3001.5501
最低0.47元/天 解锁文章
1317

被折叠的 条评论
为什么被折叠?



