十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Proteus仿真STM32F103R6数字电压表全流程

Proteus仿真STM32F103R6数字电压表全流程 简介本资源是一套基于Proteus与Keil联合仿真的STM32数字电压表完整工程面向嵌入式初学者及课程设计实践者解决STM32F103R6芯片双通道AD采集、数值处理与数码管动态显示的核心技术落地问题。资源共599个文件涵盖337个C源码含ADC初始化、数码管驱动、串口调试逻辑、106个头文件定义寄存器映射与功能接口、43个汇编启动文件及28个IAR/Keil链接脚本另有hex可执行文件、AXF调试镜像与Proteus电路图整体压缩包17.34MB结构完整便于理解底层外设配置与软硬件协同流程。已有5726人学习下载配套工程已实现两路独立电压采样、实时数码管刷新与串口同步输出支持通过调节电阻器模拟不同输入电压可直接用于课堂演示、课程设计验证或AD模块开发参考。1. 为什么用 Proteus 仿真 STM32F103R6 做数字电压表比直接焊板更高效很多刚接触嵌入式开发的工程师会疑惑既然最终要烧录到真实 STM32F103R6 芯片上运行为什么还要花时间在 Proteus 里搭电路、写代码、调 ADC答案很实际——它能提前暴露 70% 以上的硬件逻辑错误和时序冲突。比如你把 ADC 通道接错到 PA1 而不是默认的 PA0或者没配置 RCC 使能 ADC 时钟在 Proteus 里点下仿真按钮电压读数直接为 0 或溢出波形图立刻报红而如果等 PCB 打样回来再测至少延误 35 天。更关键的是Proteus 对 STM32F103 系列含 R6 封装的支持已覆盖核心外设建模ADC、GPIO、SysTick、USART且能加载 .hex 或 .elf 文件进行指令级协同仿真。这不是“玩具级”演示而是可验证采样精度、滤波算法、显示刷新率的真实闭环流程。适合单片机课程设计、毕业设计快速验证、企业原型预演尤其对没有示波器/逻辑分析仪的初学者它是唯一能看清 ADC 转换过程、寄存器变化、中断触发时刻的可视化环境。2. 在 Proteus 8.16 中搭建 STM32F103R6 最小系统并加载 ADC 仿真模型2.1 确认 Proteus 版本与 STM32 元件库兼容性Proteus 8.10 是首个原生支持 STM32F103 系列仿真的版本但完整 ADC 模型需 8.13 及以上。当前主流稳定版为 8.162023 年发布其STM32F103R6元件位于Microcontroller → ARM → STMicroelectronics → STM32F103R6。注意该元件不包含内部 Flash 编程功能仅支持外部加载.hex或.elf文件若使用 Keil MDK 编译生成.axf需通过fromelf --bin转为二进制格式再导入。常见误操作是直接拖入STM32F103C8T6蓝 pill 板常用型号其引脚定义与 R6 不同——R6 是 64-pin LQFP 封装PA0PA15、PB0PB15 全部可用而 C8T6 仅 48-pin缺少部分 ADC 输入通道如 ADC1_IN10IN17。因此原理图中必须严格选用STM32F103R6元件否则后续 ADC 通道映射将失效。2.2 构建最小系统电源、复位、晶振与调试接口在 Proteus 中新建 schematic放置以下元件STM32F103R6主控CRYSTAL8 MHz接 OSC_IN/OSC_OUT 引脚CAPACITOR×222 pF分别接晶振两端到地RESISTOR10 kΩ接 NRST 引脚到 VCC构成上拉复位CAPACITOR100 nFNRST 到地去耦电容POWERVCC 3.3 VGND 接地提示STM32F103R6 的 VDDA/VSSA 必须单独接 3.3 V 和 GND这是 ADC 参考电压源。若忽略此步ADC 读数将严重漂移或恒为 0。Proteus 中双击芯片在Properties → Power Pins可查看 VDDA/VSSA 引脚编号通常为 Pin 19/VDDA 和 Pin 20/VSSA务必手动连线。2.2.1 配置调试接口SWD用于程序下载与在线调试虽然 Proteus 仿真不依赖物理 SWD 接口但为保持与真实开发流程一致建议添加SWDIOPin 37和SWCLKPin 36引脚并连接至虚拟调试器Proteus 内置Virtual Terminal不支持 SWD此处仅作原理图完整性标注。实际仿真时通过Debug → Load Hex File加载固件即可。2.3 连接 ADC 输入与参考电压源数字电压表的核心是精确采集模拟电压因此 ADC 输入路径必须规范使用ANALOG_SOURCE元件位于Generators → ANALOG_SOURCE模拟待测电压设置DC Voltage 1.23 V便于后续校准验证将其正极接PA0即 ADC1_IN0STM32F103 默认 ADC 通道 0PA0与ANALOG_SOURCE之间串联RESISTOR10 kΩ防止过流VREF引脚Pin 21接 3.3 VVREF-Pin 22接地 —— 此为 ADC 参考电压基准决定量化范围03.3 V 对应 04095注意Proteus 中STM32F103R6元件默认启用内部参考电压VREFINT但数字电压表要求外部高精度基准必须显式连接 VREF 和 VREF-。若未连接仿真时 ADC 值将随机跳变无法稳定读取。3. Keil MDK 中编写 STM32F103R6 ADC 采集与数码管显示驱动代码3.1 工程配置启动文件、时钟与外设使能新建 Keil uVision5 工程选择STM32F103R6Device添加startup_stm32f10x_md.s启动文件。关键配置如下// system_stm32f10x.c 中设置系统时钟为 72 MHz void SetSysClockTo72(void) { RCC-CR | (uint32_t)RCC_CR_HSEON; // 开启 HSE while((RCC-CR RCC_CR_HSERDY) 0); // 等待 HSE 就绪 RCC-CFGR | (uint32_t)RCC_CFGR_PLLXTPRE_HSE_Div2; // PLL 输入为 HSE/2 4 MHz RCC-CFGR | (uint32_t)(RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC_HSE_Div2); // PLL 4×9 36 MHz RCC-CFGR | (uint32_t)(RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV1); // APB136MHz, APB272MHz RCC-CR | (uint32_t)RCC_CR_PLLON; // 开启 PLL while((RCC-CR RCC_CR_PLLRDY) 0); // 等待 PLL 就绪 RCC-CFGR | (uint32_t)RCC_CFGR_SW_PLL; // 切换主时钟为 PLL while((RCC-CFGR RCC_CFGR_SWS) ! RCC_CFGR_SWS_PLL); }3.1.1 ADC 初始化时钟、通道、采样时间与转换模式void ADC1_Init(void) { RCC-APB2ENR | RCC_APB2ENR_ADC1EN; // 使能 ADC1 时钟APB2 RCC-APB2ENR | RCC_APB2ENR_IOPAEN; // 使能 GPIOA 时钟 GPIOA-CRL ~(0xF 0); // 清除 PA0 模式位 GPIOA-CRL | (0x0 0); // PA0 设为模拟输入00 ADC1-CR2 ~ADC_CR2_ADON; // 关闭 ADC ADC1-CR1 ~ADC_CR1_SCAN; // 单通道模式 ADC1-SMPR2 ~ADC_SMPR2_SMP0; // 清除 PA0 采样时间位 ADC1-SMPR2 | ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0; // 239.5 周期采样最高精度 ADC1-SQR3 0; // 规则序列寄存器通道 0 在第 1 位 ADC1-SQR3 | (0 5); // ADC1_IN0 0 ADC1-CR2 | ADC_CR2_ADON; // 开启 ADC ADC1-CR2 | ADC_CR2_SWSTART; // 软件触发首次转换 }参数说明SMPR2_SMP0_1 | SMPR2_SMP0_0表示 239.5 个 ADC 时钟周期采样适用于 14 MHz ADC 时钟72 MHz / 6 12 MHz实际取整为 14 MHz确保信号稳定若采样时间过短如 1.5 周期Proteus 仿真中会出现读数抖动过长则降低采样率。此处值经实测在 Proteus 8.16 中匹配ANALOG_SOURCE输出特性。3.2 主循环ADC 读取、数字滤波与 BCD 转换uint16_t Read_ADC_Value(void) { while(!(ADC1-SR ADC_SR_EOC)); // 等待转换完成 return ADC1-DR; // 读取数据寄存器 } // 4 次滑动平均滤波抑制 Proteus 仿真噪声 uint16_t ADC_Filter(void) { static uint16_t buf[4] {0}; static uint8_t idx 0; uint16_t val Read_ADC_Value(); buf[idx] val; idx (idx 1) % 4; return (buf[0] buf[1] buf[2] buf[3]) / 4; } // 将 0~4095 映射为 0.00~3.30 V保留两位小数 void Convert_To_Voltage(uint16_t adc_val, uint8_t *digits) { uint32_t mv (uint32_t)adc_val * 3300 / 4095; // 毫伏值 digits[0] mv / 1000; // 个位 digits[1] (mv % 1000) / 100; // 十分位 digits[2] (mv % 100) / 10; // 百分位 }3.2.1 数码管动态扫描驱动共阴极 4 位Proteus 中使用7SEG-MPX4-CC元件4 位共阴数码管通过PB0PB3控制位选PA8PA14控制段选ag dp// 段码表0~9, ., 空 const uint16_t seg_code[12] { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80, 0x00 }; void Display_Digits(uint8_t *d, uint8_t dot_pos) { static uint8_t pos 0; GPIOB-ODR 0xFF00; // 关闭所有位选 GPIOA-ODR 0xFFFF; // 关闭所有段选 uint16_t seg seg_code[d[pos]]; if (pos dot_pos) seg | 0x80; // 点亮小数点 GPIOA-ODR ~seg; // 段选低电平有效 GPIOB-ODR ~(1 pos); // 位选低电平有效 Delay_us(500); // 每位显示 500 μs总刷新率 500 Hz pos (pos 1) % 4; }逻辑说明Delay_us(500)是关键参数。若延时过短如 100 μsProteus 仿真中数码管亮度不足过长如 2 ms则出现闪烁。经实测 500 μs 在 Proteus 8.16 中达到最佳视觉稳定性与 CPU 占用平衡。4. Proteus 与 Keil 联合调试加载固件、观测波形与校准误差4.1 固件编译与加载到 Proteus 仿真环境Keil 中设置输出格式为Intel HexOptions → Output → Intel Hex File编译生成voltage_meter.hex。在 Proteus 中双击STM32F103R6元件 →Program File栏填入 hex 文件路径Clock Frequency设为72 MHz与 Keil 中SetSysClockTo72()一致External Clock设为8 MHz匹配原理图中晶振值点击Play按钮启动仿真此时数码管应显示1.23对应ANALOG_SOURCE设置的 1.23 V。若显示0.00按顺序排查检查VREF是否接 3.3 VProteus 中右键VREF引脚 →Digital Graph确认电压为 3.3 V查看PA0引脚电平右键 →Digital Graph应为 1.23 V 直流线在 Keil 中打开Debug → View → Registers观察ADC1-DR寄存器值是否在1530±10区间1.23 V × 4095 / 3.3 ≈ 15304.2 使用 Proteus 示波器观测 ADC 采样时序Proteus 内置OSCILLOSCOPE可捕获关键信号通道 APA0模拟输入通道 BPB0第一位数码管位选用于观测扫描节拍设置时基为1 ms/div触发源选PB0上升沿波形应显示每 4 ms 完成一次 4 位扫描即 250 Hz 刷新且PA0为稳定直流线。若PA0出现高频抖动说明 ADC 采样未加 RC 滤波或SMPR2设置过短若PB0无脉冲则检查Display_Digits()是否被调用。4.2.1 校准 ADC 偏差修正3300 / 4095比例系数理论计算3300 / 4095 ≈ 0.80586但 Proteus 中ANALOG_SOURCE存在微小建模误差。实测1.23 V输入时ADC1-DR 1528则实际比例系数为1230 / 1528 ≈ 0.8051。修改Convert_To_Voltage()中计算式uint32_t mv (uint32_t)adc_val * 3297 / 4095; // 3297 1230 × 4095 / 1528四舍五入提示此校准值仅对当前 Proteus 版本及ANALOG_SOURCE参数有效。若升级 Proteus 或更换仿真源需重新测量ADC1-DR值并重算系数。真实硬件需用万用表实测基准电压后校准。5. 提升精度与抗干扰添加硬件滤波、软件中值滤波与温度补偿技巧5.1 在 Proteus 原理图中加入 RC 低通滤波器ANALOG_SOURCE输出端串联RESISTOR1 kΩ与CAPACITOR100 nF至地构成截止频率f_c 1/(2πRC) ≈ 159 kHz的一阶低通。该滤波器可抑制 Proteus 仿真中高频数值抖动使PA0波形更平滑。双击电容 →Edit Properties → Capacitance 100n电阻同理。添加后再次观测PA0的Digital Graph可见波动幅度降低约 40%。5.2 替换滑动平均为中值滤波提升抗脉冲干扰能力在强电磁干扰场景如 Proteus 中添加NOISE_SOURCE模拟干扰滑动平均无法消除尖峰。改用 5 点中值滤波uint16_t ADC_Median_Filter(void) { static uint16_t buf[5] {0}; static uint8_t idx 0; uint16_t val Read_ADC_Value(); buf[idx] val; idx (idx 1) % 5; // 简单冒泡排序取中值 uint16_t temp; for (uint8_t i 0; i 4; i) { for (uint8_t j 0; j 4 - i; j) { if (buf[j] buf[j1]) { temp buf[j]; buf[j] buf[j1]; buf[j1] temp; } } } return buf[2]; // 第 3 个值为中值 }参数对比在 Proteus 中注入10% amplitude noise后滑动平均输出波动 ±8 LSB中值滤波仅 ±2 LSB精度提升 4 倍。代价是 CPU 占用增加约 12%但对 STM32F103R672 MHz可忽略。5.3 利用 VREFINT 通道实现温度补偿Proteus 可建模STM32F103 内置VREFINT1.2 V 基准可反映芯片温度变化。Proteus 中STM32F103R6支持ADC1_IN16通道读取该电压// 在 ADC 初始化中添加 VREFINT 通道 ADC1-SQR3 | (16 5); // ADC1_IN16 16追加到规则序列末尾 ADC1-CR2 | ADC_CR2_TSVREFE; // 使能 VREFINT // 读取 VREFINT 值需等待 10 μs 稳定 Delay_us(10); ADC1-CR2 | ADC_CR2_SWSTART; while(!(ADC1-SR ADC_SR_EOC)); uint16_t vrefint ADC1-DR;根据公式Temperature(°C) (V25 - VSENSE) / Avg_Slope 25其中V25 1.41 V25°C 时 VREFINT 典型值Avg_Slope 4.3 mV/°C可在 Proteus 中设置ANALOG_SOURCE电压随温度变化验证补偿效果。实际应用中此功能可将电压表全温区误差从 ±2% 降至 ±0.5%。本文还有配套的精品资源点击获取
返回列表