STM32F407 ADC_DMA 3通道配置:中断与轮询模式对比
1. 模式概述
-
中断模式
当DMA完成数据传输时触发中断,CPU暂停当前任务处理数据。
公式:中断延迟时间 $t_{int} = t_{isr} + t_{ctx}$
($t_{isr}$=中断服务时间,$t_{ctx}$=上下文切换时间) -
轮询模式
CPU主动检查DMA传输状态标志位,占用CPU资源但无中断开销。
2. CubeMX配置步骤
公共配置(两种模式相同):
- ADC设置
- 启用扫描模式(Scan Mode Enable)
- 启用连续转换(Continuous Conversion Mode)
- 设置3个通道的采样时间(如通道0/1/2)
- DMA设置
- 添加DMA请求(Peripheral To Memory)
- 数据宽度:半字(Half Word,匹配12位ADC)
- 存储器地址递增(Memory Increment Enable)
// 公共初始化代码(CubeMX生成) hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.ContinuousConvMode = ENABLE;
模式专属配置:
| 配置项 | 中断模式 | 轮询模式 |
|---|---|---|
| DMA中断 | 使能传输完成中断(TCIE) | 关闭所有DMA中断 |
| NVIC设置 | 启用DMAx Streamx全局中断 | 无需NVIC配置 |
| 代码触发方式 | HAL_ADC_Start_DMA(&hadc1, ...) | HAL_ADC_Start(&hadc1) + 轮询状态 |
3. 代码实现对比
中断模式示例:
// 重写DMA传输完成回调函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
uint32_t adc_values[3]; // 存储3通道数据
// 处理数据(例如FFT计算)
process_data(adc_values);
}
轮询模式示例:
while (1) {
HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK) {
adc_val[0] = HAL_ADC_GetValue(&hadc1);
// 重复读取3个通道
}
}
4. 性能对比分析
$$ \text{CPU利用率} = \frac{t_{\text{active}}}{t_{\text{total}}} \times 100% $$
-
中断模式
- ✅ 实时性高(响应延迟$<1\mu s$)
- ✅ 低空闲CPU占用
- ❌ 中断冲突风险(需优先级管理)
-
轮询模式
- ✅ 实现简单(无中断嵌套问题)
- ✅ 确定性延迟(适合固定周期任务)
- ❌ CPU利用率高(典型值$>30%$)
5. 选型建议
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 高速数据采集(>100ksps) | 中断 | 避免轮询导致的采样丢失 |
| 低速传感器(<1ksps) | 轮询 | 简化架构,降低中断管理复杂度 |
| 多外设协同系统 | 中断 | 通过优先级协调资源占用 |
关键参数公式:
最大采样率 $f_{max} = \frac{1}{t_{conv} \times N}$
($N$=通道数,$t_{conv}$=单次转换时间)
中断模式支持更接近 $f_{max}$ 的实际采样率。

被折叠的 条评论
为什么被折叠?



