1
前言
上期我们介绍了STMG4如何实现ADC的DMA采样,本期我们将介绍STM32G4的DAC实现直流输出和正弦输出。
从参考手册上可以看到外部DAC的采样速率为100万样本每秒。这个参数决定了DAC最大的输出速率。后面经过测试,大概DAC可以输出200KHZ的正弦波,不过分辨率设置的不是特别高,16个点每周期。
低分辨率
高分辨率
那么本期我们就介绍如何让DAC输出直流信号和正弦波信号或者任意波形。
2
CubeMX配置
配置DAC连接到外部引脚(其他型号的没这么复杂,因为G4的DAC可以连接到内部的运放)之后
配置DAC连接到外部引脚(其他型号的没这么复杂,因为G4的DAC可以连接到内部的运放)并且触发方式选择 ** 定时器事件触发 ** 。
添加DMA通道,选择合适的数据宽度。将DMA模式选择为循环模式。这样子就可以连续输出我们设置的信号了。需要注意的是,这里要选择32位宽的,选择16位宽会传输有问题。
之后就是定时器的设定,设置分频系数和计数值。设置溢出事件。这样子当定时器计数到溢出值的时候,都会对应修改DAC的值。
接着就可以生成我们的代码了。
3
直流输出
对于直流输出代码比较简单,仅仅只有两句话。
HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_2,DAC_ALIGN_12B_R,Value);HAL_DAC_Start(&hdac2, DAC_CHANNEL_1);
设置DAC相应通道的值,由于是12位DAC,因此设置范围在0~4095。通常我们的Vref是3.3V,也就对应了0~3.3V的输出范围。
这方面没有太多可以介绍的,我们简单略过。 并且如果仅使用直流输出的时候,可以仅打开DAC,不用配置DMA 。
4
正弦波输出
在进行正弦波输出之前,我们首先介绍下DAC输出正弦波的原理。
DMA通过把缓存区中存储的正弦波的值经过每次定时器事件触发之后转给DAC。
因此我们首先第一步是实现缓存区数据的创建,也就是我们的波形数据。
#define SINE_WAVE_SAMPLES 256 //一个周期的样本点数uint32_t sine_wave[SINE_WAVE_SAMPLES]; // 鏀逛负 uint16_t锛屼笌 DAC 鏁版嵁瀹藉害鍖归厤#define M_PI 3.1415void Generate_SineWave(void){ uint32_t i; float temp; for (i = 0; i < SINE_WAVE_SAMPLES; i++) { temp = sin(2 * M_PI * i / SINE_WAVE_SAMPLES); sine_wave[i] = (uint32_t)(2048 + temp * 2047); if(sine_wave[i] > 4095) sine_wave[i] = 4095; }}
在程序开始的时候,利用for循环给数据缓存区赋值正弦波信号数据。
之后开启DAC调度。
HAL_TIM_Base_Start(&htim7);HAL_DAC_Start_DMA(&hdac2, DAC_CHANNEL_1, (uint32_t*)sine_wave, SINE_WAVE_SAMPLES, DAC_ALIGN_12B_R);
同样的还要开启定时器功能以触发DAC。这样子就可以实现正弦波输出了。
同样的,修改缓存区的数据值,就可以输出任意波形。
虽然STM32的DAC驱动能力并不是特别强,但是这样子的DAC也可以在很多地方得到非常好的应用,并且很多型号是板载DAC的。善用板载DAC可以实现很多的功能。