1.STM32 DAC介绍:
DAC(Digital to analog converter)即数字模拟转换器,它可以将数字信号转换为模拟信号。
DAC主要特性:
- 2个DAC转换器,每个转换器对应1个输出通道;
- 8位或者12位单调输出;
- 12位模式下数据左对齐或者右对齐;
- 同步更新功能;
- 噪声波形生成;
- 三角波形生成;
DAC介绍:
- 双DAC通道同时或者分别转换;
- 每个通道都有DMA功能;
- 外部触发转换;
- 输入参考电压VREF+;
STM32 DAC结构框图:
① 第一部分:电压输入引脚:
VDDA和VSSA是模块的供电管脚,VREF+是DAC模块的参考电压,三个管脚都接到了3.3V,因此DAC的参考电压依然是0~3.3V,想要电压得到一定的精度更高,可以设置一个基准电压源;
② 第二部分:DAC转换:
③ 第三部分:DAC触发和输出:
外部触发方式:当DAC接口在所选定时器触发或外部中断线上升沿检测到上升沿的时候,DAC就可以将DHRx寄存器的值,存储到最后一个数据,就会转移到DORx寄存器中,发生触发后,会经过3个时钟周期,寄存器内就会得到更新,数模转换器输出;
内部触发方式:一旦触发就会开启转换,将DHRx的值经过一个APB1的时间加载到DORx中;
④ 第四部分:DAC 的输出通道:
DAC1->PA4;
DAC2->PA5;
为了避免寄生电流的消耗,应当将DAC对应的通道管脚,配置为模拟输入模式;当配置了模拟输入模式后,对DAC的输出功能进行使能,它会自动将对应的管脚自动的连接到输出通道;
电压计算:DACout=(Vref+)*DORx/4095;
2.STM32 DAC配置步骤:
DAC相关库函数在stm32f10x_dac.c和stm32f10x_dac.h文件中;
- 使能端口及DAC时钟,设置引脚为模拟输入:RCC_APB2PeriphClockCmd()、RCC_APB1PeriphClockCmd();
- 初始化DAC,设置DAC工作模式:void DAC_Init();
- 使能DAC的输出通道:void DAC_Cmd();
- 设置DAC的输出值:DAC_SetChannel1Data()、uint16_t DAC_GetDataOutputValue();
3 .DAC数模转换:
通过KEY_UP与KEY1按键控制STM32 DAC1输出电压,通过串口将DAC1输出的电压值打印显示,LED0指示灯闪烁提示系统运行。
(1)原理图:
(2)主函数:
#include "delay.h"
#include "led.h"
#include "key.h"
#include "usart1.h"
#include "dac.h"
int main(){
u8 i=0;
u8 key=0;
int DAC_value=0; //DAC值增减的标志
u16 DAC_val=0; //存储读取的DAC1通道1的值
float DAC_vol=0.0f; //存储DAC所对应的电压值
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置分组
delay_init(); //延时初始化
LED_Init();
KEY_Init(); //按键初始化
usart1_Init(9600); //串口通信初始化
DAC1_Init(); //DAC1的初始化
while(1)
{
key=KEY_Scan(0); //扫描按键
if(key==3) //判断按键WK_UP是否被按下
{
DAC_value+=400;
if(DAC_value>4000)
{
DAC_value=4095; //判断,当DAC_value大于4000时,DAC_value=4095
}
DAC_SetChannel1Data(DAC_Align_12b_R,DAC_value); //输出DAC的值,12位右对齐
}
else if(key==2) //判断按键KEY1是否被按下
{
DAC_value-=400;
if(DAC_value<=0)
{
DAC_value=0;
}
DAC_SetChannel1Data(DAC_Align_12b_R,DAC_value); //输出DAC的值,12位右对齐
}
//系统指示灯闪烁
i++;
if(i%20==0)
{
LED0=!LED0;
}
//每隔1s打印一次
if(i%100==0)
{
DAC_val=DAC_GetDataOutputValue(DAC_Channel_1); //读取DAC1通道1的值
DAC_vol=(float)DAC_val*(3.3/4095); //将输出的DAC值转换为所对应的电压值
printf("当前的DAC对应的电压值:%.2f V\r\n",DAC_vol);
printf("\r\n");
}
delay_ms(10);
}
}
(3)头文件:
#ifndef __DAC_H
#define __DAC_H
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
void DAC1_Init(void); //DAC1的初始化
#endif
(4)DAC数模转换功能函数:
#include "stm32f10x.h"
#include "dac.h"
/*
功能:DAC1的初始化
变量:无
返回值:无
*/
void DAC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
DAC_InitTypeDef DAC_InitStruct;
//1.使能端口时钟和DAC时钟,并设置引脚模式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN; //模拟输入
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; //PA4
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; //速度
GPIO_Init(GPIOA,&GPIO_InitStruct);
//2.初始化DAC,设置DAC工作模式
DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0; //屏蔽/幅值选择器
DAC_InitStruct.DAC_OutputBuffer=DAC_OutputBuffer_Disable; //DAC输出缓存->不使用缓存
DAC_InitStruct.DAC_Trigger=DAC_Trigger_None; //触发方式->不使用外部触发
DAC_InitStruct.DAC_WaveGeneration=DAC_WaveGeneration_None; //DAC波形发生->不使用波形发生
DAC_Init(DAC_Channel_1,&DAC_InitStruct); //DAC1的通道1
//3.设置DAC的输出值
DAC_SetChannel1Data(DAC_Align_12b_R,0); //12位右对齐,设置值=0
//4.使能DAC1
DAC_Init(DAC_Channel_1,&DAC_InitStruct);
}