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

STM32 ADC实战:用一块电位器+OLED,5分钟搞定电压表(附完整代码)

STM32 ADC实战:用一块电位器+OLED,5分钟搞定电压表(附完整代码)

当你想测量某个引脚的电压值时,STM32的ADC模块就是你的数字万用表。本文将带你用最简硬件(一个电位器+OLED屏幕)和清晰代码,快速实现可调电压的实时监测。无需复杂理论,直接动手感受模拟信号到数字世界的转换魅力。

1. 硬件准备与电路连接

所需材料清单

  • STM32F103C8T6核心板(其他型号亦可)
  • 10kΩ电位器
  • 0.96寸OLED显示屏(I2C接口)
  • 杜邦线若干

电路连接示意图

3.3V ────┬─────── OLED_VCC │ [10kΩ] │ Wiper ─── PA0 (ADC输入) │ GND ─────┴─────── OLED_GND

电位器两端分别接3.3V和GND,中间滑动端接STM32的PA0引脚(ADC通道0)。OLED的SCL、SDA分别接PB6、PB7,电源接3.3V和GND。

注意:确保ADC输入电压不超过3.3V,否则可能损坏芯片。电位器阻值建议选择1kΩ-50kΩ范围。

2. 软件环境配置

首先在STM32CubeIDE中新建工程,配置关键参数:

  1. ADC配置

    • 模式:Independent mode
    • 数据对齐:Right alignment
    • 扫描模式:Disabled
    • 连续转换:Disabled
    • 触发方式:Software trigger
    • 采样时间:55.5 cycles
  2. I2C配置(用于OLED):

    • 标准模式(100kHz)
    • 无地址检测
  3. GPIO配置

    • PA0设为模拟输入
    • PB6(I2C1_SCL)、PB7(I2C1_SDA)设为复用开漏输出

生成代码后,添加OLED驱动库(如SSD1306)到项目。以下是关键初始化代码片段:

void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 72MHz HCLK配置 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); }

3. ADC数据采集实现

ADC采集的核心在于原始值到实际电压的转换。STM32的12位ADC输出范围0-4095对应0-3.3V电压:

uint16_t Read_ADC(ADC_HandleTypeDef* hadc) { HAL_ADC_Start(hadc); if (HAL_ADC_PollForConversion(hadc, 10) == HAL_OK) { return HAL_ADC_GetValue(hadc); } return 0; } float ADC_To_Voltage(uint16_t adcValue) { return (adcValue * 3.3f) / 4095.0f; }

电压测量精度优化技巧

  1. 多次采样取平均:
#define SAMPLE_TIMES 16 uint16_t Get_Stable_ADC(ADC_HandleTypeDef* hadc) { uint32_t sum = 0; for (int i=0; i<SAMPLE_TIMES; i++) { sum += Read_ADC(hadc); HAL_Delay(1); } return sum / SAMPLE_TIMES; }
  1. 参考电压校准(若板载有REF引脚):
float vref = 1.2f; // 内部参考电压典型值 float actual_vdd = (vref * 4095) / adc_ref_value;

4. OLED动态显示实现

结合SSD1306驱动库,创建电压显示界面:

void Show_Voltage(float voltage) { char str[16]; OLED_Clear(); // 标题 OLED_ShowString(0, 0, "STM32 Voltmeter", 16); // 原始ADC值 OLED_ShowString(0, 2, "ADC:", 16); sprintf(str, "%4d", adc_value); OLED_ShowString(32, 2, str, 16); // 电压值 OLED_ShowString(0, 4, "Voltage:", 16); sprintf(str, "%5.2fV", voltage); OLED_ShowString(64, 4, str, 16); // 进度条 uint8_t len = (uint8_t)(voltage * 30 / 3.3); OLED_DrawRectangle(0, 6, 127, 7); OLED_Fill(0, 6, len, 7, 1); OLED_Refresh(); }

显示效果优化

  • 添加波动指示器(←→表示稳定)
  • 电压超限警告(如>3.0V时显示!)
  • 最小/最大电压记录功能

5. 完整代码整合

主循环实现周期性采集与显示:

int main(void) { HAL_Init(); SystemClock_Config(); // 外设初始化 MX_GPIO_Init(); MX_I2C1_Init(); MX_ADC1_Init(); OLED_Init(); uint16_t adc_value; float voltage; while (1) { adc_value = Get_Stable_ADC(&hadc1); voltage = ADC_To_Voltage(adc_value); Show_Voltage(voltage); HAL_Delay(200); // 控制刷新率 } }

扩展功能实现

  1. 按键控制采样速率
  2. 电压变化趋势图
  3. 通过串口输出数据到PC
  4. 阈值报警功能(如LED闪烁)

6. 常见问题排查

ADC读数不稳定

  • 检查电源滤波(在VDD与GND间加0.1μF电容)
  • 增加采样时间(可尝试239.5 cycles)
  • 确保电位器接触良好

OLED无显示

  • 确认I2C地址(通常0x78或0x7A)
  • 检查上拉电阻(4.7kΩ到3.3V)
  • 验证初始化时序正确

电压测量偏差

// 校准公式示例 float calibrated_voltage = (raw_voltage * 3.3f) / 4095 * calibration_factor;

实测中发现,当旋转电位器时,OLED上的电压值应平滑变化。如果出现跳变,可尝试在PA0与GND之间添加100nF电容以滤除噪声。

http://www.jsqmd.com/news/756386/

相关文章:

  • Bili2text终极指南:3分钟将B站视频转为可编辑文字稿
  • 阴阳师百鬼夜行自动化脚本:5分钟快速上手终极指南
  • 实战演练:基于快马平台构建触发403 forbidden的简易权限管理系统
  • 用E4A和HC-05蓝牙模块,从零到一做个手机遥控小车的APP(附完整源码)
  • NS-USBLoader完整使用指南:Switch游戏文件传输与管理的终极解决方案
  • C# 语言基础:从零构建编程思维的基石
  • 从审稿人角度看GEOPHYSICS:你的论文格式为什么总被挑刺?
  • Sunshine终极指南:8个快速解决游戏串流问题的完整方案
  • 告别繁琐配置:用快马AI智能生成多平台软件安装包,效率提升十倍
  • 2026 镇江黄金回收优选:福正美线上线下双轨,全区域覆盖 - 福正美黄金回收
  • 如何让2008年的MacBook Pro运行macOS Sequoia?OpenCore Legacy Patcher的魔法解密
  • ESP8266——TCP客户端
  • 如何用import_3dm实现Rhino到Blender的无缝衔接:5个关键场景全解析
  • FPGA加速Ising问题分解的混合架构设计与优化
  • 3个AMD Ryzen性能瓶颈,如何用SMUDebugTool精准诊断与优化?
  • 高级显卡配置管理框架:NVIDIA Profile Inspector深度解析与性能调优指南
  • YetAnotherKeyDisplayer:5分钟掌握终极按键可视化方案
  • 揭秘大润发购物卡回收技巧,快速变现! - 团团收购物卡回收
  • 八边封袋价格是多少?中北包装来解答 - myqiye
  • Windows游戏手柄兼容性终极解决方案:ViGEmBus驱动完全指南
  • obs-multi-rtmp的3个高阶应用:解决多平台直播同步难题
  • 别再瞎调PID了!手把手教你用示波器+电桥实测2804无刷电机参数(电感/电阻/极对数)
  • 别再硬编码了!用Vue Router + el-menu动态生成后台管理系统左侧菜单(附完整代码)
  • 四川农业大学考研辅导班推荐:排名深度评测与选哪家分析 - michalwang
  • 从抓包到出结果:一份给新手的Kali+Hashcat破解WiFi握手包避坑清单(附hc22000格式最新转换指南)
  • Arm SME架构系统寄存器详解与编程实践
  • 潍坊翔鹰航空,靠谱的青少年无人机培训加盟品牌 - myqiye
  • 如何在 Compose 中配置 Redis 持久化存储 volume 路径
  • 将编程助手 Claude Code 无缝对接至 Taotoken 聚合平台
  • 2026年工业盐渠道排名,选购有哪些技巧? - myqiye