STM32 NUCLEOF334R8 DAC频率异常及ARR含义技术咨询
STM32 NUCLEOF334R8信号生成问题排查与ARR解释
问题概述
使用STM32 NUCLEOF334R8开发板生成200Hz信号时遇到两个问题:
- 变量
hasil始终等于output_end=2000; - 达到目标频率后,转动电位器调节时示波器信号偶尔消失。
代码问题排查
1. hasil值异常的原因
整数运算顺序错误
你的映射计算式顺序存在逻辑缺陷:
hasil = (output_end - output_start) / (input_end - input_start) * (input - input_start) + output_start;
由于(output_end - output_start)=1900,(input_end - input_start)=4095,整数除法会直接截断小数部分,1900/4095的结果为0。后续乘以(input - input_start)仍为0,理论上hasil应等于100,但你反馈其始终为2000,说明input的值始终是ADC最大值4095,结合以下问题:
ADC读取异常或配置错误
- 变量重复定义:全局区域同时定义了
uint16_t i;和uint16_t i = 0;,编译时会引发变量重定义错误,导致循环逻辑异常,可能使AD_RES[0]始终被赋值为最大值; - 采样时间不足:你设置的
ADC_SAMPLETIME_1CYCLE_5仅1.5个ADC时钟周期,对于电位器这类模拟输入,采样时间过短会导致读数不准或固定为最大值; - 通道映射错误:若电位器未正确连接到
ADC_CHANNEL_6(AD_RES[0]对应的通道),会导致input始终为ADC满量程值4095,此时即使运算顺序错误,最终hasil会被计算为2000。
正确的映射计算应调整运算顺序,先乘法后除法避免截断:
hasil = output_start + (output_end - output_start) * (input - input_start) / (input_end - input_start);
2. 信号偶尔消失的原因
- TIM寄存器修改时序问题:直接调用
__HAL_TIM_SET_AUTORELOAD(&htim2, hasil)修改ARR时,若TIM2未配置预装载寄存器(ARR_PRELOAD_DISABLE),修改会立即生效,可能导致计数器溢出时序混乱,中断DAC的DMA触发; - 系统阻塞影响:
HAL_Delay(500)会占用CPU核心,阻塞其他外设的中断响应,可能导致TIM或DMA的触发事件丢失; - DMA与TIM同步问题:修改ARR时未暂停DAC的DMA传输或TIM计数,导致DMA传输的触发节奏突然变化,引发传输中断,进而使信号消失。
修复建议:
- 若TIM2配置了预装载,确保
TIM_CR1.ARPE位使能,让ARR修改在下一个更新事件生效; - 修改ARR前先暂停TIM和DAC DMA,修改完成后重新启动:
HAL_DAC_Stop_DMA(&hdac1, DAC_CHANNEL_1); HAL_TIM_Base_Stop(&htim2); __HAL_TIM_SET_AUTORELOAD(&htim2, hasil); HAL_TIM_Base_Start(&htim2); HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)WaveLUT, 225, DAC_ALIGN_12B_R); - 缩短
HAL_Delay时长或改用非阻塞方式读取ADC,避免系统长时间阻塞。
ARR(自动重装载寄存器)含义
自动重装载寄存器(ARR)是STM32定时器的核心寄存器之一,用于存储定时器计数器的最大值:
- 当定时器工作在向上计数模式时,计数器从0开始递增,当数值等于ARR的值时,会触发更新事件(溢出),随后计数器自动重置为0,开始新一轮计数;
- 定时器的触发频率由ARR和预分频器(PSC)共同决定,公式为:
你通过TIM触发DAC DMA输出波形,因此ARR的值直接决定了波形的输出频率——每个更新事件会触发DMA将定时器更新频率 = 定时器时钟频率 / [(PSC + 1) * (ARR + 1)]WaveLUT的下一个值送入DAC,ARR越小,更新频率越高,波形输出频率也越高。
内容的提问来源于stack exchange,提问作者Meria Rajagukguk
相关产品推荐
相关产品推荐

