你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32H563 ADC+TIM+DMA应用演示

[复制链接]
攻城狮Melo 发布时间:2026-6-18 16:26

我这里基于STM32H563的开发板和STM32HAL库,以及STM32CubeMx配置工具,演示一下ADC+TIM+DMA的实现过程。具体实现是这样的:

有8个ADC通道工作在单次扫码模式,由TIM3的更新事件触发启动之,ADC的结果由DMA搬运到指定内存,同时还要测量每次8个ADC通道转换完成所用的时间。

image.png

如上图所示,TIM3工作在向上计数模式,图中红色箭头表示TIM3发生更新事件的时间点,蓝色箭头表示每8个通道转换完成的时间点。下面实现过程中用DMA完成事件替代8通道转换完成事件。根据目前设计,我们只要在DMA完成中断里读取触发定时器的计数器的值即可得到每轮8个通道转换所用的时间。

下面开始使用STM32CubeMx进行各种初始配置。系统主频配置在200Mhz,TIMER使用200Mhz系统时钟作为时钟源【主频其实可以配置到250MHz】。

image.png

现在对TIM3进行配置,选择其更新事件作为TRGO信号,用来触发启动ADC。

image.png

根据上面时基参数的配置,TIM3的计数频率为1Mhz,即每一个计数脉冲对应1us,计数溢出周期为20ms。TIM3将按此周期定时触发启动ADC。

下面是ADC的基本配置,具体用到ADC1的8个通道的规则转换。

image.png

为了便于测试和计算,我这里将8个通道的ADC参数除了RANk顺序外,其它都配置得一样,并启用DMA循环传输功能。

image.png

image.png

下面是有关DMA的配置,使用DMA标准请求模式,外设到内存的传输方向,工作在循环模式。

image.png

完成配置后创建工程,添加用户代码。

这里定义了两个32位变量,分别用于存放ADC转换结果和记录每轮ADC转换所用时间,单位是us。

/ USER CODE END 2 /

uint32_t ADC_Result[8]; //存放ADC转换结果

volatile uint32_t ElapsedByADC[8];//记录每轮ADC转换所用时间

/ USER CODE BEGIN 2 /

HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);

__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);

__HAL_ADC_CLEAR_FLAG(&hadc1, ADC_FLAG_EOC);

HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Result, 8);

HAL_TIM_Base_Start(&htim3);

在DMA传输完成中断回调函数里记录每一轮ADC转换所用时间:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)

{

static uint8_t i=0;

if (i==8) i= 0;

ElapsedByADC[i]= TIM3->CNT ((TIM3->PSC +1)/200); / us unit */

i++;

}

下面是测试结果的截图【因最后两个ADC通道是测试的两个内部信号,其结果比较稳定,其它ADC输入管脚都是浮空状态】:

image.png

从当前测试结果来看,每8个ADC通道转换完成所用时间为100us,结果也稳定。

我们不妨根据ADC目前参数,计算下它该花多少时间。现在每个通道的采样时间都是247.5个ADC clock,加上转换时间12.5个clock,那么每个通道单次总转换时间为260个ADC clock。现在ADC的转换时钟为200MHz的10分频,即20MHz。算下来8个通道的总转换时间应该是104us的样子。

image.png

现在是理论计算结果比实测要大些,有点偏差,但误差不大。这个误差会不会跟我所用TIMER的计数精度有关呢?前面的TIM3的计数频率为1MHz,如果我把计数频率提升到10MHz,其它参数不动,看看结果会怎么样?【这样调整后TIM3的溢出周期变短了,但依然远长于ADC一轮转换所需要的时间】

我们再来看看调整TIM3计数频率后的的结果:

image.png

不难看出,此次的测试结果跟刚才的理论计算值就非常接近了,实测值比计算值稍微大一点也是合理的,毕竟基于DMA传输完成中断服务代码获取时间的动作要比ADC实际转换完成晚些。

一般来讲,ADC的转换时间是不需要专门来测量的。除非个别调试场合的确需要确认验证外,其它时候或许是出于好奇想测测。其实,这种测试方法也不总是靠谱,在上面实验过程中我们注意到统计时间的计时分辨率就对结果就有影响。如果不是被测时间较长的话,就不要使用系统滴答个数来统计。在STM32工程里,通常系统的滴答计时分辨率为1ms。

再比方,如果系统中DMA请求及响应很多而频繁,用于搬运ADC结果的DMA通道优先级又偏低,或者说系统中的中断频繁,而DMA传输完成中断的优先级又偏低,这都会影响测试结果,影响程度视情况而定。

刚好最近跟其他人谈及相关话题,就此顺便做个分享以供参考。

文章出处:茶话MCU [/i]

image.png
收藏 评论0 发布时间:2026-6-18 16:26

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版