Day30 —【STM32F103C8 Keil5 Proteus】没有开发板也能学 STM32从环境搭建到 LED 流水灯仿真Day30 对当前 Proteus 学习阶段进行完整整理。本文记录一次“没有真实硬件”的 STM32 学习实践使用 Keil µVision 编译 STM32F103C8 程序生成 HEX 固件再由 Proteus 搭建虚拟电路并加载固件。文章同时记录单灯闪烁、四灯流水灯、常见故障以及许可证问题方便初学者复现和排错。一、为什么选择 Keil Proteus暂时没有 STM32 开发板时仍然可以先学习以下内容STM32 工程的创建和芯片选择GPIO、RCC、SysTick 等寄存器的基本使用编译、链接以及 HEX 固件的生成过程LED、电阻、电源、复位和启动引脚的连接方法使用逻辑探针、虚拟示波器观察 GPIO 波形将“代码行为”和“电路现象”对应起来。这套组合中两款软件的分工很明确工具作用Keil µVision编写、编译和链接 STM32 程序输出 HEX 固件Proteus搭建虚拟电路给虚拟 MCU 加载 HEX观察运行结果需要特别理解Proteus 不是用来替代 Keil 编译代码的。本项目在 Proteus 新建工程时选择“没有固件项目”因为固件统一由 Keil 生成。二、本次环境MCUSTM32F103C8ARM Cortex-M3IDEKeil µVision 5编译器Arm Compiler 6.21Device PackKeil STM32F1xx DFP 2.4.1仿真软件Proteus 9 Professional 9.0 SP2开发方式寄存器级 C实验项目Day28PA0 单灯闪烁Day29PA0PA3 四灯流水灯。软件版本不必完全相同但 Keil 必须能够选择STM32F103C8Proteus 元件库也必须带有该器件的可仿真模型。三、整体工作流Keil 新建 STM32F103C8 工程 ↓ 编写 GPIO 与延时代码 ↓ 开启 Create HEX File 并编译 ↓ Proteus 绘制 STM32 LED 电路 ↓ 把 Keil 输出的 HEX 加载到 STM32 元件 ↓ 运行仿真用逻辑探针或示波器验证掌握这条链路比单纯记住按钮位置更重要。以后增加按键、串口、定时器、I²C 或 FreeRTOS基本工作流仍然相同。四、Proteus 新建工程4.1 创建原理图新建工程时按下面选择原理图模板选择DEFAULT不创建 PCB Layout固件页面选择“没有固件项目”完成向导后进入 Schematic Capture。这样设置的原因是当前目标只是做虚拟电路仿真不进行 PCB 制板固件已经由 Keil 管理Proteus 只负责加载结果。4.2 放置元件按P打开 Pick Devices搜索并放置STM32F103C8LED-REDRESLOGICPROBE推荐OSCILLOSCOPE需要观察波形时使用电阻设置为330R。限流电阻的作用是限制 LED 电流即使是仿真也应按照真实电路思维设计。五、单灯电路连接最小实验使用 PA0 驱动 LEDPA0 → 330 Ω 电阻 → LED → GND此外还需要处理以下引脚引脚连接原因BOOT0GND选择从主 Flash 启动NRST10 kΩ 上拉到 VDD保证复位脚处于稳定高电平VDDA、VBATVDD给模拟域和备份域供电VSSAGND模拟地LED 极性为什么重要LED 是有方向的器件。GPIO 输出高电平时必须形成从 GPIO、限流电阻、LED 到 GND 的完整电流路径LED 才会导通。如果逻辑探针已经在 0 和 1 之间变化但 LED 始终不亮应优先检查LED 是否接反LED 和电阻是否真正连接到同一网络是否缺少 GNDGPIO 是否配置成推挽输出切换速度是否快到肉眼看起来像常亮。六、Keil 创建 STM32F103C8 工程6.1 芯片包在 Pack Installer 中确认STM32F103C8可以被搜索到并安装Keil::STM32F1xx_DFP。Device Pack 提供STM32F103C8 的寄存器定义启动文件系统时钟文件Keil 对该芯片的工程支持。如果没有芯片包即使能写 C 代码工程也缺少启动入口、内存布局和寄存器地址定义。6.2 运行环境组件新建工程并选择STM32F103C8后在 Manage Run-Time Environment 中至少选择CMSIS → COREDevice → StartupStartup会提供中断向量表和复位入口CMSIS CORE提供 Cortex-M3 的统一核心定义。七、Day28PA0 单灯闪烁核心代码如下#includestm32f10x.hstaticvoidsystick_init_1ms(void){SystemCoreClockUpdate();SysTick-LOAD(SystemCoreClock/1000U)-1U;SysTick-VAL0U;SysTick-CTRLSysTick_CTRL_CLKSOURCE_Msk|SysTick_CTRL_ENABLE_Msk;}staticvoiddelay_ms(uint32_tmilliseconds){while(milliseconds0U){while((SysTick-CTRLSysTick_CTRL_COUNTFLAG_Msk)0U){}milliseconds--;}}intmain(void){RCC-APB2ENR|RCC_APB2ENR_IOPAEN;GPIOA-CRL~0x0000000FUL;GPIOA-CRL|0x00000002UL;GPIOA-BRRGPIO_BRR_BR0;systick_init_1ms();while(1){GPIOA-ODR^GPIO_ODR_ODR0;delay_ms(1000U);}}7.1 RCC 为什么要使能RCC-APB2ENR|RCC_APB2ENR_IOPAEN;STM32 为了节能外设时钟默认不一定开启。GPIOA 没有时钟时对它的寄存器配置不会产生预期效果。7.2 PA0 为什么写成0x2STM32F1 的GPIOx_CRL每 4 位控制一个引脚。PA0 的配置值0010表示MODE0 10输出模式最大速度 2 MHzCNF0 00通用推挽输出。7.3 SysTick 为什么适合入门SysTick 是 Cortex-M 内核自带的 24 位定时器。将重装值设为SystemCoreClock / 1000 - 1可得到约 1 ms 的计数周期。轮询COUNTFLAG比空循环延时更容易解释也更接近嵌入式工程中的时间基准。八、生成 HEX 固件进入Options for Target → Output → 勾选 Create HEX File然后执行 Rebuild。最终构建结果为0 Error(s)说明程序已经成功编译、链接并生成 HEX。构建过程中出现过以下警告旧版头文件注释包含非 UTF-8 字符文件末尾缺少换行Pack 内系统文件的数组访问和变量声明警告。这些警告没有阻止 HEX 生成但仍应区分“警告”和“错误”错误必须解决后才能生成固件警告需要分析来源不能看到数量多就直接忽略。九、给 Proteus 的 STM32 加载程序双击原理图中的 STM32F103C8找到Program File选择 Keil 生成的.hex文件。同时建议OSC Frequency与程序的系统时钟设定保持一致Clock Scale使用默认值不要为了“让灯更快”随意设置为8 Times否则 Proteus 时间和代码延时不再直观对应。运行后Simulation Log 出现Loading HEX file和读取字节数说明固件已被装载到虚拟 MCU。十、如何判断程序是否真的运行不要只盯着 LED。最可靠的验证顺序是Simulation Log 能否成功读取 HEXPA0 逻辑探针是否在0和1之间切换电压表是否在约 0 V 和 3.3 V 之间变化示波器是否出现周期方波最后再看 LED 视觉效果。如果逻辑探针变化而 LED 不闪说明“程序与 GPIO 大概率正常”问题更可能在 LED 极性、连接方式、限流电阻或视觉刷新上。这种分层排错方法比反复修改代码有效得多。十一、Day29四灯流水灯完成单个 GPIO 后将 PA0PA3 都配置为推挽输出GPIOA-CRL~0x0000FFFFUL;GPIOA-CRL|0x00002222UL;每个 LED 必须单独串联一个 330 Ω 电阻PA0 → 330 Ω → LED0 → GND PA1 → 330 Ω → LED1 → GND PA2 → 330 Ω → LED2 → GND PA3 → 330 Ω → LED3 → GND流水灯核心逻辑while(1){GPIOA-ODR~0x0000000FUL;GPIOA-ODR|(1ULled_index);delay_ms(300U);led_index;if(led_index4U){led_index0U;}}1UL led_index会让逻辑 1 依次移动到 PA0、PA1、PA2、PA3led_index低四位点亮引脚00001PA010010PA120100PA231000PA3当前已完成 Keil 工程、HEX 和 Proteus 原理图最终动态现象还需要在有效的仿真许可证下继续复验。十二、这次遇到的典型问题12.1 搜不到 STM32F103C8可能原因使用的 Proteus 版本过旧元件库不含 Cortex-M3 STM32 模型搜索条件勾选了错误的分类或“仅显示带模型元件”。正确版本中搜索STM32F103应能看到 C4、C6、C8 等型号。只有带可执行仿真模型的 MCU 才能运行 HEX单纯原理图符号不能完成 MCU 仿真。12.2 引脚显示 0/1但 LED 不闪依次检查使用逻辑探针确认 GPIO 是否真的切换检查 LED 极性每个 LED 是否有独立电阻GPIO 是否为推挽输出HEX 是否为最新一次编译生成Proteus MCU 的 Program File 是否仍指向旧文件延时时间和 Clock Scale 是否匹配。12.3 仿真很慢、CPU 占用很高同时放置多个仪器、探针或存在不合理连线时仿真负载会明显上升。排错时先保留最小系统MCU、一个 LED、一个电阻和一个逻辑探针确认正常后再逐步增加元件。12.4Bad or missing Customer Key软件修复后能够启动但主页显示Licensing error. Bad or missing Customer Key. Not Licensed for Simulation这不是 STM32 工程或 HEX 的问题而是许可证状态导致仿真功能被禁用。不要从不明来源复制 DLL 覆盖安装目录或 Windows 系统文件这会带来安全、稳定性和合规风险。根据 Labcenter 官方说明普通 Proteus Demo 的微控制器仿真期为 14 天但不能仿真用户自己创建的 MCU 设计也不能保存自己的工作如需完整验证自建 STM32 工程应申请完整 evaluation license、使用学校提供的教育/云许可证或者购买相应授权。官方试用说明https://www.labcenter.com/free-trial/官方教育许可说明https://www.labcenter.com/education/十三、工程目录GitHub 仓库https://github.com/jdai10590-afk/Embedded-C-Learning-Projectsday28/ ├─ README.md └─ Src/main.c # PA0 单灯闪烁 day29/ ├─ README.md ├─ Src/main.c # PA0PA3 流水灯 ├─ Keil/ # Keil 工程与 HEX └─ Proteus/ # Proteus 原理图工程 day30/ ├─ README.md # 本文CSDN Markdown └─ Images/ # 本文截图十四、本阶段总结目前已经走通以下关键链路Keil 能识别 STM32F103C8Device Pack、CMSIS 和 Startup 组件可用寄存器级 GPIO 与 SysTick 程序能够编译Keil 能生成 HEXProteus 能识别 STM32F103C8 模型并加载 HEX逻辑探针可观察 GPIO 的 0/1 状态已搭建单灯和四灯流水灯原理图已明确 LED 不闪时的分层排错方法已定位当前阻塞项为仿真许可证而不是缺少所谓version.dll。下一阶段先在有效许可证下复验 Day28 和 Day29 的动态现象再学习按键输入、外部中断、定时器 PWM、USART 和 FreeRTOS。没有硬件并不会阻止前期学习但仿真结果最终仍应在真实开发板上验证。