多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

STM32 DAC 实战:用 DMA 把定时器表变成波形,自制信号发生器

STM32 DAC 实战:用 DMA 把定时器表变成波形,自制信号发生器 想用 STM32 出个正弦波、三角波、或者可调频的方波最常用的笨办法是在主循环里一步步算好值、写进 DAC 数据寄存器。CPU 被这事儿占满不说频率稍微高点波形就锯齿得没法看。正确的玩法是让 DAC 自己按节奏出数定时器当节拍器每隔固定时间触发一次 DAC 转换DMA 把一张预先算好的波形表自动搬过去。CPU 只管生成那张表之后彻底脱手。这篇文章把 DAC 定时器触发 DMA 波形发生讲清楚以及那些让波形失真、频率算错的坑。DAC 到底在干什么DAC数模转换器把一个数字量变成模拟电压。STM32 多数型号带 1~2 路 DAC分辨率 12 位输出 0 到 VREF 之间的电压。最基础用法是HAL_DAC_SetValue写一个值输出立刻变。但手动写值的瓶颈在 CPU你想出 1kHz 正弦波一个周期至少几十个点每秒就得写几万次主循环啥也别干了。解法是用定时器触发和DMA定时器按你设定的频率产生触发事件比如溢出每次触发让 DAC 转换下一个数据DMA 自动从波形表取下一个值送进 DAC 寄存器取完一圈自动回绕整个过程 CPU 不参与数据搬运只偶尔更新一下波形表或频率参数。波形表和定时器触发先在内存里放一张正弦波表比如 256 个点值是 12 位范围内按正弦算好的#defineN256uint16_tsine[N];for(inti0;iN;i){// 12位 DAC中点 2048幅度 2047sine[i](uint16_t)(20482047*sin(2*PI*i/N));}配置定时器触发 DAC。以 TIM6 作触发源它的溢出频率决定每个点间隔进而决定输出波形频率波形频率 定时器触发频率 / 表长 N (TIM_CLK / (PSC1) / (ARR1)) / N比如表长 256想出 1kHz 波形触发频率就得是 256kHz。反过来用这个公式去算 PSC 和 ARR。启动HAL_TIM_Base_Start(htim6);// 定时器开始产触发HAL_DAC_Start_DMA(hdac,DAC_CHANNEL_1,(uint32_t*)sine,N,DAC_ALIGN_12B_R);// DMA 自动送表DAC_ALIGN_12B_R是右对齐 12 位格式波形表就按这个对齐准备。DMA 在 Circular 模式下自动回绕波形就持续不断地出。输出缓冲和幅度DAC 内部有输出缓冲放大器开启后驱动能力强、带负载稳但会吃掉一点电压余量到不了轨。关闭缓冲直接输出摆幅更满但源阻抗高后面不接运放就带不动负载。想要任意幅度和偏移单靠 DAC 不够。常见做法是 DAC 出 0~3.3V 的波形再经过一级运放做缩放和电平平移。比如要 ±5V 输出DAC 先出 0~3.3V 中点 1.65V运放做 2 倍增益、减去偏置得到 ±5V。十个坑波形丑基本都在这触发源没配对。DAC 的触发源要在 CubeMX 里选成对应定时器比如 TIM6 TRGO没选或选错DAC 不转输出一直是上次的值。波形表对齐格式错。DMA 送的是DAC_ALIGN_12B_R右对齐还是12B_L左对齐要和表的数据格式一致。左对齐的表用右对齐送进去波形直接被砍半或移位。表长 N 和频率公式搞反。以为改 N 就能调频其实 N 是分辨率、ARR 才是频率主旋钮。频率 触发频率 / N调频动定时器调波形平滑度动 N。DMA 没开 Circular 模式。Normal 模式送完一圈就停波形只出一次。波形发生器必须 Circular让它自动回绕。定时器触发频率太高超 DAC 建立时间。DAC 转换和建立需要时间触发太快前一个值还没稳下一个又来了波形台阶化、失真。查手册建立时间别逼太狠。输出缓冲没开带不动负载。直接驱动长线或低阻负载电压被拉垮、波形变形。轻载可以关缓冲换满摆幅重载必须开缓冲或后级加运放。波形表没算对幅度和偏置。算出来的值超 0~4095 被截断正弦顶部削平没加直流偏置纯交流表送进去负半周全丢。表值夹在范围内交流波要加中点偏置。两路 DAC 抢同一个触发源。部分型号两路 DAC 共用一个定时器触发想两路不同频率做不到得错开或用其他触发。需要独立波形时确认型号是否支持分触发。更新波形表时和 DMA 读冲突。正 Circular 搬运时你改表可能半新半旧拼成一个怪波形。更新前先HAL_DAC_Stop_DMA或双缓冲切换别边读边写。VREF 不稳波形带电源噪声。DAC 参考电压取自 VREF 脚电源纹波直接叠到输出。参考源加旁路、用独立基准波形才干净尤其小信号时明显。把这件事收一下DAC 出波形核心是「定时器定节拍、DMA 搬数据、CPU 只备表」。这三件套搭起来正弦、三角、任意波形都是同一张表的区别频率交给定时器算。坑大多在触发源配对、对齐格式、还有缓冲和参考电压这些模拟侧的细节数字部分反而省心。调好了一个 STM32 就是台可编程信号源。DAC 出波靠的是「定时器打拍、DMA 搬表、CPU 备料」。频率动定时器、平滑动表长对齐格式和参考电压卡死波形才干净不乱。
返回列表