当前位置: 首页 > news >正文

从0开始:STM32F103C8T6开发环境搭建与第一个LED闪烁

本文目标:完成STM32F103C8T6的开发环境搭建,并通过标准库控制GPIO输出,实现LED的闪烁效果。这是单片机开发的“Hello World”,也是后续所有实验的基础!

一、为什么从LED闪烁开始?

LED(发光二极管)是最简单的输出设备,控制它的亮灭(即GPIO引脚输出高/低电平)是单片机最基础的操作。通过这个实验,你能掌握:

  1. STM32最小系统的核心组成(电源、晶振、复位、GPIO);
  2. 开发工具链(Keil MDK + STM32标准库)的配置流程;
  3. 标准库中GPIO初始化与输出函数的使用方法;
  4. 最简单的嵌入式程序逻辑:初始化→循环操作。

二、硬件准备

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

• 安装步骤:

  1. 运行安装程序,按提示选择“ARM”版本;
  2. 安装过程中会提示输入序列号(试用版可跳过,或使用网上公开的试用序列号);
  3. 安装完成后,打开Keil,进入 Pack Installer(菜单栏 Pack > Update),确保已安装 STM32F1xx_DFP(设备支持包,包含STM32F103C8T6的寄存器定义和启动文件)。
  4. 安装步骤就不上图了

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. 创建新工程

  1. 打开Keil μVision5,点击 Project > New μVision Project;

  2. 选择保存路径(如 D:\STM32_Projects\LED_Blink),输入工程名(如 LED_Blink),点击 Save;

  3. 在弹出的 Select Device for Target 窗口,搜索并选择 STM32F103C8(注意是C8型号,不是其他变种如C6/T6等);
    在这里插入图片描述5. 点击 OK 后, 添加标准库文件

  4. 解压之前下载的STM32标准库,找到 Libraries 文件夹(路径类似 STM32F10x_StdPeriph_Lib_V3.6.0/Libraries);

  5. 在Keil工程中,右键 Target 1 下的 Source Group 1,选择 Add Group,命名为 CMSIS(存放 Cortex-M3 核心支持文件)和 StdPeriph_Driver(存放标准外设驱动文件);
    在这里插入图片描述

  6. 添加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,根据你的库版本确认);
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  7. 添加StdPeriph_Driver文件(来自 Libraries/STM32F10x_StdPeriph_Driver):
    • 右键 StdPeriph_Driver 组,添加以下文件:

    ◦ stm32f10x_gpio.c(GPIO驱动);

    ◦ stm32f10x_rcc.c(时钟驱动);

    ◦ misc.c(NVIC中断优先级管理,部分版本可能需要);

    ◦ (可选)stm32f10x_usart.c(后续串口实验用,本文为后续方便驱动文件全部添加了)。
    在这里插入图片描述
    如图:
    在这里插入图片描述

  8. 配置头文件路径
    在这里插入图片描述

  9. 点击Keil菜单栏 Options for Target > C/C++;

  10. 在 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闪烁程序

  1. 硬件连接确认

• 假设你的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. 编译与下载

  1. 点击Keil的 Build 按钮(或按F7),检查是否有错误(若提示缺少头文件,检查Include Paths配置);
  2. 确认编译成功后,连接STM32开发板到电脑(通过USB转串口模块或直接USB,取决于板载调试接口);
  3. 在Keil中点击 Options for Target > Debug,选择仿真器(如ST-Link或J-Link,若没有则选“Use Simulator”模拟调试,但无法真机运行);
    在这里插入图片描述
  4. 点击 Flash > Download(或按Ctrl+F5),将程序下载到STM32芯片中;
  5. 观察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过来就行

在这里插入图片描述

下一步学习建议:

  1. 尝试修改延时时间(调整 Delay() 函数中的循环次数),观察LED闪烁频率变化;
  2. 实验不同GPIO引脚(如PA1、PB0),验证代码的通用性;
  3. 思考:为什么必须调用 RCC_APB2PeriphClockCmd() 开启时钟?如果不调用会发生什么?

推荐给初学者阔以看看,用心学习。


文章转载自:

http://UEwKrGLW.ypdmr.cn
http://8XRVAMvR.ypdmr.cn
http://7W3qUcyN.ypdmr.cn
http://wJx6OHPH.ypdmr.cn
http://SC4iVK0f.ypdmr.cn
http://0XEIASgz.ypdmr.cn
http://V9qmHGpm.ypdmr.cn
http://2BUUR5KA.ypdmr.cn
http://j2PCG9Zu.ypdmr.cn
http://p161SKwa.ypdmr.cn
http://pbkTYDa2.ypdmr.cn
http://a835FvoZ.ypdmr.cn
http://miDdvUEm.ypdmr.cn
http://k6mrL4M3.ypdmr.cn
http://fANhYmYF.ypdmr.cn
http://e006uXas.ypdmr.cn
http://E9Mhtw98.ypdmr.cn
http://TEE9JCeH.ypdmr.cn
http://fD7htUZs.ypdmr.cn
http://y0RCaxRB.ypdmr.cn
http://hYZWNzG8.ypdmr.cn
http://MAZEg58r.ypdmr.cn
http://zoqLG678.ypdmr.cn
http://h2BkV8Nm.ypdmr.cn
http://OBb8kW7Q.ypdmr.cn
http://ixHfKhu1.ypdmr.cn
http://r5zojZnK.ypdmr.cn
http://o0t8TGRr.ypdmr.cn
http://OBglFYKI.ypdmr.cn
http://8Pve5N9l.ypdmr.cn
http://www.dtcms.com/a/382610.html

相关文章:

  • linux C 语言开发 (九) 进程间通讯--管道
  • LinuxC++项目开发日志——高并发内存池(5-page cache框架开发)
  • MATLAB基于组合近似模型和IPSO-GA的全焊接球阀焊接工艺参数优化研究
  • SpringSecurity的应用
  • 算法题(206):方格取数(动态规划)
  • 第十六周周报
  • [硬件电路-193]:双极型晶体管BJT与场效应晶体管FET异同
  • ID3v2的header中的扩展标头(Extended Header),其Size字段如何计算整个ID3的长度?
  • 【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
  • Linux -- 权限的理解
  • Java零基础学习Day10——面向对象高级1
  • 解析通过base64 传过来的图片
  • Redis 持久化策略
  • STM32---PWR
  • 0913刷题日记
  • Java基础面试篇(7)
  • 4-机器学习与大模型开发数学教程-第0章 预备知识-0-4 复数与指数形式(欧拉公式)
  • TA-VLA——将关节力矩反馈融入VLA中:无需外部力传感器,即可完成汽车充电器插入(且可多次自主尝试)
  • 从0到1开发一个商用 Agent(智能体),Agent零基础入门到精通!_零基础开发aiagent 用dify从0到1做智能体
  • android 消息队列MessageQueue源码阅读
  • Gtest2025大会学习记录(全球软件测试技术峰会)
  • oneshape acad数据集 sam-dataset
  • 堆(优先队列)
  • 【卷积神经网络详解与实例】7——经典CNN之AlexNet
  • Digital Clock 4,一款免费的个性化桌面数字时钟
  • mysql 必须在逗号分隔字符串和JSON字段之间二选一,怎么选
  • 分布式锁介绍与实现
  • 海盗王客户端dx9的64位release版测试
  • MX模拟赛总结
  • FLEXSPI_Init 硬件故障问题