1、环境
(1)原理图:PB1引脚控制LED灯。
(2)IDE:Keil MDK
(3)MCU:STM32F429IGT6
(3)目标:从零开始编写LED闪烁程序。
2、GPIO控制相关的寄存器
(1)通过查阅芯片参考手册的存储器映射,获取相应模块的基地址。
- RCC基地址:0x40023800
- GPIOB基地址:0x40020400

(2)GPIOB时钟使能的寄存器:0x40023800 + 0x30

(3)GPIO配置为输出模式的寄存器:0x40020400 + 0x00

(4)GPIO输出0/1寄存器:0x40020400 + 0x18

3、编写程序
3.1、创建工程
(1)创建空工程,选择新品型号即可。
(2)创建main.c文件和start.s文件。

3.2、main.c文件
(1)通过指针读写各个寄存器,实现LED闪烁。
void delay(int i);
int main()
{
unsigned int *pReg;
/*使能GPIOB*/
pReg = (unsigned int *)(0x40023800 + 0x30);
*pReg |= (0x01 << 1);
/*配置PB1为输出模式*/
pReg = (unsigned int *)(0x40020400 + 0x00);
*pReg |= (0x01 << 2);
pReg = (unsigned int *)(0x40020400 + 0x18);
while(1)
{
*pReg |= (0x01 << 1); /*PB1输出1*/
delay(1000000);
*pReg |= (0x01 << 17); /*PB1输出0*/
delay(1000000);
}
}
void delay(int i)
{
while(i--);
}
3.3、start.s文件
; 架构配置指令
PRESERVE8 ; 强制8字节堆栈对齐(符合AAPCS标准,确保函数调用时堆栈指针保持8字节对齐)
THUMB ; 声明使用Thumb-2指令集(16/32位混合模式,代码密度与性能平衡方案)
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY ; 定义只读数据段,存放中断向量表
EXPORT __Vectors ; 导出向量表符号供外部链接
__Vectors DCD 0 ; [0x00] 初始堆栈指针值(复位后CPU自动加载到SP)
DCD Reset_Handler ; [0x04] 复位向量 - 指向复位处理程序
; 代码段定义
AREA |.text|, CODE, READONLY
; 复位处理程序(系统启动入口点)
Reset_Handler PROC
EXPORT Reset_Handler [WEAK] ; 弱导出(允许其他模块覆盖实现)
IMPORT main ; 声明外部引用main()函数(C代码入口)
LDR SP, =(0x20000000+0x30000) ; 初始化堆栈指针(必须为复位后首要操作)
BL main ; 调用main()函数
ENDP ; 结束过程定义
END ; 结束汇编模块
4、ROM大小和RAM大小和起始地址
