最近在研究STM32，看了一段洋桃电子的教学视频感觉还不错，就买了开发板回来折腾。但是在看视频刚刚看到代码的时候我就产生了大量的疑惑，因为视频里并没有一开始就上来写代码，而是对已经写好的代码进行讲解。他们写好的代码里已经做了很多封装抽象，比如sys.h，led.h都不是官方固件库里有的，其中有大量的宏定义，我认为这增加了学习的难度，因为宏是你自己定义的，方便自己用的，给别人用还需要一定的学习记忆，对本质代码的理解很不直观。因此我又看了其他厂商如正点原子、野火的一些视频，基本都是一个样。还在网上阅读了各种使用寄存器操作的所谓“最简”代码。最后我阅读了《STM32固件库用户手册》，自己实现了点LED灯的最简代码。构建Project对于工程的构建大家基本上都是一样的，固件库压缩包里的Library(库)文件夹才是本体。下面列出它的文件目录树：├─CMSIS │ ├─CM3 │ │ ├─//CoreSupport -- CMSIS │ │ └─DeviceSupport │ │ └─ST │ │ └─//STM32F10x -- CMSIS │ │ └─startup │ │ ├─//arm -- STARTUP │ │ ├─gcc_ride7 │ │ ├─iar │ │ └─TrueSTUDIO │ └─Documentation └─//STM32F10x_StdPeriph_Driver -- LIB ├─inc └─src其中标注//的目录下含有.h、.c、.s后缀的C/汇编源码文件，一般需要将其单独复制出来，建立一个工程模板方便使用。单独复制出来有三个文件夹：CMSIS、LIB、STARTUP，实际上还需建立一个放我们自己代码的文件夹——User，ST公司对此提供了一个工程模板，并不在Library中，而是在固件库压缩包的Project-->STM32F10x_StdPeriph_Template文件夹中。我们仅需复制其中的main.c、stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h即可。之后我们在keil5里新建工程，导入这几个文件夹即可，如下图所示： 编译设置导入文件后需要做一些编译设置，点击工具栏上的魔术棒按钮，如下图设置： Define编辑框内设置：STM32F10X_MD,USE_STDPERIPH_DRIVER Include Paths编辑框内设置：.\CMSIS;.\LIB\inc;.\USER输出设置，如下图： 编写代码准备工作首先需要清空main.c，加入如下最简的代码，编译构建一遍看是否出错，若出错需检查上一步骤：#include "stm32f10x.h" int main() { while(1) { } } 若无错误就可以开始对照《STM32固件库用户手册》进行编程啦。我的开发板上的LED灯电路比较简单，如下图所示：LED1接在PB0上，LED2接在PB1上，PB实际上是GPIO口（标准IO口）。初始化引脚在固件库的用户手册中提到，操作引脚必须先对其进行初始化，在手册中第2.3节提到了具体的代码编写方法： 我总结了一下以上内容大概是：假设外设接口叫PPP，首先要声明一个PPP_InitTypeDef类型的名为PPP_InitStructure结构体，然后对结构体的参数进行设置（不同外设接口参数不一样），最后使用PPP_Init函数初始化外设。此外，需要记住的是，在初始化外设之前还需要初始化时钟，可使用RCC_AHBPeriphClockCmd、RCC_APB2PeriphClockCmd、RCC_APB1PeriphClockCmd函数操作。而我的LED灯接在GPIO口上，自然需要查阅初始化GPIO的一些函数。翻一翻用户手册的目录，我直接找到了目录中的GPIO_Init函数，其中对其参数介绍非常详细，读者可自行查阅。由此便可以写出初始化的代码了：void LED_Init() { //把GPIOB的时钟初始化了 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //设定好GPIO初始化的参数 GPIO_InitTypeDef LED_InitStructure; LED_InitStructure.GPIO_Pin = GPIO_Pin_0; //第0脚 LED_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHz最大速度 LED_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式 //执行初始化 GPIO_Init(GPIOB, &LED_InitStructure); //GPIOB组引脚 }点亮LED编写点亮LED的代码之前，需要在main函数中执行我们上面写好的初始化代码。//在while死循环前加入 LED_Init();下一步便是点亮LED了，由我的电路可知，要给引脚输出高电平才能点亮LED。再次查阅手册，发现GPIO_SetBits函数可以很好地实现这个功能。于是在main函数中加入如下代码：//在while循环中加入 GPIO_SetBits(GPIOB, GPIO_Pin_0);构建，烧录运行，是不是看到效果啦？！总体代码如下，是不是很简单：#include "stm32f10x.h" void LED_Init() { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef LED_InitStructure; LED_InitStructure.GPIO_Pin = GPIO_Pin_0; LED_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; LED_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &LED_InitStructure); } int main() { LED_Init(); while(1) { GPIO_SetBits(GPIOB, GPIO_Pin_0); } }