一、学习路径规划

(一)基础理论阶段(1-2 周)

  1. 模拟电子技术基础复习
  • 重点掌握运算放大器原理、RC 滤波电路、电桥电路等基础电路
  • 理解分压原理、信号放大与电平转换的基本方法

     2.数字电路基础补充

  • 学习 ADC 模数转换的基本原理:采样、保持、量化、编码四个步骤
  • 掌握奈奎斯特采样定理及其在实际工程中的应用

     3.STM32 ADC 模块原理学习

  • 阅读 STM32 数据手册中 ADC 部分,了解 ADC 的主要特性参数
  • 学习 STM32 ADC 的工作模式:独立模式、扫描模式、连续转换模式等
  • 理解 ADC 分辨率、采样率、参考电压等关键指标对采集精度的影响

(二)实践操作阶段(2-3 周)

  1. 开发环境搭建
  • 安装 STM32CubeIDE 或 Keil MDK 开发环境
  • 配置 STM32CubeMX 工具,掌握基本的工程创建流程

    2.硬件平台准备

  • 准备 STM32 开发板(推荐 STM32F103 或 STM32F4 系列)
  • 配备基本的信号源和测量工具:函数发生器、万用表、示波器

    3.基础实验操作

  • 完成单个 ADC 通道的配置与数据采集实验
  • 实现 ADC 多通道轮流采集功能
  • 学习使用不同的触发方式:软件触发、定时器触发、外部中断触发

(三)进阶提高阶段(3-4 周)

  1. 硬件设计与优化
  • 设计简单的信号调理电路,包括滤波、放大、电平转换
  • 学习 PCB 设计中模拟部分的布局布线原则
  • 实践模拟地与数字地的分离技术

    2.数据处理算法实现

  • 实现多种数字滤波算法:均值滤波、中值滤波、滑动平均滤波
  • 学习 ADC 误差分析与校准方法
  • 掌握实际工程中的数据处理与转换技巧

    3.综合项目实践

  • 完成温度采集系统设计与实现
  • 尝试压力、湿度等其他物理量的采集系统开发
  • 实现多通道同步采集系统

二、核心知识要点详解

(一)ADC 基础原理深入理解

  1. 采样定理的工程应用
  • 实际应用中,为保证信号还原质量,通常取采样频率为信号最高频率的 3-5 倍
  • 示例:采集音频信号(最高频率 20kHz),采样频率应设置为 80kHz 以上

    2.量化误差计算

  • 12 位 ADC 的量化单位:\(Q = V_{ref}/4096\)
  • 量化误差范围:\(\pm Q/2\)
  • 示例:3.3V 参考电压下,量化单位为 0.805mV,量化误差约为 ±0.4mV

(二)STM32 ADC 关键特性

  1. ADC 通道与引脚对应关系
  • 以 STM32F103 为例,ADC1 通道 0 对应 PA0 引脚,通道 1 对应 PA1 引脚,依此类推
  • 不同 STM32 型号的 ADC 通道与引脚映射关系可能不同,需查阅对应数据手册

    2.采样时间与转换速度的关系

  • 采样时间设置:ADC_SAMPLETIME_71CYCLES_5 表示采样时间为 71.5 个时钟周期
  • 转换时间计算:转换时间 = 采样时间 + 12.5 个时钟周期(12 位转换)
  • 示例:时钟频率为 14MHz 时,采样时间 71.5 周期约为 5.1us,总转换时间约为 6.0us,采样率约为 167kHz

(三)HAL 库编程核心技巧

  1. ADC 初始化流程优化

// 优化后的ADC初始化函数

void MX_ADC1_Init(void)

{

ADC_ChannelConfTypeDef sConfig = {0};

// ADC基础配置

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; // 时钟分频设置

hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 12位分辨率

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐

hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 禁用扫描模式(单通道)

hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; // 转换序列结束标志

hadc1.Init.ContinuousConvMode = ENABLE; // 连续转换模式

hadc1.Init.NbrOfConversion = 1; // 转换通道数

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发

hadc1.Init.DMAContinuousRequests = DISABLE; // 禁用DMA请求

hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; // 溢出处理方式

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}

// 通道配置

sConfig.Channel = ADC_CHANNEL_10; // 选择通道10(PA0)

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; // 通道排名

sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; // 采样时间设置

sConfig.Offset = 0; // 偏移量设置

if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

{

Error_Handler();

}

}

2.高效数据采集方法


// 带数字滤波的数据采集函数

uint16_t Get_ADC_Value_Filtered(void)

{

uint32_t adc_sum = 0;

uint16_t adc_buffer[10] = {0};

uint8_t i, j, temp;

// 采集10个数据

for(i = 0; i < 10; i++)

{

HAL_ADC_Start(&hadc1);

if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)

{

adc_buffer[i] = HAL_ADC_GetValue(&hadc1);

}

HAL_ADC_Stop(&hadc1);

}

// 中值滤波:排序

for(i = 0; i < 9; i++)

{

for(j = 0; j < 9 - i; j++)

{

if(adc_buffer[j] > adc_buffer[j+1])

{

temp = adc_buffer[j];

adc_buffer[j] = adc_buffer[j+1];

adc_buffer[j+1] = temp;

}

}

}

// 去掉最大值和最小值,取中间8个值的平均值

for(i = 1; i < 9; i++)

{

adc_sum += adc_buffer[i];

}

return (uint16_t)(adc_sum / 8);

}

三、实践项目指导

(一)基础项目:模拟电压采集显示系统

  1. 项目需求
  • 采集 0-3.3V 模拟电压信号
  • 在 LCD 上实时显示电压值
  • 精度要求达到 0.01V

    2.硬件设计

  • 信号输入:通过电位器分压提供 0-3.3V 可调电压
  • 显示模块:OLED 或 LCD1602
  • 参考电压:使用 STM32 内部参考电压或外部高精度参考源

   3.软件实现


// 电压转换与显示函数

void Display_Voltage(void)

{

uint16_t adc_value;

float voltage;

char display_buffer[20];

// 获取ADC值

adc_value = Get_ADC_Value_Filtered();

// 转换为电压值(参考电压3.3V)

voltage = (float)adc_value * 3.3 / 4096;

// 格式化显示字符串

sprintf(display_buffer, "Voltage: %.2fV", voltage);

// 在LCD上显示

LCD_Clear();

LCD_SetCursor(0, 0);

LCD_PrintString(display_buffer);

}

(二)进阶项目:多通道温度采集系统

  1. 系统架构
  • 传感器:4 路 PT100 热电阻
  • 信号调理:4 路电桥电路 + 仪表放大器
  • 显示模块:LCD 触摸屏
  • 通信接口:USB 或蓝牙,用于数据上传

   2.温度计算优化


// 改进的温度计算函数(考虑线性补偿)

float Calculate_Temperature(uint16_t adc_value, uint8_t channel)

{

float voltage, resistance, temperature;

float A = 3.9083e-3, B = -5.775e-7;

float compensation = 0;

// 根据通道选择不同的补偿系数(考虑通道差异)

switch(channel)

{

case 0: compensation = 0.1; break;

case 1: compensation = 0.2; break;

case 2: compensation = 0.15; break;

case 3: compensation = 0.05; break;

default: compensation = 0;

}

// 计算电压和电阻

voltage = (float)adc_value * 3.3 / 4096;

resistance = 100 * voltage / (3.3 - voltage);

// 计算温度(使用二次方程求根公式)

temperature = (-A + sqrt(A*A - 4*B*(1 - resistance/100))) / (2*B);

// 加入补偿

temperature += compensation;

return temperature;

}

四、学习资源推荐

(一)硬件资源

  1. 开发板

  • STM32F103C8T6 开发板(入门级,性价比高)
  • STM32F407VET6 开发板(进阶型,功能更强大)

   2.传感器套件

  • 模拟传感器套件(包含温度、压力、湿度等传感器)
  • PT100 热电阻及调理电路模块

(二)软件资源

  1. 开发工具
  • STM32CubeMX(图形化配置工具)
  • STM32CubeIDE(集成开发环境)
  • Keil MDK(经典嵌入式开发工具)

 

   2.参考代码

  • STM32 官方 HAL 库例程
  • STM32Cube_FW_F1 固件库(针对 F1 系列)
  • 开源项目中的 ADC 应用代码(如 GitHub 上的相关项目)

(三)学习资料

  1. 书籍
  • 《STM32 库开发实战指南》
  • 《深入浅出 STM32》
  • 《模拟电子技术基础》(童诗白)
  • 《数字电子技术基础》(阎石)

    2.在线教程

  • 慕课网:STM32 单片机原理及应用
  • 哔哩哔哩:STM32 ADC 数据采集专题教程
  • 博客园:STM32 开发系列博客(推荐关注嵌入式相关博主)

五、常见问题与解决方案

(一)硬件问题

  1. 问题现象:ADC 采集值波动较大,不稳定
  • 可能原因:电源纹波大、接地不合理、信号线受干扰
  • 解决方案:
  • 增加电源滤波电容,使用低纹波电源
  • 优化接地设计,确保模拟地与数字地正确连接
  • 缩短信号线长度,必要时使用屏蔽线

   2.问题现象:采集值与实际值偏差较大

  • 可能原因:参考电压不准、信号调理电路误差、ADC 未校准
  • 解决方案:
  • 使用高精度参考源,并定期校准参考电压
  • 检查信号调理电路参数,确保放大倍数正确
  • 在程序中加入 ADC 校准函数,定期进行偏移校准

(二)软件问题

  1. 问题现象:ADC 转换速度达不到预期
  • 可能原因:时钟配置不正确、采样时间设置过长、程序中存在阻塞
  • 解决方案:
  • 检查 ADC 时钟分频设置,确保时钟频率足够
  • 优化采样时间设置,在精度和速度间找到平衡
  • 改用 DMA 方式传输数据,避免 CPU 阻塞

   2.问题现象:多通道采集时通道间干扰严重

  • 可能原因:扫描模式配置不当、通道切换时间不足
  • 解决方案:
  • 合理配置扫描模式,确保通道切换时有足够的稳定时间
  • 增加通道间的采样间隔,或使用独立的 ADC 模块进行采集

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐