4

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?

ocrdu
  • 8,705
  • 21
  • 30
  • 42
Nick
  • 199
  • 7
  • 4
    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? – Justme Oct 10 '20 at 22:48
  • 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. – A.R.C. Oct 15 '20 at 14:00

3 Answers3

2

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).

Theoristos
  • 71
  • 4
1

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

Null
  • 7,448
  • 17
  • 36
  • 48
0

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);

}