DAC DMA停止和启动之间的差距
我有一个1000字节的数组,在HAL_DAC_START_DMA函数中调用,启动DAC DMA触发定时器。在DAC DMA的半完成回调时,我从SD卡内的文件中读取下一个1000字节,在完成DAC DMA回调时,停止触发计时器,停止DAC DMA并将新的1000字节重新加载到HAL_DAC_START_DMA函数中,然后再次启动计时器。// audio out function main bitsmemset((void *) DacAudioBuffer.Audio16BitBuffer, 0, sizeof(DacAudioBuffer.Audio16BitBuffer));memcpy((void *) DacAudioBuffer.Audio16BitBuffer, (void *) DacAudioBuffer.Temp16AudioBuffer, sizeof(DacAudioBuffer.Temp16AudioBuffer)); HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *) DacAudioBuffer.Audio16BitBuffer, BuffSize, DAC_ALIGN_12B_R);HAL_TIM_Base_Start_IT(&htim2); // DAC DMA half out call backIsDacDataHalfOut = TRUE; // DAC DMA complete call backif(HAL_TIM_Base_Stop_IT(&htim2) == HAL_OK) { if(HAL_DAC_Stop_DMA(hdac, DAC_CHANNEL_1) == HAL_OK) {} IsDacDataCpltOut = TRUE;}我的主要问题是,当我停止计时器和重新启动它之间有一个时间差。我从文件中阅读的数据是音频字节,希望这些波形能完美地融合在一起,但随着时间的推移,时间差变得越来越大。如下图请教如何解决https://community.st.com/t5/image/serverpage/image-id/25733iFA72C6DC09D2D9FF/image-size/large?v=v2&px=999https://community.st.com/t5/image/serverpage/image-id/25734i92F9D3A065EF0DEE/image-size/large?v=v2&px=999DMA 停止后,DAC 输出会保持最后一个数据值,直到 DMA 重新启动并填充新数据
DMA 停止/启动需要 软件干预,耗时约 几微秒~几十微秒
硬件状态不同步的常见表现为DMA 传输完成标志(TC)未正确清除,DAC 未及时进入空闲状态,缓冲区指针未复位到起始地址
// 在 DMA 传输一半和完成中断中切换缓冲区
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)buf0, 256, DAC_ALIGN_12B_R);
// 在中断中动态修改缓冲区地址
使用 DAC 内置 FIFO可以在 DMA 暂停期间由 FIFO 维持输出
避免完全停止 DMA,改用 动态缓冲区更新
// 暂停时降低 TIMER 频率以减少数据消耗
__HAL_TIM_SET_AUTORELOAD(&htim6, new_reload_value);
可以使用软件做补偿,比如:
// 在停止前写入一个渐变到 0 的序列
for(int i=0; i<10; i++) {
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ramp_down);
HAL_Delay(1);
}
通过合理选择硬件特性和软件策略,可将 DAC DMA 启停间隙控制在 <1μs 级别
不同的模式下,他们的区别是不一样的
页:
[1]