从0开始:STM32F103C8T6开发环境搭建与第一个LED闪烁
本文目标:完成STM32F103C8T6的开发环境搭建,并通过标准库控制GPIO输出,实现LED的闪烁效果。这是单片机开发的“Hello World”,也是后续所有实验的基础!
一、为什么从LED闪烁开始?
LED(发光二极管)是最简单的输出设备,控制它的亮灭(即GPIO引脚输出高/低电平)是单片机最基础的操作。通过这个实验,你能掌握:
- STM32最小系统的核心组成(电源、晶振、复位、GPIO);
- 开发工具链(Keil MDK + STM32标准库)的配置流程;
- 标准库中GPIO初始化与输出函数的使用方法;
- 最简单的嵌入式程序逻辑:初始化→循环操作。
二、硬件准备
1. 核心开发板:STM32F103C8T6 建议初学者在TB买个开发板或者最小系统板
• 芯片特性:Cortex-M3内核,72MHz主频,20KB RAM + 64KB Flash,足够应对大多数基础实验。
• 最小系统需求:
• 电源:3.3V(注意!STM32F103C8T6工作电压为2.0~3.6V,推荐3.3V,切勿直接接5V!);
• 晶振:通常板载8MHz外部晶振(用于系统时钟源)+ 32.768kHz(可选,用于RTC);
• 复位电路:按键复位(NRST引脚通过10kΩ上拉电阻接VCC,按键一端接NRST,另一端接地);
• GPIO引脚:至少1个可用引脚(如PA0 、PC13 等),本文用PA0控制LED。
注意:如果你使用的是现成的STM32F103C8T6开发板 ,通常已集成最小系统,直接找板载的LED(一般标记为“D1”或“LED”,连接在某个GPIO引脚,如PA0或PC13),确认其对应的引脚号即可。
2. 其他工具
• USB转串口模块(后续串口实验用,本文暂不需要);
• 杜邦线/面包板(如果用分立元件搭最小系统);
• 3.3V电源(开发板通常通过USB供电,或用稳压电源模块)。
三、软件工具链安装
1. Keil MDK(μVision5)
• 作用:编写、编译、调试STM32代码的集成开发环境(IDE)。
• 下载:访问 keil 官网
https://www.keil.com/demo/eval/arm.htm
• 安装步骤:
- 运行安装程序,按提示选择“ARM”版本;
- 安装过程中会提示输入序列号(试用版可跳过,或使用网上公开的试用序列号);
- 安装完成后,打开Keil,进入 Pack Installer(菜单栏 Pack > Update),确保已安装 STM32F1xx_DFP(设备支持包,包含STM32F103C8T6的寄存器定义和启动文件)。
- 安装步骤就不上图了
2. STM32标准库(Standard Peripheral Library)
• 作用:官方提供的底层外设驱动函数库(如GPIO_Init()、USART_SendData()),避免直接操作寄存器(降低学习门槛)。
• 下载:从ST官网历史页面获取(ST已停止维护标准库,但仍有资源):
• 推荐下载地址 :
https://www.st.com.cn/zh/embedded-software/stsw-stm32054.html
下载需要注册账号 ,需要的可以后台留言邮箱,我发送我下载好的
• 解压后得到文件夹(如 STM32F10x_StdPeriph_Lib_V3.6.0),包含 Libraries(库文件)和 Project(示例工程)。
替代方案:如果找不到官方标准库,也可以用现成的“固件库包”(如正点原子的标准库版本),核心功能一致。
四、开发环境配置(Keil + 标准库)
1. 创建新工程
-
打开Keil μVision5,点击 Project > New μVision Project;
-
选择保存路径(如 D:\STM32_Projects\LED_Blink),输入工程名(如 LED_Blink),点击 Save;
-
在弹出的 Select Device for Target 窗口,搜索并选择 STM32F103C8(注意是C8型号,不是其他变种如C6/T6等);
5. 点击 OK 后, 添加标准库文件
-
解压之前下载的STM32标准库,找到 Libraries 文件夹(路径类似 STM32F10x_StdPeriph_Lib_V3.6.0/Libraries);
-
在Keil工程中,右键 Target 1 下的 Source Group 1,选择 Add Group,命名为 CMSIS(存放 Cortex-M3 核心支持文件)和 StdPeriph_Driver(存放标准外设驱动文件);
-
添加CMSIS文件(来自标准库的 Libraries/CMSIS/CM3/CoreSupport 和 Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x):
• 右键 CMSIS 组,添加以下文件:◦ core_cm3.c(Cortex-M3核心函数);
◦ startup_stm32f10x_md.s(启动文件,注意:STM32F103C8T6属于“Medium-density”系列,启动文件名通常是 startup_stm32f10x_md.s 或 startup_stm32f10x_md_vl.s,根据你的库版本确认);
-
添加StdPeriph_Driver文件(来自 Libraries/STM32F10x_StdPeriph_Driver):
• 右键 StdPeriph_Driver 组,添加以下文件:◦ stm32f10x_gpio.c(GPIO驱动);
◦ stm32f10x_rcc.c(时钟驱动);
◦ misc.c(NVIC中断优先级管理,部分版本可能需要);
◦ (可选)stm32f10x_usart.c(后续串口实验用,本文为后续方便驱动文件全部添加了)。
如图:
-
配置头文件路径
-
点击Keil菜单栏 Options for Target > C/C++;
-
在 Include Paths 中添加以下路径(指向标准库的头文件目录):
• …\Libraries\CMSIS\CM3\CoreSupport;
• …\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;
• …\Libraries\STM32F10x_StdPeriph_Driver\inc;
点击那个虚框增加路径
(路径根据你的实际解压位置调整,例如如果库放在 D:\STM32_StdLib,则路径可能是 D:\STM32_StdLib\Libraries…)。 最好是库和工程放在同一个文件下下,到时移植方便,就是内存多占点。
五、编写第一个LED闪烁程序
- 硬件连接确认
• 假设你的STM32F103C8T6开发板上有一个LED连接在 PA0引脚(若实际连接在其他引脚,如PC13,后续代码中修改 GPIOA → GPIOC,GPIO_Pin_0 → GPIO_Pin_13 即可)。
• 如果没有现成LED,可以自己用杜邦线连接:
• LED正极(长脚)→ 通过一个 330Ω限流电阻 → PA0引脚;
• LED负极(短脚)→ GND(开发板的地,通常标有“GND”)。
2. 代码实现
在Keil工程中,右键 新建Group 命名user,添加新建文件 main.c,输入以下代码:
代码如下:
#include "stm32f10x.h" // STM32标准库头文件// 延时函数(简单粗暴的循环延时,后续可用定时器优化)
void Delay(uint32_t time) {for(uint32_t i = 0; i < time; i++) {for(uint32_t j = 0; j < 5000; j++); // 空循环消耗时间}
}int main(void) {// 1. 初始化GPIO:配置PA0为推挽输出(低速即可)GPIO_InitTypeDef GPIO_InitStructure; // 定义GPIO配置结构体// 1.1 使能GPIOA的时钟(必须!STM32外设不使用时钟会不工作)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 1.2 配置PA0为推挽输出,速度50MHz(GPIO_Speed_50MHz)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选择PA0引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出速度50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA0while(1) { // 主循环GPIO_SetBits(GPIOA, GPIO_Pin_0); // PA0输出高电平(LED熄灭,假设共阳接法)Delay(500); // 延时约500msGPIO_ResetBits(GPIOA, GPIO_Pin_0); // PA0输出低电平(LED点亮,假设共阳接法)Delay(500); // 延时约500ms}
}
关键点说明:
编译器预编译报错,看红色位置应该是没有定义
注意添加宏定义
编译还有提示错误:
需要将这个文件 stm32f10x_conf.h 从库里面拷贝到自己建立的工程这边来,或者直接添加它所在的路径也行,我直接拷贝过来,后续使用方便。
在库里面给的参考工程里面找到文件:
拷贝到自己工程:
然后再添加路径
再继续编译:
发现没有报错了。整个工程图如下:
程序关键点说明:
-
GPIO模式:GPIO_Mode_Out_PP 表示推挽输出(适合驱动LED等负载),若用开漏输出(GPIO_Mode_Out_OD)需外加上拉电阻;
-
时钟使能:STM32的所有外设(包括GPIO)必须通过 RCC_APB2PeriphClockCmd() 或 RCC_APB1PeriphClockCmd() 开启对应时钟,否则外设不工作!PA0属于APB2总线外设,所以用 RCC_APB2Periph_GPIOA;
-
推挽输出:GPIO_SetBits() 设置引脚为高电平,GPIO_ResetBits() 设置为低电平(LED亮灭逻辑取决于硬件接法:若LED正极接PA0、负极接GND,则高电平LED亮;若LED负极接PA0、正极接VCC,则高电平LED灭。本文假设常见接法:LED正极接VCC,负极接PA0,因此低电平LED亮)。
3. 编译与下载
- 点击Keil的 Build 按钮(或按F7),检查是否有错误(若提示缺少头文件,检查Include Paths配置);
- 确认编译成功后,连接STM32开发板到电脑(通过USB转串口模块或直接USB,取决于板载调试接口);
- 在Keil中点击 Options for Target > Debug,选择仿真器(如ST-Link或J-Link,若没有则选“Use Simulator”模拟调试,但无法真机运行);
- 点击 Flash > Download(或按Ctrl+F5),将程序下载到STM32芯片中;
- 观察LED是否以约1Hz频率闪烁(亮500ms,灭500ms)。时间是粗略延时,具体看实际测试情况。
六、常见问题解决
1. 编译错误:找不到头文件
• 检查 Include Paths 是否添加了标准库的头文件目录(如 CMSIS 和 StdPeriph_Driver/inc);
• 确认工程中添加了正确的源文件(core_cm3.c、stm32f10x_gpio.c 等)。
2. 下载后LED不亮
• 检查硬件连接:LED正负极是否接反?限流电阻是否漏接(建议330Ω~1kΩ)?PA0引脚是否正确?
• 用万用表测量PA0引脚电压:低电平时应为0V(LED亮),高电平时应为3.3V(LED灭);
• 确认代码中的GPIO引脚号(如 GPIO_Pin_0)与实际硬件一致(若LED接PC13,则改用 GPIOC 和 GPIO_Pin_13)。
3. Keil无法识别STM32F103C8
• 确保安装了 STM32F1xx_DFP 设备支持包(通过Pack Installer更新); X度下载运行安装就行,注意路径(如果电脑只安装了一个keil就不用担心)
下载地址:
https://www.keil.arm.com/packs/stm32f1xx_dfp-keil/versions/
需要的可以后台留言邮箱,我发送我下载好的
• 检查芯片型号选择是否正确(STM32F103C8,不是F103C6或其他变种)。
七、总结与下一步
恭喜!你已经完成了STM32开发的第一个实验——通过标准库控制GPIO输出,实现了LED闪烁。这看似简单的代码,背后包含了单片机开发的核心流程:硬件连接→环境配置→外设初始化→循环操作。
如果不想自己建立工程,阔以直接用库文件里面建好的工程,参考他给的demo,然后把要使用的外设copy过来就行
下一步学习建议:
- 尝试修改延时时间(调整 Delay() 函数中的循环次数),观察LED闪烁频率变化;
- 实验不同GPIO引脚(如PA1、PB0),验证代码的通用性;
- 思考:为什么必须调用 RCC_APB2PeriphClockCmd() 开启时钟?如果不调用会发生什么?
推荐给初学者阔以看看,用心学习。