4
\$\begingroup\$

I am using the STM32F3 Discovery development board which has an STM32F303VCT6 MCU. I am also using the STM32CubeIDE.

I am trying to set up the DAC to perform one-off digital to analog conversions when I update the DAC output register, however, I have been unable to get anything other than 0 V out of the output pin.

According to the datasheet, the channel 1 DAC output pin is PA4. From my (obviously incorrect) understanding, the only register edits that I had to perform to get the DAC up and running were:

Change the PA4 mode to "Analog": GPIOA -> MODER |= 0x00000300;

Enable the channel 1 DAC: DAC -> CR |= DAC_CR_EN1;

and write the output voltage: DAC -> DHR12R1 = 3000; (3.3V * 3000/4096 = 2.42V output)

All of these are within the main() function. I use the STM32CubeIDE device configuration tool to initialize the clocks. However, when I run the program on the MCU, I don't measure any voltage on pin PA4. What else needs to be configured to get an output voltage?

\$\endgroup\$
2
  • 4
    \$\begingroup\$ If you already use CubeMX built into CubeIDE, why not also configure the DAC output with few mouse clicks, and see the resulting init code? \$\endgroup\$
    – Justme
    Oct 10, 2020 at 22:48
  • \$\begingroup\$ Like Justme said, if you already use CubeMX then use the HAL functions to activate the DAC output. They are always a good start and can be optimized later if you need a higer performance. \$\endgroup\$
    – A.R.C.
    Oct 15, 2020 at 14:00

3 Answers 3

2
\$\begingroup\$

I met (and solved) the same problem.

The origins are:

  1. For some reason, at program start hdac1.State have very wrong value (something like 254, when a proper values lie in 0..4).

The HAL_Init() checks if hdac1.State is equal to HAL_DAC_STATE_RESET, otherwise just doing nothing, giving "OK" neither doing any real init, nor resetting "locked" status.

Adding manually the

hdac1.State = HAL_DAC_STATE_RESET;

before HAL_Init(); solves that.

  1. Configurator didn't inserted any HAL_DAC_Start() commands itself. It is this command that actually sets bits in DAC conf reg. to turn on channels

One need to put

 HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
 HAL_DAC_Start(&hdac1, DAC_CHANNEL_2);

at end of initialization code to do that.

After this two steps DAC starts to work and chip DAC register looks OK.

The PA4|PA5 pins get proper initialization deep in HAL_Init() (when hdac1.State have a correct value).

\$\endgroup\$
1
\$\begingroup\$

I had a similar problem where my output was always 0 V. After surfing through many tutorials it looks like they all skipped over HAL_DAC_Start(). Here is code that runs using DAC channel 1 on a Nucleo-L552ZE-Q. This code will create a sawtooth wave from 0 V to 3.3 V, measured from PA4 to GND. Good luck!

DAC_HandleTypeDef hdac1;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DAC1_Init();

  uint16_t value_dc =0;
  HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);

  while (1)
  {
      HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value_dc);

      if(value_dc < 4095) value_dc++;
      else value_dc = 0;

      HAL_Delay(10);
  }
}

Here is the video that I followed: https://www.youtube.com/watch?v=Thvclkyd3B0

\$\endgroup\$
0
\$\begingroup\$

here is an example of HAL library

static void MX_DAC1_Init(void)
{
  DAC_ChannelConfTypeDef sConfig = {0};
  hdac1.Instance = DAC1;
  if (HAL_DAC_Init(&hdac1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC;
  sConfig.DAC_DMADoubleDataMode = DISABLE;
  sConfig.DAC_SignedFormat = DISABLE;
  sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
  sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
  sConfig.DAC_Trigger2 = DAC_TRIGGER_NONE;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
  sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
  sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
  if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }

    HAL_DAC_MspInit(&hdac1);
    __HAL_DAC_ENABLE(&hdac1,DAC_CHANNEL_1);
    HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);
    HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,0);

}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.