目录
本节学习的是有关DAC的知识点,主要进行的是数字信号到模拟信号的转换,内容其实和我们之前学51的时候是类似的,在此就不做过多介绍,如果对AD/ DA有不太了解的同学还是建议先去看一下51的AD/DA转换。
https://live.csdn.net/v/embed/233690
DAC
STM32F4 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。DAC 可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时, 数据可以设置成左对齐或右对齐。DAC 模块有 2 个输出通道,每个通道都有单独的转换器。 在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个 通道的输出。DAC 可以通过引脚输入参考电压 Vref+(通 ADC 共用)以获得更精确的转换结果。
图中 VDDA 和 VSSA 为 DAC 模块模拟部分的供电,而 Vref+则是 DAC 模块的参考电 压。DAC_OUTx 就是 DAC 的输出通道了(对应 PA4 或者 PA5 引脚)。 值得我们注意的是,如果我们想要写入东西到DOR中去,则必须通过DHR寄存器来写入,所以这样会有一个延迟,时间大概是3个时钟周期。
触发选择
这个是选择触发源,我们本实验使用的是软件触发。
和之前一样,手册都有,我就不再赘述了。
我们需要注意的是,DAC模块是连接到PA4引脚上的,所以我们到时候需要使能相应的GPIO,还有,本实验同时使用ADC,DAC 模块,所以还需要使用跳线帽连接ADC和DAC模块,让DAC的模拟输出作为ADC的模拟输入。
1、开启 PA 口时钟,设置 PA4 为模拟输入。
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能 GPIOA 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
2、使能 DAC1 时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能 DAC 时钟
3、初始化 DAC,设置 DAC 的工作模式。
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
4、使能 DAC 转换通道。
DAC_Cmd(DAC_Channel_1, ENABLE); //使能 DAC 通道 1
5、设置 DAC 的输出值。
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12 位右对齐数据格式设置 DAC 值
#include "dac.h"
//DAC通道1输出初始化
void Dac1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
DAC_InitType.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //DAC1输出缓存关闭
DAC_InitType.DAC_Trigger = DAC_Trigger_None;//不使用触发功能
DAC_InitType.DAC_WaveGeneration = DAC_WaveGeneration_None;//不使用波形发生
DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化DAC通道1
DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值
}
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "adc.h"
#include "dac.h"
#include "key.h"
int main(void)
{
u16 adcx;
float temp;
u8 t=0;
u16 dacval=0;
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
Adc_Init(); //adc初始化
KEY_Init(); //按键初始化
Dac1_Init(); //DAC通道1初始化
DAC_SetChannel1Data(DAC_Align_12b_R,dacval);//初始值为0
while(1)
{
t++;
key=KEY_Scan(1);
if(key==WKUP_PRES)
{
if(dacval<4000)dacval+=200;
DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
}else if(key==KEY1_PRES)
{
if(dacval>200)dacval-=200;
else dacval=0;
DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
}
if(t==100||key==KEY1_PRES||key==WKUP_PRES) //WKUP/KEY1按下了,或者定时时间到了
{
adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值
printf ("DAC VAL:%d",adcx); //显示DAC寄存器值
printf ("\r\n\r\n");
temp=(float)adcx*(3.3/4096); //得到DAC电压值
adcx=temp;
printf("DAC VOL:%fV",temp); //显示电压值
printf ("\r\n\r\n");
adcx=Get_Adc_Average(ADC_Channel_5,10); //得到ADC转换值
temp=(float)adcx*(3.3/4096); //得到ADC电压值
adcx=temp;
printf("ADC VOL:%fV",temp); //显示电压值
printf ("\r\n\r\n");
LED0=!LED0;
t=0;
}
delay_ms(10);
}
}
本节DAC的基础知识就先介绍到这,后期还会对代码进行修改以及调试,继续探索一下AD/DA的功能,好了,谢谢大家的观看。