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

STM32F103用CubeMX实现ADC欠采样:用800Hz采样率捕获1kHz正弦波的保姆级教程

STM32F103用CubeMX实现ADC欠采样:用800Hz采样率捕获1kHz正弦波的保姆级教程

当信号频率超过奈奎斯特采样定理的限制时,传统方法会要求我们提升采样率。但通过欠采样技术,我们能够以远低于信号频率的采样率捕获高频信号。本文将手把手教你如何在STM32F103上实现用800Hz采样率准确捕获1kHz正弦波。

1. 硬件准备与环境搭建

在开始之前,我们需要准备以下硬件和软件环境:

  • STM32F103C8T6开发板(蓝色药丸板即可)
  • USB转TTL串口模块(用于数据传输)
  • 信号发生器(或能输出1kHz正弦波的设备)
  • STM32CubeMX v6.x
  • Keil MDK-ARM或STM32CubeIDE
  • VOFA+(或其它串口波形显示工具)

提示:如果使用其它STM32F103系列开发板,只需注意引脚兼容性。VOFA+是一款免费的串口数据可视化工具,支持多种协议。

安装好开发环境后,我们先计算几个关键参数:

采样间隔 = 1/800Hz = 1.25ms 等效采样率 = 信号频率 × 每周期采样点数 = 1kHz × 4 = 4kHz

2. CubeMX工程配置

启动CubeMX并按照以下步骤配置:

2.1 时钟树设置

  1. 选择外部晶振(HSE)作为时钟源
  2. 配置系统时钟为72MHz
  3. 设置APB2总线时钟为72MHz(ADC时钟源)

关键参数表

参数
HCLK72MHz
APB136MHz
APB272MHz
ADC预分频6分频
ADC时钟12MHz

2.2 ADC配置

  1. 启用ADC1
  2. 选择"Regular Conversion Mode"
  3. 设置"Data Alignment"为Right
  4. 启用"DMA Continuous Requests"
  5. 配置"Number Of Conversion"为1
// 生成的ADC初始化代码片段 hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1;

2.3 定时器配置(TIM3)

  1. 启用TIM3
  2. 设置时钟源为内部时钟
  3. 配置为"Trigger Output"模式
  4. 设置预分频器(PSC)为999
  5. 设置自动重载值(ARR)为89

定时器参数计算

定时器频率 = 72MHz / (PSC+1) = 72,000Hz 定时周期 = (ARR+1) / 定时器频率 = 90 / 72,000 = 1.25ms 触发频率 = 1 / 1.25ms = 800Hz

2.4 DMA配置

  1. 添加DMA通道(ADC1)
  2. 设置模式为"Circular"
  3. 数据宽度为"Word"
  4. 内存地址递增
// DMA配置示例 hdma_adc1.Instance = DMA1_Channel1; hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_adc1.Init.Mode = DMA_CIRCULAR;

3. 代码实现与调试

生成代码后,我们需要添加一些用户代码来实现完整功能。

3.1 主程序逻辑

#define SAMPLE_SIZE 400 // 采集400个点(约5个周期) uint32_t adcBuffer[SAMPLE_SIZE]; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_TIM3_Init(); HAL_ADC_Start_DMA(&hadc1, adcBuffer, SAMPLE_SIZE); HAL_TIM_Base_Start(&htim3); while (1) { // 数据通过DMA自动采集 // 可通过串口定期发送数据 } }

3.2 串口发送数据

添加串口发送函数,将采集到的数据发送到上位机:

void sendDataToPC(uint32_t *data, uint16_t size) { for(int i=0; i<size; i++) { uint16_t value = data[i] & 0xFFFF; // 取低16位 uint8_t buffer[2]; buffer[0] = value >> 8; buffer[1] = value & 0xFF; HAL_UART_Transmit(&huart1, buffer, 2, HAL_MAX_DELAY); HAL_Delay(1); // 防止发送过快导致丢包 } }

3.3 VOFA+配置

  1. 打开VOFA+,选择串口模式
  2. 设置正确的串口号和波特率
  3. 选择"FireWater"协议
  4. 添加波形显示控件
  5. 设置Y轴范围为0-3.3V(对应ADC值0-4095)

4. 结果分析与优化

当信号发生器输出1kHz正弦波时,我们将在VOFA+上看到类似下图的波形:

采样点分布示例: 周期1:点A(0°) → 周期2:点B(90°) → 周期3:点C(180°) → 周期4:点D(270°) 周期5:点A(0°) → 周期6:点B(90°) → ...

常见问题及解决方案

  1. 波形不连续或错位

    • 检查定时器配置是否正确
    • 确保信号频率准确为1kHz
    • 调整采样点数使其为信号周期的整数倍
  2. ADC值不稳定

    • 添加RC低通滤波电路(如1kΩ电阻+100nF电容)
    • 在代码中添加软件滤波(如移动平均)
  3. 数据传输丢失

    • 降低串口波特率(如改为115200)
    • 增加发送间隔时间

对于更精确的应用,可以考虑以下优化:

  • 使用定时器的主从模式实现更精确的触发
  • 添加硬件触发同步电路
  • 实现自动增益控制(AGC)适应不同幅值信号

在实际项目中,我发现最关键的三个参数是:

  1. 定时器触发间隔的精确性
  2. 信号频率的稳定性
  3. 采样点数与信号周期的匹配关系
http://www.jsqmd.com/news/688263/

相关文章:

  • 在线推荐系统构建:从基础架构到算法优化
  • FlicFlac深度解析:Windows音频格式转换的终极技术指南
  • 深度解析Resemble Enhance:突破性AI语音增强技术实现专业级音频优化
  • 为什么92%的嵌入式团队在VSCode 2026正式版发布72小时内紧急升级调试插件?揭秘DAPv2.3协议兼容性避坑清单
  • 别再让你的CUDA程序慢吞吞了!手把手教你用Memory Coalescing榨干GPU带宽
  • VMware macOS虚拟机终极解锁指南:Unlocker完整使用教程
  • 深入Linux内核:PWM风扇驱动源码解析与中断、定时器协同工作原理
  • Drupal高危漏洞实战:从XSS到RCE的攻防演练
  • 蓝桥杯单片机备赛:从LED到串口,这9个坑我帮你踩过了(附完整代码)
  • 安徽诚鑫物资回收:合肥电线回收源头厂家哪个好 - LYL仔仔
  • LTC6813-1 实战解析:构建高可靠isoSPI菊花链通信网络
  • 第10篇:面向对象总结与最佳实践
  • 十六两的白名单卡、回拨系统、截流引流获客系统、GEO - AI 搜索关键词智能优化系统是什么样的? - 速递信息
  • 硬件视频编码器能耗预测:高斯过程回归模型实践
  • 告别开机卡顿:在Ubuntu桌面版用systemd优雅延迟启动你的Docker或开发环境
  • 3分钟掌握鼠标抖动神器:让Windows电脑永不休眠的终极方案
  • 别再死记硬背for循环语法了!用C#实战打印九九乘法表,5分钟彻底搞懂
  • 2026目的地婚礼哪家好?三亚纪梵希婚纱摄影大理婚纱照产品矩阵解析 - 深度智识库
  • 2026最新临床执业医师考试押题卷哪个好?这个贴心指南请别忘了 - 医考机构品牌测评专家
  • 天价罚单!苹果或被罚 380 亿美元。网友神评:印度赚钱印度花,一分别想带回家
  • 2026耳机全价位选购指南:从入门到旗舰,精准匹配你的预算 - 见闻解构
  • 手把手图解联邦迁移学习(FTL)训练与预测流程:从加密中间结果到秘密共享
  • 中性原子量子模拟:emu-sv与emu-mps仿真器对比
  • 2026年面膜公司推荐榜/糙米面膜,糙米水面膜,糙米发酵面膜,糙米沁透面膜 - 品牌策略师
  • 从SFNet到VIT:手把手拆解PyTorch grid_sample在视觉论文中的核心用法
  • 2026贵州贵阳装修公司口碑排行TOP4,丰立装饰领衔实力认证 - 深度智识库
  • [具身智能-423]:国产AI编程工具分析与对比
  • 高速永磁无刷直流电机控制系统设计与实现
  • 从细菌到植物:手把手教你根据基因组大小,配置你的生信分析‘炼丹炉’(含BWA、Velvet实战配置)
  • null的用法