一、为什么需要HT与TC中断配合?
在STM32中使用ADC+DMA进行连续转换时,DMA通常配置为循环模式,自动将ADC数据搬运到指定内存数组。若只使用传输完成中断(TC),则必须等待整个缓冲区填满才能处理数据,导致:
- 数据处理延迟大,实时性差;
- 若处理速度跟不上采集速度,新数据会覆盖未处理数据;
- 无法实现“乒乓”式分块处理。
半传输中断(HT) 在DMA传输完成一半时触发,与TC中断配合,可将缓冲区分为前后两块,实现“采集一块、处理另一块”的流水线操作,显著提高系统响应速度与数据安全性。
二、DMA双缓冲与分块原理
假设ADC采集缓冲区大小为 BUFFER_SIZE(偶数),DMA循环模式下的传输过程:
- DMA从外设(ADC)搬运数据到内存,计数器递减;
- 当传输过半(即搬运了
BUFFER_SIZE/2个数据)时,触发HT中断; - 当传输全部完成(
BUFFER_SIZE个数据)时,触发TC中断,同时DMA自动重装载计数器,开始下一轮循环。
因此,HT中断时前半缓冲区 [0, BUFFER_SIZE/2-1] 已满,可安全处理;TC中断时后半缓冲区 [BUFFER_SIZE/2, BUFFER_SIZE-1] 已满。两者交替,实现连续无缝处理。
注意:HAL库中DMA中断回调为
HAL_ADC_ConvHalfCpltCallback()和HAL_ADC_ConvCpltCallback(),分别对应HT和TC。
三、CubeMX配置步骤
- ADC配置:选择连续转换模式(Continuous Conversion Mode = Enabled),DMA连续请求(DMA Continuous Requests = Enabled);
- DMA配置:添加ADC对应的DMA通道,模式设为Circular,数据宽度根据ADC分辨率选择(通常Half Word),内存地址自增;
- NVIC配置:使能DMA通道的HT和TC中断;
- 生成代码:HAL库会自动初始化并启动ADC+DMA。
四、完整代码示例
#include "main.h"
#define BUFFER_SIZE 256
#define HALF_SIZE (BUFFER_SIZE / 2)
uint16_t adc_buffer[BUFFER_SIZE];
volatile uint8_t half_ready = 0;
volatile uint8_t full_ready = 0;
/* HT中断回调:前半缓冲区就绪 */
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1) {
half_ready = 1;
// 可在此处快速处理前半数据,或置标志由主循环处理
// process_data(&adc_buffer[0], HALF_SIZE);
}
}
/* TC中断回调:后半缓冲区就绪 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1) {
full_ready = 1;
// 可在此处快速处理后半月数据
// process_data(&adc_buffer[HALF_SIZE], HALF_SIZE);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
// 启动ADC+DMA连续转换
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, BUFFER_SIZE);
while (1) {
if (half_ready) {
half_ready = 0;
// 处理前半缓冲区数据(此时DMA正在填充后半部分)
process_data(&adc_buffer[0], HALF_SIZE);
}
if (full_ready) {
full_ready = 0;
// 处理后半缓冲区数据(此时DMA已重新开始填充前半部分)
process_data(&adc_buffer[HALF_SIZE], HALF_SIZE);
}
}
}
五、注意事项
- 缓冲区大小必须为偶数,否则HT中断位置不准确;
- 中断回调中避免耗时操作,建议只置标志位,由主循环或RTOS任务处理数据;
- 数据一致性:处理某半区时,DMA不会写入该半区(循环模式下HT/TC交替),但若处理时间超过半缓冲区采集时间,仍可能被覆盖,需评估采样率与处理速度;
-
HAL库版本差异:部分系列(如G0/G4)DMA中断回调可能需通过
HAL_DMA_IRQHandler间接调用,确保在stm32fxx_hal_msp.c中正确使能中断; - 调试时:可在HT/TC回调中翻转GPIO,用示波器观察中断频率,验证分块时序;
- 若使用RTOS:可在回调中释放信号量,由任务处理数据,避免在中断上下文中进行复杂运算。
六、总结
通过HT与TC中断的配合,ADC+DMA连续转换可实现高效的双缓冲分块处理,既保证了数据采集的连续性,又为数据处理留出了充足时间。掌握这一模式,是开发高性能数据采集系统的关键技能。
暂无评论,来抢沙发~