Professional Documents
Culture Documents
实验手册
推荐关注我们的公众号获取更新资料
版本说明:
版本 日期 内容说明
V1.0 2020/07/04 第一次发布
V2.0 2021/10/27 文档模板更新
网址:www.wheeltec.net
序言
本实验手册是 STM32 单片机的入门教程,从点亮 LED 灯到读取 ADC,一
步步指导大家进行学习,且每一个例程讲的都是实用性很强的功能,是大部分项
目都必须用到的功能。本实验手册基于 STM32F103C8T6 芯片,提供全套源码、
原理图、芯片资料及全套软件工具。
本实验手册共有 11 节,分别是新建工程、点亮 LED、按键控制 LED、串口
通信、外部中断、定时中断、定时器的 PWM 输出模式、PWM 输出控制舵机、
定时器的输入捕获模式、定时器的编码器模式、ADC 采集。
目录
序言 ............................................................................................................. 2
1. 新建工程 ................................................................................................ 6
1.1 新建工程及相关文件准备 ................................................................... 6
1.2 添加官方库和 HEX 文件设置 ........................................................... 10
1.3 添加 delay、sys 和 usart 库 ................................................................26
1.4 配置简体中文环境 ............................................................................. 31
2. 点亮 LED ............................................................................................. 33
2.1 相关 IO 介绍 ....................................................................................... 33
2.2 创建硬件外设库函数文件并加入工程 ............................................. 33
2.3 编写硬件外设库函数 ......................................................................... 39
2.4 查看函数定义、声明及入口变量 ..................................................... 43
2.5 编写主函数 ......................................................................................... 49
2.6 上传程序到 STM32F103C8T6 核心板 ..............................................50
2.7 实现思路及效果 ................................................................................. 54
2.8 本节知识要点 ..................................................................................... 55
4. 串口通信 .............................................................................................. 63
4.1 相关 IO 介绍 ....................................................................................... 63
4.2 准备工作 ............................................................................................. 63
4.3 编写串口通信 1 初始化函数 ............................................................. 64
4.4 编写串口通信 1 中断函数 ................................................................. 66
4.5 编写主函数 ......................................................................................... 68
4.6 实现思路、串口调试助手软件的使用及程序效果 ......................... 68
4.7 本节知识要点 ..................................................................................... 70
5. 外部中断 .............................................................................................. 72
5.1 相关 IO 介绍 ....................................................................................... 72
5.2 创建工程与外部中断库文件 ............................................................. 72
5.3 编写外部中断库函数 ......................................................................... 73
5.4 编写主函数 ......................................................................................... 76
5.5 实现思路及效果 ................................................................................. 76
5.6 本节知识要点 ..................................................................................... 77
6. 定时中断 .............................................................................................. 78
6.1 相关 IO 介绍 ....................................................................................... 78
6.2 创建工程与定时中断库文件 ............................................................. 78
6.3 编写定时中断库函数 ......................................................................... 78
6.4 编写主函数 ......................................................................................... 81
6.5 实现思路及效果 ................................................................................. 82
6.6 本节知识要点 ..................................................................................... 82
9. 定时器的输入捕获模式 ......................................................................93
9.1 相关 IO 介绍 ....................................................................................... 93
9.2 编写定时器输入捕获库函数 ............................................................. 93
9.3 编写主函数 ......................................................................................... 99
9.4 实现思路及效果 ................................................................................. 99
9.5 本节知识要点 ................................................................................... 100
1.1新建工程及相关文件准备
1 创建项目与相关文件夹
新建一个文件夹【NewProject】,用于保存工程库文件,同时在文件夹
【NewProject】下创建一个文件夹【USER】。
图 1-1-1 创建文件夹
图 1-1-2 新建项目
第 6 页 共 114 页
在第一步新建的文件夹【NewProject】下的文件夹【USER】下创建工程文
件,文件名为【NewProject】,点击【保存】。
图 1-1-3 在【USER】文件夹下保存工程【NewProject】
2 选择工程芯片
图 1-1-4 选择芯片型号
第 7 页 共 114 页
点击【Cancel】。
图 1-1-5 点击取消
3 复制相关库文件
在文件夹【NewProject】下新建三个文件夹【CORE】、【OBJ】、
【STM32F10x_FWLib】,文件夹【CORE】用来存放核心文件和启动文件,
【OBJ】
是用来存放编译过程文件以及 hex 文件,文件夹【STM32F10x_FWLi】用来存
放 STM 官方提供的库函数源码文件。
图 1-1-6 新建文件夹
第 8 页 共 114 页
复制文件夹【inc】、【src】到文件夹【STM32F10x_FWLib】下,您可以直
接到我们提供的工程模板下复制。【inc】、【src】是官方固件库包,其中【inc】
内是.h 头文件,【src】是.c 源文件。
图 1-1-7 复制文件
复制文件【core_cm3.c】、【core_cm3.h】、【startup_stm32f10x_hd.s】到文
件夹【CORE】下,您可以直接到我们提供的工程模板下复制。其中【core_cm3.c】、
【core_cm3.h】为核心文件,【startup_stm32f10x_hd.s】为启动文件,启动文件
除了【startup_stm32f10x_hd.s】外还有【startup_stm32f10x_ld.s】和
【startup_stm32f10x_md.s】,三者适用与不同容量的 STM32 芯片。
【startup_stm32f10x_ld.s】适用与小容量(FLASH 的大小≤32K)的芯片,
【startup_stm32f10x_md.s】适用与中容量(64K≤FLASH 的大小≤128K)的芯
片,【startup_stm32f10x_ld.s】适用与大容量(256K≤FLASH 的大小)的芯片。
第 9 页 共 114 页
图 1-1-8 复制文件
复制文件【main.c】、
【stm32f10x.h】、
【stm32f10x_conf.h】、
【stm32f10x_it.c】、
【stm32f10x_it.h】、【system_stm32f10x.c】、【system_stm32f10x.h】到文件夹
【USER】下。
图 1-1-9 复制文件
我们已经将需要的固件库相关文件复制到了我们的工程目录下面,但是我们
还要将这些文件加入工程中去才能使用。右键点击 【Target1】,选择【Manage
Project Items】。
第 10 页 共 114 页
图 1-2-1 选择项目管理器
第 11 页 共 114 页
【Project Targets】一栏,我们将【Target1】重命名为【NewProject】,然后在
【Groups】 一栏删掉【Source Group1】,建立三个 Groups:
【USER】、
【CORE】、
【STM32F10x_FWLib】。点击 OK。可以看到【NewProject】下多了三个子项
目【USER】、【CORE】、【STM32F10x_FWLib】。
图 1-2-2 新建分组【USER】、【CORE】、【STM32F10x_FWLib】
图 1-2-3 分组效果
第 12 页 共 114 页
2 向【USER】分组添加库文件
图 1-2-4 选择项目管理器
选中 Groups【USER】后,点击【Add Files】。
图 1-2-5 向【USER】分组添加文件
第 13 页 共 114 页
选中文件夹【USER】下的【main.c】、
【stm32f10x_it.c】、
【system_stm32f10x.c】,
点击【Add】,然后点击【Close】。可以看见 Groups【USER】下成功添加了 3
个文件。
第 14 页 共 114 页
3 向【CORE】分组添加库文件
选中 Groups【CORE】后,点击【Add Files】。
图 1-2-8 向【CORE】分组添加文件
点击【1】处,返回上一级文件夹,双击文件夹【CORE】,点击【2 处】,
选择【All Files (*.*)】。
图 1-2-9 返回上一级
第 15 页 共 114 页
图 1-2-10 点击进入【CORE】文件夹
图 1-2-11 选择可识别文件类型
第 16 页 共 114 页
选中文件【core_cm3.c】、【core_cm3.h】和【startup_stm32f10x_hd.s】(启
动文件根据芯片 FLASH 大小选择 hd、ld 还是 md),点击【Add】,然后点击
【Close】。
4 向【STM32F10x_FWLib】分组添加库文件
选中 Groups【STM32F10x_FWLib】后,点击【Add Files】。
图 1-2-13 向【STM32F10x_FWLib】分组添加文件
第 17 页 共 114 页
点击【1】处,返回上一级文件夹,双击文件夹【STM32F10x_FWLib】,双
击文件夹【src】。
图 1-2-14 返回上一级文件夹
图 1-2-15 点击进入【STM32F10x_FWLib】文件夹
第 18 页 共 114 页
图 1-2-16 点击进入【src】文件夹
选中该文件夹下的所有文件,点击【Add】,然后点击【Close】。该文件夹
下是外设库文件,如果我们只用到了其中的某个外设,我们可以不添加没有用到
的外设的库文件。例如如果只用 GPIO,则可以只添加 stm32f10x_gpio.c 而其他
的可以不用添加。这里我们全部添加进来是为了后面方便,不用每次添加,这样
做不好的方面是工程太大,编译起来速度慢。
第 19 页 共 114 页
点击【OK】。
图 1-2-18 点击 OK 确认添加源文件
5 编辑 HEX 文件生成路径
第 20 页 共 114 页
图 1-2-20 选择到文件夹【NewProject】下的文件夹【OBJ】,点击 OK
图 1-2-21 点击 OK
第 21 页 共 114 页
6 添加头文件路径
接下来还需要添加头文件所在路径,否则点击 1 处【构建】时会报错,如 2
处。要注意,所有使用到的头文件都必须添加其所在路径进工程。
图 1-2-22 存在报错
点击【魔术棒】,点击【C/C++】,点击 3 处【...】。
第 22 页 共 114 页
点击 1 处,点击 2 处。
分 别 在 在 路 径 【 NewProject\USER 】 、 【 NewProject\CORE 】 、
【NewProject\STM32F10x_FWLib\inc】下点击【选择文件夹】,以设置系统头文
件(.h 文件)所在路径。
图 1-2-25 选择【USER】文件夹
图 1-2-26 选择【CORE】文件夹
第 23 页 共 114 页
图 1-2-27 选择【STM32F10x_FWLib】文件夹
添加头文件设置路径成功,点击【OK】。
第 24 页 共 114 页
7 添加宏定义与编译测试
在【Define】下输入“STM32F10X_MD,USE_STDPERIPH_DRIVER”以添
加宏定义,点击【OK】。注意其中的【STM32F10X_HD】对应大容量:256K≤
FLASH 的 STM 芯片。中容量则应该改为【STM32F10X_MD】,小容量则应该
改为【STM32F10X_LD】。
图 1-2-29 添加宏定义
此时点击 1 处【全部重新构建】,显示运行成功,无错误,无警告。注意
main.c 里的最后一行要为空行,以后建立的所有程序,最后一行都要为空行,否
则会有一个警告,该警告属于 Keil 的 BUG。
图 1-2-30 无报错
第 25 页 共 114 页
1.3添加 delay、sys 和 usart 库
1 添加【.C】文件
经过以上步骤,工程基本完成了,接下来我们在添加几个库函数,方便以后
编写程序。在文件夹【NewProject】下新建文件夹【SYSTEM】,复制文件夹【delay】、
【sys】、【usart】到文件夹【SYSTEM】下,您可以直接到我们提供的工程模
板下复制。
【delay】里面是封装好的延迟函数,【sys】里面是封装好的 IO 口控制函数,
【usart】里面是封装好的串口使用函数。
图 1-3-1 复制粘贴已准备好的库函数
图 1-3-2 选择项目管理器
第 26 页 共 114 页
在【Groups】下新建【SYSTEM】,选中【SYSTEM】后点击【Add Files】。
图 1-3-3 向【SYSTEM】分组添加文件
在路径下【NewProject\SYSTEM\delay】,点击【Add】。
第 27 页 共 114 页
重复类似前面的步骤,将文件夹【sys】下的文件【sys.c】和文件夹【usart】
下的文件【usart.c】都添加进 Groups【SYSTEM】中。点击【OK】。
图 1-3-5 添加源文件【sys.c】、【usart.c】
2 添加对应头文件路径
点击【魔法棒】,点击【C/C++】,点击 3 处【...】。
第 28 页 共 114 页
点击 1 处后点击 2 处【...】。
进入到文件夹【SYSTEM】下的文件夹【delay】下,点击【选择文件夹】,
则将头文件【delay.h】所在的路径添加进了工程。
图 1-3-8 选择【delay】文件夹
重复类似前面两步的步骤,将头文件【sys.h】、【usart.h】所在的路径都添
加进工程。点击 OK。再次点击【OK】。
第 29 页 共 114 页
图 1-3-9 继续添加【sys】、【usart】文件夹路径
图 1-3-10 点击 OK
第 30 页 共 114 页
1.4配置简体中文环境
接下来点击【编辑】,点击【配置】。
图 1-4-1 选择配置
选择【Encoding】下的【Chinese GB2312(Simplified)】,点击【OK】。此处
是为了避免中文注释时出现乱码。
第 31 页 共 114 页
点击 1 处【全部保存】,新建工程完毕。
图 1-4-3 点击 1 处保存全部文件
第 32 页 共 114 页
2. 点亮 LED
2.1相关 IO 介绍
Forest S1 上可控制的 LED 灯有 1 个,为蓝色 LED 灯,受引脚 PA4 控制,
低电平时点亮。
2.2创建硬件外设库函数文件并加入工程
为使工程规范、编程方便,一个好的习惯是为单片机要控制的每一个硬件建
立库函数。接下来我们以上一节创建好的工程为基础,为 LED 灯建立一个库函
数。
1 创建文件夹
首先在文件夹【NewProject】下新建文件夹【HARDWARE】,用于存放硬
件库函数。
图 2-2-1 新建文件夹
第 33 页 共 114 页
2 创建分组
图 2-2-2 新建分组【HARDWARE】
3 创建库文件
点击 1 处【新建文件】,点击 2 处【保存文件】。
图 2-2-3 新建文件
第 34 页 共 114 页
图 2-2-4 点击保存文件
在文件夹【HARDWARE】下,文件名为【LED.h】,点击【保存】。
图 2-2-5 保存文件【LED.h】
第 35 页 共 114 页
重复类似前面的步骤,
【新建文件】、
【保存文件】,在文件夹【HARDWARE】
下保存文件名为【LED.c】。
图 2-2-6 新建并保存文件【LED.c】
4 添加库文件到分组
图 2-2-7 添加文件到【HARDWARE】分组
第 36 页 共 114 页
选择文件夹【HARDWARE】下的文件【LED.c】,单击【Add】。
5 添加头文件路径
第 37 页 共 114 页
单击 1 处,单击 2 处。
在文件夹【HARDWARE】下,点击【选择文件夹】。然后点击【OK】,
再次点击【OK】。
图 2-2-11 选择【HARDWARE】文件夹
第 38 页 共 114 页
图 2-2-12 点击 OK
2.3编写硬件外设库函数
1 LED.h
图 2-3-1 LED.h
第 39 页 共 114 页
注意,全文灰色阴影部分为程序。
#ifndef __LED_H //与 #endif 一起使用,避免重复引用头文件,提高编译效率
#define __LED_H //如果没有引用过头文件,则进入以下定义
#endif //定义完毕,或者引用过头文件到达这一步
.h 文件称为头文件,#ifndef、#define 与#endif 一起使用,在#define 与#endif
中间写函数原型。
2 LED.c
图 2-3-2 LED.c
#include "led.h"
#include "stm32f10x_gpio.h"
//LED 硬件初始化函数定义
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟,
GPIOA 挂载在 APB2 时钟下,在 STM32 中使用 IO 口前都要使能对应时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4; //引脚 4
第 40 页 共 114 页
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //引脚输入输出模式为推挽
输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //引脚输出速度为 50MHZ
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据上面设置好的
GPIO_InitStructure 参数,初始化引脚 GPIOA_PIN4
第 41 页 共 114 页
图 2-3-4 挂载在 APB2 时钟下各引脚、功能对应的时钟名字
图 2-3-5 GPIO_Pin
第 42 页 共 114 页
(3) GPIO_Mode 有 8 个选项(即 GPIO 的 8 种工作模式):
GPIO_Mode_AIN 模拟输入;
GPIO_Mode_IN_FLOATING 浮空输入;
GPIO_Mode_IPD 下拉输入;
GPIO_Mode_IPU 上拉输入;
GPIO_Mode_Out_OD 开漏输出;
GPIO_Mode_Out_PP 推挽输出;
GPIO_Mode_AF_OD 复用开漏输出;
GPIO_Mode_AF_PP 复用推挽输出。
图 2-3-6 GPIO_Mode
图 2-3-7 GPIO_Speed
2.4查看函数定义、声明及入口变量
有时候我们会想知道函数的作用、函数的定义、入口变量的意义、入口变量
的其它选项等,这时我们可以这样做:
第 43 页 共 114 页
1 查看函数定义、声明
图 2-4-1 将鼠标指针放在函数名上
第 44 页 共 114 页
即自动跳转到函数定义。
第 45 页 共 114 页
图 2-4-5 RCC_APB2PeriphClockCmd 的函数声明
2 查看入口变量、结构体成员
图 2-4-6 将鼠标指针放在变量名上
第 46 页 共 114 页
单击右键,选择【Go To Definition Of ‘xxxx’】。
即自动跳转到变量定义,并且可以看到附近有其它功能的时钟名,而它们都
是挂载在 APB2 时钟下的,则函数 RCC_APB2PeriphClockCmd 的第一个入口变
量可以为这些时钟名,再往下拉可以看见挂载在 APB1 时钟下的其它时钟。
第 47 页 共 114 页
图 2-4-9 挂载在 APB1 时钟下的功能时钟名
第 48 页 共 114 页
图 2-4-11 GPIO_InitStructure.GPIO_Mode 可能的值
2.5编写主函数
图 2-5-1 主函数
#include "stm32f10x_gpio.h"
#include "led.h"
#include "delay.h"
#include "sys.h"
第 49 页 共 114 页
由于使用了 stm32f10x_gpio.h、led.h、delay.h 三个库的函数,所以都要进行
引用。
最终只有放在 main 函数里的函数才会被执行。
int main(void)
{
LED_Init(); //调用初始化 LED 函数,引用"led.h"后可使用
delay_init(); //调用初始化延迟函数,引用"delay.h"后可使用
在使用一些功能前,必须进行相应初始化,如接下来要使用延迟函数 delay,
那么就要调用函数 delay_init();进行初始化;接下来要控制 LED 外设,那么调用
LED 初始化函数 LED_Init(); 进行初始化。
while(1)
{
GPIO_SetBits(GPIOA, GPIO_Pin_4); //GPIOA_PIN4 输出高电平,LED 灯熄灭,
引用"stm32f10x_gpio.h"后可使用
//PAout(4)=1; //引用 sys.h 头文件后,可以直接使用该宏定义操作
IO(GPIOA_PIN4)输出高电平
delay_ms(1000); //延迟 1 秒,引用"delay.h"后可使
用
GPIO_ResetBits(GPIOA, GPIO_Pin_4); //设置 A4 引脚为低电平,点亮,引
用"stm32f10x.h"后可使用
//PAout(4)=0; //引用 sys.h 头文件后,可以直接使用该宏定义操作
IO(GPIOA_PIN4)输出低电平
delay_ms(1000); //延迟 1 秒,引用"delay.h"后可使
用
}}
第 50 页 共 114 页