STM32 DAC detailed

table of Contents

01. Introduction to DAC

02, DAC conversion

03. Function description

04, DAC output voltage

05, code configuration


The previous article introduced " STM32ADC Detailed Explanation ". Since there is an analog-to-digital ADC module, there must be a digital-to-analog DAC module. As the name suggests, this module only has the supplementary functions of ADC. It converts digital binary values ​​into analog voltage output. The DAC module has many uses, including audio generation, waveform generation, etc. Usually in most 8-bit microcontrollers, this module is not available, and pulse width modulation (PWM) can slightly meet its needs. Part of the reason is due to their relatively low hardware resources and operating speed. All STM32 microcontrollers have a PWM module, but the high-capacity STM32 also has a DAC module. The STM32DAC module is not very complicated and is similar to the ADC module in terms of working principle.

01. Introduction to DAC

Seen from the STM32F207 data sheet, STM32F207 has two DAC modules.

Each DAC has an independent channel, and the corresponding GPIO are: PA4 and PA5. For GPIO alternate functions (Alternatefunctions) and additional functions (Additionalfunctions), there is a detailed explanation in " STM32ADC Detailed Explanation ".

In addition to the DAC output pins, there are other related pins

Note: After enabling DAC channel x, the corresponding GPIO pin (PA4 or PA5) will be automatically connected to the analog converter output (DAC_OUTx). In order to avoid parasitic current consumption, first configure the PA4 or PA5 pin to analog mode (AIN).

The simplified block diagram below shows the main components of the STM32DAC module.

02, DAC conversion

It can be seen from the block diagram that the DAC is directly controlled by the DORx register, but data cannot be directly written to the DORx register. Instead, it is indirectly passed to the DORx register through DHRx to realize the output control of the DAC.

You cannot directly write data to the register DAC_DORx. Any data output to DAC channel x must be written to the DAC_DHRx register (the data is actually written to the DAC_DHR8Rx, DAC_DHR12Lx, DAC_DHR12Rx, DAC_DHR8RD, DAC_DHR12LD, or DAC_DHR12RD register).

  1. If the hardware trigger is not selected (the TENx bit of the register DAC_CR1 is 0), the data stored in the register DAC_DHRx will be automatically transferred to the register DAC_DORx after one APB1 clock cycle;

  2. If the hardware trigger is selected (the TENx bit of the register DAC_CR1 is set to 1), the data transfer is completed 3 APB1 clock cycles after the trigger occurs.

Once the data is loaded from the DAC_DHRx register into the DAC_DORx register, the output is valid after the time tSETTLING has elapsed. The length of this period of time will vary depending on the power supply voltage and the analog output load.

DAC control register (DAC_CR)

     DMAEN1: DAC channel 1 DMA enable (DAC channel1 DMA enable), we do not use DMA, so set to 0

     MAMP1[3:0]: DAC channel 1 mask/amplitude selector (DAC channel1 mask/amplitude selector) is not used, so these bits are also set to 0

     WAVE1[1:0]: DAC channel1 noise/triangle wave generation enable (DAC channel1 noise/triangle wave generationenable), we also use it and set it to 0

     TEN1: DAC channel1 trigger enable (DAC channel1 trigger enable) We do not need to trigger, so set it to 0

     TSEL1[2:0]: DAC channel 1 trigger selection (DAC channel1 trigger selection) Note: This bit can only be set when TEN1=1 (DAC channel 1 trigger selection). We set TEN1 to 0, so these bits do not need to be set, the default is 0

     BOFF1: Turn off the DAC channel 1 output buffer (DAC channel1 output buffer disable). We turn off the output buffer so it is set to 1.

     EN1: DAC channel1 enable (DAC channel1 enable) We want to enable the DAC channel, so set it to 1.

03. Function description

STM32's DAC equivalent circuit is as follows

The output buffer shown in this circuit runs on an internal 3.3V power supply. Like most ops operating on a single power supply (rather than +/- dual power supplies), the output swing will never really reach the target. However, as shown in the circuit, there are two internal switches (S1 and S2) that can be controlled by registers. Turning them on will directly connect the "DACINT" signal to the "DACOUT" pin through two series-connected resistors (Ra and Rb). For reference, Ra+Rb is about 15k.

 

According to the selected configuration mode, data is written to the specified register as described below:

Single DAC channel x, there are 3 situations:

  1. 8-bit data right-justified: the user must write the data into the register DAC_DHR8Rx[7:0] bits (actually, it is stored in the register DHRx[11:4] bits);

  2. 12-bit data left-justified: the user must write the data into the register DAC_DHR12Lx[15:4] bits (actually, it is stored in the register DHRx[11:0] bits);

  3. The 12-bit data is right-justified: the user must write the data into the register DAC_DHR12Rx[11:0] bits (actually, it is stored in the register DHRx[11:0] bits).

Generally, the third method is adopted: 12-bit data is more right-aligned.

According to the operation on the DAC_DHRyyyx register, after the corresponding shift, the written data is transferred to the DHRx register (DHRx is the internal data storage register x). Subsequently, the content of the DHRx register is either automatically transferred to the DORx register, or is transferred to the DORx register via a software trigger or an external event trigger.

Dual DAC channels, there are 3 situations:

  1. 8-bit data right-aligned: the user must write the DAC channel 1 data into the register DAC_DHR8RD[7:0] bits (actually in the register DHR1[11:4] bits), and write the DAC channel 2 data into the register DAC_DHR8RD[15: 8] bit (actually stored in register DHR2[11:4] bit);

  2. 12-bit data left-justified: the user must write the DAC channel 1 data into the register DAC_DHR12LD[15:4] bits (actually in the register DHR1[11:0] bits), and write the DAC channel 2 data into the register DAC_DHR12LD[31: 20] bit (actually stored in register DHR2[11:0] bit);

  3. The 12-bit data is right-aligned: the user must write the DAC channel 1 data into the register DAC_DHR12RD[11:0] bits (actually in the register DHR1[11:0] bits), and write the DAC channel 2 data into the register DAC_DHR12RD[27: 16] bits (actually stored in register DHR2[11:0] bits).

04, DAC output voltage

When the reference voltage of the DAC is VREF+, the digital input is linearly converted to an analog voltage output through the DAC, and its range is 0 to VREF+.

The output voltage on any DAC channel pin satisfies the following relationship:

DAC output = VREF x (DOR / 4095).

Note: At this time, the data format: 12-bit data should be right aligned.

05, code configuration

DAC configuration

void DAC1_Config(void)
{
  DAC_InitTypeDef  DAC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /* DMA1 clock and GPIOA clock enable (to be used with DAC) */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  
  /* DAC Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
  
  /* DAC channel 1 & 2 (DAC_OUT1 = PA.4)(DAC_OUT2 = PA.5) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
   /* DAC channel2 Configuration */
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
  DAC_Init(DAC_Channel_1, &DAC_InitStructure);

  /* Enable DAC Channel2 */
  DAC_Cmd(DAC_Channel_1, ENABLE);
}

Set output voltage

 

//设置通道1输出电压
//vol:0~3300,代表0~3.3V
void Dac1_Set_Vol(uint16_t vol)
{
  double temp=vol;
  temp/=1000;
  temp=temp*4096/3.3;
  DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值
}

The test case is very simple, it is to repeatedly output 1.2V and 3.0V voltage

 

 while (1)
  {
    GPIO_SetBits(GPIOE,GPIO_Pin_4);  //熄灭LED灯
    Dac1_Set_Vol(1200);
    LCD_ShowString(0,0,"DAC OUT 1.2V");
    Delay(500);                      //延时500ms
    GPIO_ResetBits(GPIOE,GPIO_Pin_4);//点亮LED灯
    Dac1_Set_Vol(3000);
    LCD_ShowString(0,0,"DAC OUT 3.0V");
    Delay(500);                      //延时500ms
  }

Download verification

 

 

 

Hardware and software open source address:

https://github.com/strongercjd/STM32F207VCT6

 

Click to view the album where this article is located, STM32F207 tutorial

 

Pay attention to the official account, and receive article updates as soon as possible . The comment area cannot be seen in time, you can go to the official account to communicate if you need to communicate

Guess you like

Origin blog.csdn.net/Firefly_cjd/article/details/108789076