stm32f407vet6汇编点灯

前言

闲来无事,想不用库点亮led。折腾了一段时间,最后还是点亮了。

环境

  • openocd
  • arm-none-eabi-gcc

点灯

点灯就是配置GPIO,我们现在要配置的GPIO是PD_13。先使能GPIOD的时钟,然后配置PD_13为推挽输出模式,最后拉低PD_13。

查看参考手册。使能GPIOD时钟要配置RCC_AHB1ENR寄存器,寄存器地址为0x40023830,往寄存器写入0x00000008使能GPIOD时钟。往GPIOD对应的GPIOx_MODER寄存器写入0x04000000配置PD_13为输出模式,GPIOx_MODER的偏移地址为0x00,GPIOD的地址为0x40020c00,所以寄存器地址为0x40020c00。最后拉低PD_13,需要往GPIOD的GPIOx_ODR寄存器写入0x00000000,GPIOx_ODR的偏移地址为0x14,同理可得寄存器地址为0x40020c14。

把上面的配置过程写成汇编代码,并保存在led.s文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.syntax unified    
.cpu cortex-m4
.thumb

.text
.word 0x20020000 @堆栈指针MSP初始值
.word _start @PC指针初始值

.global _start
.type _start, %function
_start:
@使能GPIOD时钟
ldr r0, =0x40023830
ldr r1, =0x00000008
str r1, [r0]

@配置GPIOD PIN5为推挽输出模式
ldr r0, =0x40020c00
ldr r1, =0x04000000
str r1, [r0]

@配置GPIOD PIN5为低电平
ldr r0, =0x40020c14
ldr r1, =0x00000000
str r1, [r0]

然后编译:

1
2
arm-none-eabi-gcc -c led.s -o led.o
arm-none-eabi-ld -Ttext 0x08000000 led.o -o led.elf

最后使用openocd烧录程序:

1
openocd -f interface/cmsis-dap.cfg -f target/stm32f4x.cfg -c init -c halt -c "program led.elf verify reset exit" -c reset

可以看到led灯成功被点亮。