STM32 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐。DAC 模块有 2 个输出通道,每个通道都有单独的转换器。在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个通道的输出。DAC 可以通过引脚输入参考电压 VREF+以获得更精确的转换结果。
STM32 的 DAC 模块主要特点有: ① 2 个 DAC 转换器:每个转换器对应 1 个输出通道 ② 8 位或者 12 位单调输出 ③ 12 位模式下数据左对齐或者右对齐 ④ 同步更新功能 ⑤ 噪声波形生成 ⑥ 三角波形生成 ⑦ 双 DAC 通道同时或者分别转换 ⑧ 每个通道都有 DMA 功能 单个 DAC 通道的框图如图 25.1.1 所示:
一旦使能DACx通道,相应的GPIO引脚(PA4或者PA5)就会自动与DAC的模拟输出相连(DAC_OUTx)。为了避免寄生的干扰和额外的功耗,引脚PA4或者PA5在之前应当设置成模拟输入(AIN)。
数字输入经过DAC被线性地转换为模拟电压输出,其范围为0到VREF+,任一DAC通道引脚上的输出电压满足下面的关系:
DAC输出电压 = VREF+ x (DOR /4095)。
输出电压就是自己想输出的模拟量电压,比如2.5V,但输出电压要在0 ~ VREF+之间, VREF+是单片机的参考电压,一般为3.3V
所以要输出2.5V的电压,则2.5 = 3.3 * (DOR/4095),计算得出DOR的值为3102,该值在后面用HAL库函数HAL_DAC_SetValue时当作最后一个参数传入,PA4或PA5引脚就会输出2.5V电压
DAC的配置比较简单,因为使用到PA4,所以选择OUT1,在参数配置中使能Output Buffer,Output Buffer 选项可以理解为个驱动,一般开启DAC都会使能,使能后使出信号具有一定驱动能力,能驱动小负载;如果没有使能,则只是输出一个信号
Trigger为触发事件,有许多定时器触发事件,本次没有用到,所以不用使能
DAC_Apply.c
源文件的主要三个函数,启动DAC,输出模拟量,可以输出0 ~ 3.3V任意电压,最后一个输出正弦波
输出正弦波的原理是:将想要输出的正弦波峰值到0V之间分成许多份,每一份都对应一个电压值,经过公式计算出DOR的值,用数组保存,再在for循环中调用HAL_DAC_SetValue函数将数组中的值都输出,延时一会,便得到了一个正弦波,如果要波形更加平滑的话,就将这个范围内的电压值分的再细点
const uint16_t CH_value[32] =
{
2448,2832,3186,3496,3751,3940,4057,4095,4057,3940,
3751,3496,3186,2832,2448,2048,1648,1264,910,600,345,
156,39,0,39,156,345,600,910,1264,1648,2048
};
DAC_Apply_t DAC_Apply =
{
1,
DAC_Start,
DAC_Output_Analog,
Output_Sine_Wave
};
/*
* @name DAC_Start
* @brief 启动DAC
* @param None
* @retval None
*/
static void DAC_Start()
{
//启动DAC
HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
}
/*
* @name DAC_Output_Analog
* @brief 输出模拟量(电压值)
* @param data:要输出的电压值,范围 0 ~ 3.3V
* @retval None
*/
static void DAC_Output_Analog(float data)
{
float temp;
temp = (data*4095)/3.3;
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,(uint32_t)temp);
}
/*
* @name Output_Sine_Wave
* @brief 输出正弦波
* @param None
* @retval None
*/
static void Output_Sine_Wave()
{
uint8_t i,Cycle = 0;
for(i=0;i<32;i++)
{
//输出数组的DOR值
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,CH_value[i]);
//延时
Cycle = DAC_Apply.Cycle;
while(Cycle--);
}
}
System.c
/*
* @name Run
* @brief 系统运行
* @param None
* @retval None
*/
static void Run()
{
//启动DAC
DAC_Apply.DAC_Start();
//输出模拟量
DAC_Apply.DAC_Output_Analog(2.5); //输出2.5V电压
//输出正弦波
//DAC_Apply.Output_Sine_Wave();
}
主函数中调用启动DAC函数,再调用输出模拟量函数,即可输出设定的电压,用万用表测量PA4引脚的电压即可
输出正弦波可以用示波器来看,也可以用keil硬件仿真,用万用表测量着引脚,然后在输出正弦波函数的for循环中单步执行,看引脚的电压是否会变化