# STM32L496_ADC_DMA_MuChannel_Sample **Repository Path**: createskyblue/STM32L496_ADC_DMA_MuChannel_Sample ## Basic Information - **Project Name**: STM32L496_ADC_DMA_MuChannel_Sample - **Description**: STM32L496 双通道50K ADC采样 USB传输示例 - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-06 - **Last Updated**: 2026-08-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # STM32L496 双通道50K ADC采样 USB传输示例 基于正点原子潘多拉STM32L496开发板的ADC DMA采集与USB CDC数据传输示例项目。 ## 项目简介 本项目实现了ADC单通道连续采集,通过DMA双缓冲模式进行数据传输,并使用JustFloat协议通过USB CDC(虚拟串口)将采集的波形数据实时传输到PC端。 **主要功能**: - ADC定时器触发采集 - DMA双缓冲传输 - USB CDC虚拟串口数据传输 - JustFloat协议数据格式 ![alt text](./img/PixPin_2026-01-23_11-13-21.png) ![alt text](./img/PixPin_2026-01-23_11-11-55_87468322.gif) ### 核心特性 - **定时器触发**: TIM1定时器触发ADC采集,采样率稳定 - **DMA 双缓冲模式**: 自动循环接收数据,无需 CPU 干预 - **JustFloat 协议**: 标准化的float数据传输格式,便于PC端解析 - **USB CDC 虚拟串口**: 免驱动的USB通信方式 - **空闲中断**: 检测一帧数据结束,实现可变长数据接收 - **批量操作**: 中断中批量写入数据到用户队列,主循环中批量读取处理 --- ## 硬件平台 | 项目 | 说明 | |------|------| | **开发板** | 正点原子潘多拉 STM32L496 | | **MCU** | STM32L496 | | **主频** | 80MHz (PLL倍频) | --- ## 引脚定义 | 功能 | 引脚 | 备注 | |------|------|------| | ADC1_IN3 | PC2 | 模拟输入通道3 | | ADC1_IN9 | PA4 | 模拟输入通道9 | | DEBUG | PB11 | 调试指示输出(DMA缓冲区切换) | | USB DM | PA11 | USB数据负 | | USB DP | PA12 | USB数据正 | --- ## 技术细节 ### ADC配置 - **分辨率**: 12位 (0-4095) - **参考电压**: 3.3V - **采样通道**: ADC1_IN3 (PC2)、ADC1_IN9 (PA4) - **触发方式**: TIM1_TRGO 上升沿触发 - **采样时间**: 2.5个ADC时钟周期 - **DMA模式**: 循环模式,双缓冲 ### DMA双缓冲机制 ``` ┌─────────────┬─────────────┐ │ 缓冲区前半 │ 缓冲区后半 │ │ (256样本) │ (256样本) │ └─────────────┴─────────────┘ ↑ ↑ HT中断 TC中断 ``` - **半传输中断 (HT)**: 前半缓冲区填满,处理前256个样本 - **传输完成中断 (TC)**: 后半缓冲区填满,处理后256个样本 - **缓冲区大小**: 总共512个样本 (uint16_t) ### JustFloat数据格式 ``` [float电压值(4字节)] [同步字(4字节)] ``` - **float数据**: IEEE 754格式的float电压值(单位:V) - **同步字**: `0x00 0x00 0x80 0x7F` - **协议开销**: 每个样本点8字节(4字节数据 + 4字节同步字) ### 传输速率限制 - **USB CDC 最大速率**: 1 MByte/s - **JustFloat 协议开销**: 每包需要4字节的协议同步尾巴 - **基于USB HS CDC单通道最大传输速率**: 125 kSa/s = (1MB/s传输速率 / (4字节float + 4字节同步字)) ### 数据转换公式 ```c voltage = (ADC_value / 4096.0) * 3.3 ``` > **⚠️ 关于ADC参考电压的说明** > > 本示例代码使用固定的 **3.3V** 作为ADC参考电压进行计算,这是为了保持代码简洁,便于快速理解和演示ADC DMA与USB传输的核心功能。 > > 在**实际工程应用**中,需要注意: > - **电源电压波动**:实际系统的3.3V电源会因负载、温度等因素产生波动(通常在±5%范围内) > - **测量误差**:使用固定参考电压会导致ADC测量结果出现系统性偏差 > - **推荐做法**:对于精度要求较高的应用,建议使用STM32内部的 **VREFINT**(内部参考电压通道)进行实时校准: > 1. 读取内部VREFINT通道的ADC值 > 2. 根据VREFINT的实际值反推出当前的VDDA电压 > 3. 使用计算得到的VDDA_actual替换固定的3.3V进行电压转换 > > 这样可以消除电源电压波动带来的测量误差,显著提高ADC测量精度。 --- ## 使用说明 ### 编译与下载 1. 使用VSCODE打开项目 2. 使用 Cmake + Gcc 编译项目 3. 通过ST-Link连接开发板 4. 下载程序到开发板 5. 用USB线连接开发板到PC ### 波形观察 推荐使用 **JustFloat Web Oscilloscope** 在线示波器工具观察波形: **项目地址**: [createskyblue/justfloat-web-oscilloscope](https://github.com/createskyblue/justfloat-web-oscilloscope) **在线使用**: [https://createskyblue.github.io/JustFloat-Web-Oscilloscope/](https://createskyblue.github.io/JustFloat-Web-Oscilloscope/) **使用步骤**: 1. 用USB线连接开发板到PC(会识别为一个虚拟串口设备) 2. 打开浏览器访问 [JustFloat Web Oscilloscope](https://createskyblue.github.io/JustFloat-Web-Oscilloscope/) 3. 点击连接按钮,选择开发板的USB CDC虚拟串口端口 4. 即可实时观察采集的波形 --- ## 项目结构 ``` ├── Core/ │ ├── Inc/ # 头文件 │ │ ├── main.h # 主程序头文件 │ │ ├── adc.h # ADC配置头文件 │ │ ├── dma.h # DMA配置头文件 │ │ ├── tim.h # 定时器配置头文件 │ │ ├── usart.h # 串口配置头文件 │ │ └── stm32l4xx_it.h # 中断处理头文件 │ └── Src/ # 源文件 │ ├── main.c # 主程序(实现JustFloat数据打包) │ ├── adc.c # ADC配置 │ ├── dma.c # DMA配置 │ ├── tim.c # TIM1配置 │ └── stm32l4xx_it.c # 中断处理 ├── Drivers/ │ ├── CMSIS/ # CMSIS库 │ ├── HAL_Driver/ # HAL库 │ ├── app_drv_fifo/ # FIFO队列驱动 │ └── app_drv_serial_rx/ # 串口DMA接收驱动 ├── Middlewares/ │ └── ST/ # USB CDC中间件 ├── STM32L496_DEMO.ioc # CubeMX配置文件 └── README.md # 本文件 ``` --- ## 开发环境 - **IDE**: Vscode - **工具链**: ARM GCC --- ## 常见问题 ### Q: 波形显示不正常? A: 确认模拟信号连接到PC2(ADC1_IN3)引脚,电压范围0-3.3V。 ### Q: 采样率如何调整? **推荐工具**: [Web-Timer-Helper](https://github.com/createskyblue/Web-Timer-Helper) - 在线定时器配置计算工具 **采样率计算说明**: - **触发方式**: TIM1定时器每次触发,ADC会对规则组中的**所有通道**依次完成一次采样转换 - **示例计算**: - 配置了2个规则通道(IN3、IN9) - 如果定时器触发频率为50kHz - 那么每个通道的采样率都是50kHz(总采样率为50kHz × 2 = 100kSa/s) **计算公式**: ``` 定时器触发频率 = 单通道采样率 TIM1_ARR = (TIM1时钟频率 / 预分频系数) / 目标触发频率 - 1 ``` ![alt text](./img/PixPin_2026-01-23_11-14-48.png) **使用步骤**: 1. 访问 [Web-Timer-Helper](https://createskyblue.github.io/Web-Timer-Helper/) 2. 输入目标频率和定时器时钟(80MHz) 3. 获得推荐的预分频(PSC)和周期(ARR)值 4. 在CubeMX中配置TIM1的PSC和ARR 5. 重新编译烧录程序