Linux 学习记录54(ARM篇)
本文目录
- Linux 学习记录54(ARM篇)
- 一、框图分析
- 1. 芯片手册内部框图
- 2. 操作GPIO过程
- 二、通过汇编完成GPIO操作
- 1. 常用的汇编指令
- 2. GPIO初始化流程
- 3. 查找相关寄存器
- (1. RCC寄存器
- (2. GPIO寄存器
- >1. 模式配置寄存器
- >2. 输出模式配置寄存器
- >3. 速度配置寄存器
- >4. 上下拉配置寄存器
- >5. GPIO输出寄存器
- 4. 寄存器配置示例
- (1. RCC寄存器配置
- (2. GPIO寄存器配置
- 思维导图
- 练习代码
一、框图分析
以STM32MP157为例
1. 芯片手册内部框图
可以看到在STM32MP157A中有三个内核
2个Cortex-A7 以及 一个Cortex-M4
2. 操作GPIO过程
二、通过汇编完成GPIO操作
1. 常用的汇编指令
1、数据操作指令
1>数据搬移指令 mov
2>移位操作指令 lsr lsl asr ror
3>位运算指令 and orr eor bic
4>算数运算指令 add adc sub sbc mul
5>比较指令 cmp
2、跳转指令 b / bl
3、特殊功能寄存器操作指令 msr mrs
4、内存操作指令
1> 单寄存器操作指令 ldr / str
2> 多寄存器操作指令 ldm / stm
3> 栈指针操作指令 stmfd / ldmfd
2. GPIO初始化流程
3. 查找相关寄存器
相关数据手册在文章顶部下载
(1. RCC寄存器
2.5.2
(2. GPIO寄存器
>1. 模式配置寄存器
>2. 输出模式配置寄存器
>3. 速度配置寄存器
>4. 上下拉配置寄存器
>5. GPIO输出寄存器
4. 寄存器配置示例
(1. RCC寄存器配置
@RCC_Init: @RCC时钟初始化 GPIOE
ldr r0,=0x50000A28 @GPIO的RCC地址为0x50000000,E组GPIO需要加上0x0A28的偏移量,上面图片的RCC寄存器可查
ldr r1,[r0] @将0x50000A28寄存器的地址中的数据读出
orr r1,r1,#(0X1<<4) @将E组的GPIO使能位置1
str r1,[r0] @重新写入寄存器中
(2. GPIO寄存器配置
@LED_Init: @LED的GPIO初始化
@初始化GPIOE 8-10
ldr r0,=0x50006000 @GPIOE模式 基地址
ldr r1,[r0] @当前寄存器数据
and r1,r1,#(~(0x3<<16)) @将要修改的位先清零
orr r1,r1,#(0x1<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@输出配置
ldr r0,=0x50006004 @GPIOE输出 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x1<<8) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@速度配置
ldr r0,=0x50006008 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x3<<16) @将要修改的位先清零
orr r1,r1,#(0x1<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@上下拉配置
ldr r0,=0x5000600c @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x3<<16) @将要修改的位先清零
orr r1,r1,#(0x1<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@将该引脚设置为高电平
ldr r0,=0x50006014 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
orr r1,r1,#(0x1<<8) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
思维导图
练习代码
.text
.global _start
_start:
bl Init
mov r5,#0
loop:
bl LED_ON
bl delay_1s
bl LED_OFF
bl delay_1s
cmp r5,#10
add r5,r5,#1
bls loop
Init:
@RCC_Init: @RCC时钟初始化
ldr r0,=0x50000A28
ldr r1,[r0]
orr r1,r1,#(0X3<<4)
str r1,[r0]
@LED_Init: @LED的GPIO初始化
@初始化GPIOE 8-10
ldr r0,=0x50006000 @GPIOE模式 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x33<<16)
orr r1,r1,#(0x11<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@输出配置
ldr r0,=0x50006004 @GPIOE输出 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x5<<8) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@速度配置
ldr r0,=0x50006008 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x33<<16) @重新赋值参数到r1寄存器
orr r1,r1,#(0x11<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@上下拉配置
ldr r0,=0x5000600c @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x33<<16) @重新赋值参数到r1寄存器
orr r1,r1,#(0x11<<16) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@初始化GPIOF 10
ldr r0,=0x50007000 @GPIOE模式 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x3<<20)
orr r1,r1,#(0x1<<20) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@输出配置
ldr r0,=0x50007004 @GPIOE输出 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x1<<10) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@速度配置
ldr r0,=0x50007008 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x3<<20) @重新赋值参数到r1寄存器
orr r1,r1,#(0x1<<20) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
@上下拉配置
ldr r0,=0x5000700c @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x3<<20) @重新赋值参数到r1寄存器
orr r1,r1,#(0x1<<20) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
mov pc,lr
LED_ON:
ldr r0,=0x50006014 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
orr r1,r1,#(0x5<<8) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
ldr r0,=0x50007014 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
orr r1,r1,#(0x1<<10) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
mov pc,lr
LED_OFF:
ldr r0,=0x50006014 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x5<<8) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
ldr r0,=0x50007014 @GPIOE速度 基地址
ldr r1,[r0] @当前寄存器数据
bic r1,r1,#(0x1<<10) @重新赋值参数到r1寄存器
str r1,[r0] @设置GPIO 参数到模式寄存器
mov pc,lr
@ 大概1s的延时函数
delay_1s: @延时函数
mov r3, #0x10000000
mm:
cmp r3, #0
subne r3, r3, #1
bne mm
mov pc, lr
.end