GD32F303实战:用定时器4和DMA实现ADC定时采集,10秒中断处理1024个数据点

张开发
2026/4/6 2:46:41 15 分钟阅读

分享文章

GD32F303实战:用定时器4和DMA实现ADC定时采集,10秒中断处理1024个数据点
GD32F303精密数据采集实战基于Timer4DMA的ADC高效采样方案在工业传感器监测、电机控制等实时性要求较高的场景中如何实现精准的周期性数据采集一直是嵌入式开发者面临的挑战。传统轮询方式会占用大量CPU资源而简单中断模式又难以保证严格的时间间隔。本文将展示如何利用GD32F303的硬件协同特性构建一个由定时器精确触发、DMA自动搬运的完整数据采集系统。1. 系统架构设计与硬件选型1.1 核心组件协同工作原理这个采集系统的精妙之处在于三个硬件模块的默契配合Timer4作为系统节拍器产生精确的10ms触发信号ADC2负责将模拟信号转换为数字量DMA通道4在后台自动完成数据搬运当Timer4的PWM输出达到设定周期时会自动触发ADC2启动转换转换完成后DMA立即将结果搬运到指定内存区域。整个过程无需CPU干预直到采集满1024个点后DMA才通过中断通知CPU进行批处理。1.2 硬件资源配置依据选择ADC2而非ADC1的主要考虑是其专用DMA通道具有更低的延迟。查看GD32F303参考手册可以发现外设可用触发源对应DMA通道ADC1Timer1/2/3DMA1_CH1ADC2Timer4/5/8DMA1_CH4Timer4的通道0输出特别适合作为ADC触发源因为时钟树配置灵活可来自APB1或内部时钟16位计数器提供更宽的周期调节范围与DMA1_CH4有专用连接通路2. 关键外设配置详解2.1 定时器精准触发配置Timer4的配置需要特别注意三个参数timer_initpara.prescaler 11999; // 预分频值 timer_initpara.period 100-1; // 自动重装载值 timer_channel_output_pulse_value_config(ADC_PWM_TMER, ADC_PWM_CH, 50); // 比较值计算实际触发频率系统时钟120MHz经过119991分频 → 10kHz周期值100-1 → 100us计数周期比较值50 → 50%占空比的PWM 最终得到精确的10ms触发间隔100us × 100提示实际调试时可用逻辑分析仪检查TIMER4_CH0输出波形确保触发间隔准确2.2 ADC多通道扫描模式设置ADC2工作在扫描模式下的关键配置项adc_channel_length_config(ADC_NUM_CH,ADC_REGULAR_CHANNEL, 2); adc_regular_channel_config(ADC_NUM_CH,0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(ADC_NUM_CH,1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);采样时间设置为55.5个ADC时钟周期对于4MHz的ADC时钟120MHz/6/5单次转换时间 55.5 12.5 68周期 → 17us双通道扫描约需34us远小于10ms间隔2.3 DMA循环搬运配置DMA1通道4的配置亮点在于循环缓冲设计dma_init_struct.memory_addr (uint32_t)laser_fre; // 目标地址 dma_init_struct.number LASWER_FRE_NUME*ADC_CHANNEL_NUMER; // 2048个半字 dma_circulation_enable(DMA1, DMA_CH4); // 循环模式这种配置下DMA会在写满2048个数据后自动回到缓冲区起始地址配合中断处理可实现无缝数据拼接。3. 数据采集全流程实现3.1 系统初始化序列正确的初始化顺序对系统稳定性至关重要开启各外设时钟RCU配置GPIO模拟输入配置Timer4基本参数设置DMA通道初始化ADC校准及功能配置最后使能Timer4启动整个系统注意ADC校准必须在DMA使能前完成否则可能导致初始数据异常3.2 中断处理与数据滤波当DMA完成1024个点的采集后触发中断处理流程void DMA1_Channel3_4_IRQHandler(void) { if(dma_interrupt_flag_get(DMA1,DMA_CH4, DMA_INT_FLAG_FTF)) { timer_channel_output_mode_config(ADC_PWM_TMER, TIMER_CH_0, TIMER_OC_MODE_HIGH); dma_interrupt_flag_clear(DMA1,DMA_CH4, DMA_INT_FLAG_G); Lcd_flag.battery_adc_flag true; } }采用中位值平均滤波算法处理采集数据uint16_t filter_bat(uint16_t barray[LASWER_FRE_NUME][ADC_CHANNEL_NUMER],uint8_t len) { // 排序后取中间值平均 for(i 3FILER_MID;i len-3FILER_MID;i) { sum barray[i][0]; } return (sum2); }4. 调试技巧与性能优化4.1 常见问题排查指南现象可能原因解决方案无ADC数据触发信号未到达检查Timer4输出波形数据跳变采样时间不足增加ADC_SAMPLETIMEDMA不触发地址对齐问题确保内存地址是16bit对齐中断不触发优先级冲突检查NVIC配置4.2 系统性能优化建议时钟配置优化将APB1预分频设为1使Timer4获得最大时钟频率ADC时钟不超过14MHz以保证转换精度DMA传输优化dma_init_struct.priority DMA_PRIORITY_ULTRA_HIGH; dma_init_struct.memory_width DMA_MEMORY_WIDTH_16BIT;低功耗设计采集间隔期间可进入WAIT模式使用ADC间断模式减少功耗实际测试表明该方案在120MHz主频下CPU占用率低于5%同时能保证±1us的触发精度。对于需要长时间稳定运行的工业现场这种硬件协同的设计模式展现了GD32F303在实时控制领域的独特优势。

更多文章