STM32的DAC

二、DAC,数字模拟转换

1、定义

STM32F4 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的 DAC。DAC可以配置为 8 位或 12位模式,也可以与 DMA 控制器配合使用。 DAC 工作在 12 位模式时,数据可以设置成左对齐或右对齐,一般设置右对齐,从第零位开始。 DAC 模块有 2个输出通道,每个通道都有单独的转换器。在双 DAC 模式下, 2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2个通道的输出。 DAC 可以通过引脚输入参考电压 Vref+(通 ADC 共用) 以获得更精确的转换结果。

#主要应用在
输出自定义电压、音频播放、视频播放

2、库函数

a.根据DAC_InitTypeDef初始化DAC

  • @param DAC_Channel: the selected DAC channel.
  • This parameter can be one of the following values:
  •        @arg DAC_Channel_1: DAC Channel1 selected
    
  •        @arg DAC_Channel_2: DAC Channel2 selected
    
  • @param DAC_InitStruct: pointer to a DAC_InitTypeDef structure that contains the configuration information for the specified DAC channel.
void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct)
typedef struct
{
    
    
  uint32_t DAC_Trigger;                      /*!< Specifies the external trigger for the selected DAC channel.
                                                  This parameter can be a value of @ref DAC_trigger_selection */

  uint32_t DAC_WaveGeneration;               /*!< Specifies whether DAC channel noise waves or triangle waves
                                                  are generated, or whether no wave is generated.
                                                  This parameter can be a value of @ref DAC_wave_generation */

  uint32_t DAC_LFSRUnmask_TriangleAmplitude; /*!< Specifies the LFSR mask for noise wave generation or
                                                  the maximum amplitude triangle generation for the DAC channel. 
                                                  This parameter can be a value of @ref DAC_lfsrunmask_triangleamplitude */

  uint32_t DAC_OutputBuffer;                 /*!< Specifies whether the DAC channel output buffer is enabled or disabled.
                                                  This parameter can be a value of @ref DAC_output_buffer */
}DAC_InitTypeDef;

b.使能 DAC 对应的通道

  • @param DAC_Channel: The selected DAC channel.
  • This parameter can be one of the following values:
  •        @arg DAC_Channel_1: DAC Channel1 selected
    
  •        @arg DAC_Channel_2: DAC Channel2 selected
    
  • @param NewState: new state of the DAC channel.
  •      This parameter can be: ENABLE or DISABLE.
    
  • @note When the DAC channel is enabled the trigger source can no more be modified.
void DAC_Cmd(uint32_t DAC_Channel, FunctionalState NewState)

c.设置DAC对应通道的数据对齐格式,输出数据值

  • @brief Set the specified data holding register value for DAC channel1.
  • @param DAC_Align: Specifies the data alignment for DAC channel1.
  • This parameter can be one of the following values:
  •        @arg DAC_Align_8b_R: 8bit right data alignment selected
    
  •        @arg DAC_Align_12b_L: 12bit left data alignment selected
    
  •        @arg DAC_Align_12b_R: 12bit right data alignment selected
    
  • @param Data: Data to be loaded in the selected data holding register.
void DAC_SetChannel1Data(uint32_t DAC_Align, uint16_t Data)

软件设置输出电压的计算公式如下:
在这里插入图片描述

实现每1Sdac的值自动加100,超过3300置为0,重新计数。
部分代码:


void dac_init(void)
{
    
    
	/* GPIOA clock enable (to be used with DAC) ,GPIOA硬件时钟初始化*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  
	
	/* DAC Periph clock enable ,DAC硬件时钟使能*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);


	/* 配置DAC1为模拟输入引脚 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				//第4号引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;			//引脚设置为模拟输出,能够输出更加广范围的电平(0V~3.3V任何电压)
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* DAC channel1 Configuration ,DAC通道1配置*/
	DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;						//不依赖于其他定时器来触发DAC硬件的输出,通过软件触发输出电压值
	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;			//不需要输出波形,只需要输出自定义的电压值
	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;			//使能输出
	DAC_Init(DAC_Channel_1, &DAC_InitStructure);

	/* Enable DAC Channel1,使能DAC通道1硬件 */
	DAC_Cmd(DAC_Channel_1, ENABLE);


}

int main(void)
{
    
     
	uint32_t adc_val,adc_vol;
	uint32_t dac_vol=0;			//自定义电压值

	LED_Init();		

	//系统定时器初始化,时钟源来自HCLK,且进行8分频,
	//系统定时器时钟频率=168MHz/8=21MHz
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
		
	//设置中断优先级分组2
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//串口1,波特率115200bps,开启接收中断
	USART1_Init(115200);
	
	//DAC初始化
	dac_init();
	
	//ADC初始化
	adc_init();
	

	while(1)
	{
    
    
		dac_vol +=100;
		
		//使用DAC通道1输出自定义电压值
		DAC_SetChannel1Data(DAC_Align_12b_R, dac_vol*4095/3300);
		
		printf("dac vol=%dmv\r\n",dac_vol);
		
		if(dac_vol >=3300)
			dac_vol = 0;
		
		delay_ms(500);
		
		
		/* Start ADC Software Conversion ,启动ADC1进行转换*/ 
		ADC_SoftwareStartConv(ADC1);
		
		//等待转换结束
		while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
		
		
		//获取ADC转换后的数值
		adc_val=ADC_GetConversionValue(ADC1);
		
		//将ADC输出的结果值转换位电压值
		adc_vol = adc_val*3300/4095;
		
		printf("adc vol = %dmv\r\n",adc_vol);
		
		delay_ms(500);

	}
}

猜你喜欢

转载自blog.csdn.net/ABCisCOOL/article/details/115186706