STM32裸机编程指南-5
系列目录
- STM32裸机编程指南-1,存储和寄存器相关知识
- STM32裸机编程指南-2,更易读的外设寄存器编程
- STM32裸机编程指南-3,启动代码和向量表
- STM32裸机编程指南-4,Makefile构建自动化
- STM32裸机编程指南-5,闪烁LED
- STM32裸机编程指南-6,用SysTick中断实现闪烁
- STM32裸机编程指南-7,添加串口调试输出
- STM32裸机编程指南-8,重定向
printf()
到串口 - STM32裸机编程指南-9,用Segger Ozone进行调试
- STM32裸机编程指南-10,供应商CMSIS头文件
- STM32裸机编程指南-11,配置时钟
- STM32裸机编程指南-12,带设备仪表盘的网络服务器
闪烁LED
现在我们已经搭建好了完整的构建、烧写的基础设施,是时候让固件做点儿有用的事情了。什么是有用的事情?当然是闪烁LED了!Nucleo-F429ZI开发板有3颗LED,在开发板数据手册的6.5节,我们可以看到板载LED连接的引脚:
- PB0: green LED
- PB7: blue LED
- PB14: red LED
再次修改 main.c
文件,添加上引脚定义,然后把蓝色LED引脚设为输出模式,开始无限循环。首先,把我们之前讨论过的GPIO定义和模式设置拷贝过来,注意,现在又新加了一个 BIT(position)
工具宏:
1 |
|
某些微控制器在上电时会把所有外设都自动使能,然而,STM32微控制器在上电时外设是默认关闭的,以降低功耗。为了使能GPIO外设,我们需要通过RCC单元使能外设时钟。在芯片数据手册7.3.10节,可以找到AHB1ENR寄存器与此相关,还是先定义整个RCC单元:
1 | struct rcc { |
在AHB1ENR寄存器文档中可以看到0-8位控制GPIOA - GPIOI的时钟:
1 | int main(void) { |
接下来需要做的就是找到如何开关GPIO引脚,然后在主循环中点亮LED,延时,熄灭LED,延时。在芯片数据手册8.4.7节,可以看到BSRR寄存器与设置电压高低有关,低16位设置ODR寄存器输出高,高16位设置ODR寄存器输出低。为此定义一个API函数:
1 | static inline void gpio_write(uint16_t pin, bool val) { |
下一步我们需要实现一个延时函数,目前还不需要精确延时,所以定义一个 spin()
函数,执行NOP指令给定的次数:
1 | static inline void spin(volatile uint32_t count) { |
最后,修改主循环来让LED闪烁起来:
1 | for (;;) { |
执行 make flash
来看蓝色LED闪烁吧!
完整工程源码可以在 step-1-blinky 文件夹找到。