cancel
Showing results for 
Search instead for 
Did you mean: 

How to write your own DAC driver in STM32?

RShre.2
Associate III

I was using HAL Driver for DAC, however, it turned out not to be suitable for my project because at high sampling frequency, using HAL_DAC_Setvalue() inside a timer interrupt caused problem. So i need to write my own driver for DAC. But I have no idea how to get started. Is there any material someone could link?

22 REPLIES 22

The DMA only works if you change the CUBE default of HALF WORD to WORD for the DAC peripheral.

If you try and set it up as both HALF WORD it passes all the set up HAL_ calls with HAL_OK but then simply does not start. HRRRRRRRUUUUUUMMMMPPPPPHHHHHHHHH. 3 days wasted.

rclar.6
Senior

Here is my main file that sets up DMA for the DAC (my DAC is routed internally to an OPAMP because I have a G474 device).

 

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DAC3_Init();
  MX_OPAMP3_Init();
  MX_TIM3_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
  //               1                                    10      12
  int16_t pData[]={100,200,300,400,500,600,700,800,900,800,700,600,500,400,300,200,0};
  int i;
  i = HAL_TIM_Base_Start(&htim3);
  i = HAL_TIM_Base_Start(&htim6);
  i = HAL_DAC_Start(&hdac3, DAC_CHANNEL_2);
  // really required ??? //
  i = HAL_DMA_Init(&hdma_dac3_ch2);

  i = HAL_OPAMP_Start(&hopamp3);

  i = HAL_DAC_SetValue(&hdac3, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 0); // see this on scope output

  //i = HAL_DAC_SetValue(&hdac3, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 4095); // see this on scope output


  //HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t Length,
                                  //    uint32_t Alignment)
  i = HAL_DAC_Start_DMA(&hdac3, DAC_CHANNEL_2, (uint32_t *)pData, 16, DAC_ALIGN_12B_R); // gives HAL_OK does nothing

  // causes error unsuprisinigly : i = HAL_DAC_Start_DMA(&hdma_dac3_ch2, DAC_CHANNEL_2, (uint32_t *)pData, 10, DAC_ALIGN_12B_R); // gives HAL_OK does nothing


  if ( i != HAL_OK ) {
	  Error_Handler();
  }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  pData[5]++; // make the 6th in sequence wobbly so as to distingish it from the triangle auto wave generator
	  if ( pData[5] > 650)
		  pData[5] = 550; 
    asm (" nop");

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
LCE
Principal

It's hard to read with the comments - so is it working now?

Do you have it working below the limits, let's say with a sampling rate of 100 kHz?