2.2 新建工程
一、STM32 开发方式
基于寄存器开发:通过程序直接配置寄存器实现功能,这种方式底层且高效,但因 STM32 结构复杂、寄存器繁多,开发难度较大,目前较少采用。
基于标准库(库函数)开发:ST 官方提供封装好的函数,开发者通过调用函数间接配置寄存器,该方式对开发者友好,能有效提高开发效率,本文重点介绍此开发方式。
基于 HAL 库开发:借助图形化界面快速配置 STM32,适合初学者快速上手,但该方式隐藏底层逻辑,若对 STM32 不够熟悉,开发水平易受限,建议在掌握标准库后再学习。
二、基于库函数的 STM32 工程搭建步骤
2.1 准备工作
使用库函数开发,需准备 STM32 库函数压缩包,可从课程资料链接获取,路径为 固件库/STM32F10x_StdPeriph_Lib_V3.5.0.zip。
解压后,文件夹包含:库函数文件 Libraries、官方工程示例和模板 Project、评估板例程 Utilities、发布文档 Release_Notes.html、和使用手册 stm32f10x_stdperiph_lib_um.chm,这些资料对开发非常具有参考价值。

2.2 工程创建
创建工程文件夹:在磁盘(如 D 盘、E 盘或桌面)创建存放工程的文件夹,如
STM32Project,便于统一管理工程。新建工程:打开 Keil MDK - ARM 软件,依次点击
Project->New μVision Project,选择新建文件夹并命名为STM32Project,再创建用于存放本次工程的子文件夹,如2 - 1 STM32 工程模板。进入该子文件夹,为工程文件命名,如Project,然后保存。选择器件型号:依据芯片型号 STM32F103C8T6,在弹出窗口中选择
STM32F103C8,点击OK。此时弹出的新建工程小助手,可以帮助快速新建工程,目前暂时用不到,可以先关闭,此时工程虽然已经创建,但没有实质文件,还不能使用。
2.3 添加工程必要文件
添加启动文件: 进入固件库文件夹
Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm复制所有文件。回到工程模板文件夹,新建Start文件夹,将启动文件粘贴其中。相关信息
启动文件是程序执行的起始点。
添加其他文件:
- 在固件库位于
Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x文件夹中,复制stm32f10x.h和两个system开头的文件到Start文件夹。 - 此外,再从
CM3\CoreSupport复制两个cm3文件到Start文件夹。
相关信息
stm32f10x.h用于描述 STM32 外设寄存器及地址;两个system文件负责配置时钟,STM32 的 72 兆赫兹主频由此配置。core_cm3.h(Cortex-M3) 文件包含了对内核寄存器的描述;core_cm3.c包含了内核的配置函数。
- 在固件库位于
文件添加到工程:在 Keil 软件中,将左侧栏的
Target下的Source Group 1重命名为Start,右键选择Add Existing Files to Group'Start'。在Start文件夹中,选择文件类型All files,先添加与芯片型号对应的启动文件(如 STM32F103C8T6 选md.s,详见 4.1 启动文件选择 ),再按住Ctrl选择所有的.c和.h文件,点击Add添加文件。

相关信息
这些文件为 STM32 基础文件,不需要修改,文件右上角的钥匙标志代表只读。
- 添加头文件路径:点击 Keil 软件的魔术棒按钮,打开工程选项,在
C/C++选项卡中找到Include Paths栏,点击右侧三点按钮新建路径,添加Start文件夹路径并点击OK,确保软件能找到头文件。

2.4 新建main函数测试工程
在工程文件夹中新建
User文件夹存放 main 函数。回到 Keil 软件,在
Target处右键点击Add Group,命名为User。右键点击
Add New Item to Group 'User',选择C File,命名为main.c,选择User文件夹路径后点击Add。在
main.c中右键选择insert '#include file'插入头文件stm32f10x.h,编写包含while (1)死循环的 main 函数。#include "stm32f10x.h" // Device header int main(void) { while(1) { } }注意
需注意,文件末尾需留空行,否则会报警告。
点击 Build 按钮或按 F7 进行编译,若提示
0 Error(s), 0 Warning(s),说明工程初步搭建成功。此时工程未添加库函数,只能基于寄存器开发。
注意
为了避免中文乱码需要设置解码为UTF-8。
点击设置按钮,在左侧的 Encoding 一栏,选择 Encode in UTF-8 without signature。
2.5 配置调试器与下载程序
- 硬件连接:使用 STM32 最小系统板、ST - Link 和四根母对母杜邦线,按照下方图片连接 3.3V、SWDIO、SWCLK、GND。连接 ST - Link 到电脑并通电,此时板子电源灯应常亮,PC13 口连接的灯因芯片测试程序应闪烁。

配置调试器:在 Keil 软件中点击魔术棒按钮,选择
Debug,将调试器由默认的ULink改为ST - Link Debugger。
点击右侧
Settings,在Debug的Port选择SW。
在
Flash Download勾选Reset and Run,方便下载程序后自动复位执行。
配置完成后确认,重新编译无错误后点击
Load按钮,程序即可下载到 STM32。
此时由于没有编写任何代码, PC13 口灯不亮。
2.6 配置寄存器实现点灯操作
使能 GPIOC 时钟:查阅
STM32入门教程资料\参考文档\STM32F10xxx参考手册(中文).pdf,在 RCC 的 APB2 外设时钟使能寄存器RCC_APB2ENR中配置,将IOPCEN位置 1(其余无关位先置 0),16 进制值为0x00000010。在while (1)前添加RCC->APB2ENR = 0x00000010;,开启 GPIOC 时钟。
二进制转换为十六进制,每四个数据为一组 配置 PC13 口模式:找到端口配置高寄存器
GPIOx_CRH(x 为 A - G 字母),将 PC13 口配置为通用推挽输出模式,CNF13和MOD13四位设为0011,其余位设为 0,16 进制值为0x00300000。在while (1)前添加GPIOC->CRH = 0x00300000;。
PC13 口输出数据:利用端口输出数据寄存器
GPIOx_ODR,ODR13位写 1 时 PC13 口为高电平,写 0 为低电平。因灯低电平点亮,ODR = 0x00000000灯亮,ODR = 0x00002000灯灭。
代码
在 Keil 软件中分别赋值编译下载,观察灯的状态。#include "stm32f10x.h" // Device header int main(void) { RCC->APB2ENR = 0x00000010; GPIOC->CRH = 0x00300000; GPIOC->ODR = 0x00000000; //灯亮,更改为0x00002000后灯灭 while(1) { } }
2.7 添加库函数到工程
新建文件夹:在工程文件夹中新建
Library文件夹用于存放库函数。复制库函数文件:进入固件库
Libraries\STM32F10x_StdPeriph_Driver\src文件夹,全选复制到library文件夹。再进入inc文件夹,全选头文件复制到library文件夹。添加到工程:在 Keil 软件
Target处右键添加组,命名为Library,右键选择Add Existing Files to Group 'Library',选择文件类型All files,全选Library文件夹文件后点击Add。添加其他文件:从固件库
Project\STM32F10x_StdPeriph_Template文件夹复制stm32f10x_conf.h和两个it结尾文件到工程User文件夹下,在 Keil 软件右侧User组中添加这三个文件。相关信息
stm32f10x_conf.h用于配置库函数头文件的包含关系,其包含所有库函数头文件。- 两个
it(interrupt) 结尾的文件用于中断服务函数。
宏定义与路径配置:打开
stm32f10x_conf.h,可以找到如下代码:#ifdef USE_STDPERIPH_DRIVER #include "stm32f10x_conf.h" #endif这是一个条件编译,当定义了
USE_STDPERIPH_DRIVER字符串时,才会包含stm32f10x_conf.h文件。在工程选项
C/C++的Define栏写入USE_STDPERIPH_DRIVER,实现对标准外设库的包含。同时在Include Paths栏添加User和Library文件夹路径,点击OK,完成基于库函数的工程搭建。
编译工程,若零错误零警告,则工程搭建成功。
三、使用库函数实现点灯操作
使用库函数间接配置寄存器实现点灯,步骤与配置寄存器相似,但代码更简洁:
使能时钟:调用库函数
RCC_APB2PeriphClockCmd(),第一个参数选外设(如RCC_APB2Periph_GPIOC),第二个参数选状态(如ENABLE)。通过右键查看函数定义和参数说明,完成 GPIOC 外设时钟配置。配置端口模式:使用
GPIO_Init()函数,第一个参数选 GPIO(如GPIOC),第二个参数为结构体。先定义结构体变量,根据结构体参数(GPIO_Mode、GPIO_Pin、GPIO_Speed),通过右键跳转查看定义和说明进行配置,最后将结构体变量地址作为第二个参数传入函数,完成端口模式配置。设置端口电平:用
GPIO_SetBits()函数将指定端口置高电平,GPIO_ResetBits()函数置低电平。分别调用函数,传入GPIOC和GPIO_Pin_13参数,注释其中一个函数测试灯的亮灭。代码:
#include "stm32f10x.h" // Device header int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC, GPIO_Pin_13); //设置为低电平,灯亮 //GPIO_SetBits(GPIOC, GPIO_Pin_13); //设置为高电平,灯灭 while(1) { } }警告
编译如果如果出现错误
error: #268: declaration may not appear after executable statement in block,是因为 C90 标准,声明不能在执行语句之后,可以在魔术棒中的C/C++中勾选C99 Mode,或者更改代码顺序。
四、补充知识
4.1 启动文件选择
| 缩写 | 释义 | Flash容量 | 型号 |
|---|---|---|---|
| LD_VL | 小容量产品超值系列 | 16~32K | STM32F100 |
| MD_VL | 中容量产品超值系列 | 64~128K | STM32F100 |
| HD_VL | 大容量产品超值系列 | 256~512K | STM32F100 |
| LD | 小容量产品 | 16~32K | STM32F101/102/103 |
| MD | 中容量产品 | 64~128K | STM32F101/102/103 |
| HD | 大容量产品 | 256~512K | STM32F101/102/103 |
| XL | 加大容量产品 | 大于512K | STM32F101/102/103 |
| CL | 互联型产品 | / | STM32F105/107 |
4.2 新建工程步骤总结
建立工程文件夹,在 Keil 中新建工程并选择型号。
在工程文件夹创建 start、library、user 等文件夹,复制固件库文件到工程文件夹,确保工程独立性。
在工程中创建同名分组,将文件夹内文件添加到分组,可选择添加所有 .h 和 .c 文件。
在工程选项 C/C++ 的 Include Paths 栏声明头文件路径。
在 C/C++ 的 Define 栏定义 USE_STDPERIPH_DRIVER 字符串。
在 Debug 下拉列表选择调试器(如 ST - Link 选 ST - Link Debugger),在 Flash Download 勾选 Reset and Run。
4.3 工程架构解析

启动文件:用汇编编写,定义中断向量表和中断服务函数,复位中断为程序入口。STM32 复位时,程序进入复位中断函数,调用 system_init() 函数和 main() 函数,system_init() 函数位于 system 开头的 .c 文件,用于初始化微控制器。
中断函数:启动文件定义 STM32 其他中断,中断函数定义在 STM32F10x_it.c 文件,ST 建议将自定义中断写在此处,也可写在其他位置。
寄存器描述文件:stm32f10x.h 和 core_cm3.h 等为外设和内核寄存器描述文件,直接调用寄存器开发为基于寄存器开发方式。
库函数文件:库函数文件封装寄存器操作,提供人性化函数调用方式,熟悉操作套路后配置外设更简便。
conf 文件:stm32f10x_conf.h 配置头文件包含关系,其包含所有库函数头文件,stm32f10x.h 又包含 conf.h,因此使用库函数时只需包含 stm32f10x.h 即可调用所有库函数。
