Skip to main content
Lead
June 22, 2021
Question

DAC and PWM won't give out current - Why?

  • June 22, 2021
  • 4 replies
  • 744 views

Hi!

I'm trying to enable DAC and PWM so they can give out current, but nothing happens. I have tried to connect a simple LED to the pin, but non of the DAC nor PWM pins light up the LED.

First of all, here is my init for TIM2, which has PWM enabled.

I enabling both DAC and PWM like this. But still. It does not work att all. I have checked at PWM channel 4 and channel 1 for TIM5 and TIM2.

What working for me by the way, is SDADC, Encoder and Input capture. I have also checked that the TIM2 and TIM5 actully counting.

HAL_TIM_Base_Start(htim6); /* The Analog Outputs (DAC) are triggered by TIM6 */
if(HAL_DAC_Start(hdac1, DAC1_CHANNEL_1) != HAL_OK)
	Error_Handler();
if(HAL_DAC_Start(hdac1, DAC1_CHANNEL_2) != HAL_OK)
	Error_Handler();
if(HAL_DAC_Start(hdac2, DAC2_CHANNEL_1) != HAL_OK)
	Error_Handler();
if(HAL_TIM_PWM_Start(htim2, TIM_CHANNEL_ALL) != HAL_OK)
	Error_Handler();
if(HAL_TIM_PWM_Start(htim5, TIM_CHANNEL_ALL) != HAL_OK)
	Error_Handler();
 
HAL_DAC_SetValue(&hdac1, DAC1_CHANNEL_1, DAC_ALIGN_12B_R, 4095);
HAL_DAC_SetValue(&hdac1, DAC1_CHANNEL_2, DAC_ALIGN_12B_R, 4095);
HAL_DAC_SetValue(&hdac2, DAC1_CHANNEL_1, DAC_ALIGN_12B_R, 4095);

static void MX_TIM2_Init(void)
{
 
 /* USER CODE BEGIN TIM2_Init 0 */
 
 /* USER CODE END TIM2_Init 0 */
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};
 
 /* USER CODE BEGIN TIM2_Init 1 */
 
 /* USER CODE END TIM2_Init 1 */
 htim2.Instance = TIM2;
 htim2.Init.Prescaler = 20;
 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim2.Init.Period = 0xffff;
 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 0xffff;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.Pulse = 0;
 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.Pulse = 0xffff;
 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM2_Init 2 */
 
 /* USER CODE END TIM2_Init 2 */
 HAL_TIM_MspPostInit(&htim2);
 
}

Then I have TIM5, which is my next PWM counter.

static void MX_TIM5_Init(void)
{
 
 /* USER CODE BEGIN TIM5_Init 0 */
 
 /* USER CODE END TIM5_Init 0 */
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 TIM_OC_InitTypeDef sConfigOC = {0};
 
 /* USER CODE BEGIN TIM5_Init 1 */
 
 /* USER CODE END TIM5_Init 1 */
 htim5.Instance = TIM5;
 htim5.Init.Prescaler = 19;
 htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim5.Init.Period = 0xffff;
 htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
 {
 Error_Handler();
 }
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_Init(&htim5) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.OCMode = TIM_OCMODE_PWM1;
 sConfigOC.Pulse = 0;
 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
 if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
 {
 Error_Handler();
 }
 sConfigOC.Pulse = 0xffff;
 if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM5_Init 2 */
 
 /* USER CODE END TIM5_Init 2 */
 HAL_TIM_MspPostInit(&htim5);
 
}

And for DAC1

static void MX_DAC1_Init(void)
{
 
 /* USER CODE BEGIN DAC1_Init 0 */
 
 /* USER CODE END DAC1_Init 0 */
 
 DAC_ChannelConfTypeDef sConfig = {0};
 
 /* USER CODE BEGIN DAC1_Init 1 */
 
 /* USER CODE END DAC1_Init 1 */
 /** DAC Initialization
 */
 hdac1.Instance = DAC1;
 if (HAL_DAC_Init(&hdac1) != HAL_OK)
 {
 Error_Handler();
 }
 /** DAC channel OUT1 config
 */
 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 /** DAC channel OUT2 config
 */
 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DAC1_Init 2 */
 
 /* USER CODE END DAC1_Init 2 */
 
}

And DAC2

static void MX_DAC2_Init(void)
{
 
 /* USER CODE BEGIN DAC2_Init 0 */
 
 /* USER CODE END DAC2_Init 0 */
 
 DAC_ChannelConfTypeDef sConfig = {0};
 
 /* USER CODE BEGIN DAC2_Init 1 */
 
 /* USER CODE END DAC2_Init 1 */
 /** DAC Initialization
 */
 hdac2.Instance = DAC2;
 if (HAL_DAC_Init(&hdac2) != HAL_OK)
 {
 Error_Handler();
 }
 /** DAC channel OUT1 config
 */
 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
 if (HAL_DAC_ConfigChannel(&hdac2, &sConfig, DAC_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DAC2_Init 2 */
 
 /* USER CODE END DAC2_Init 2 */
 
}

Also both DAC1 and DAC2 have an external trigger, called TIM6.

static void MX_TIM6_Init(void)
{
 
 /* USER CODE BEGIN TIM6_Init 0 */
 
 /* USER CODE END TIM6_Init 0 */
 
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 /* USER CODE BEGIN TIM6_Init 1 */
 
 /* USER CODE END TIM6_Init 1 */
 htim6.Instance = TIM6;
 htim6.Init.Prescaler = 18;
 htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim6.Init.Period = 0xffff;
 htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN TIM6_Init 2 */
 
 /* USER CODE END TIM6_Init 2 */
 
}

This topic has been closed for replies.

4 replies

TDK
June 22, 2021

One problem at a time.

For PWM, follow an example for how to do things.

https://github.com/STMicroelectronics/STM32CubeF3/blob/86346f63f25b859f93f9603837dcd5be28e8e7bf/Projects/STM32F303ZE-Nucleo/Examples/TIM/TIM_PWMOutput/Src/main.c

> if(HAL_TIM_PWM_Start(htim2, TIM_CHANNEL_ALL) != HAL_OK)

Note that TIM_CHANNEL_ALL is not a valid argument here, per the function header.

https://github.com/STMicroelectronics/STM32CubeF3/blob/86346f63f25b859f93f9603837dcd5be28e8e7bf/Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c#L1425

/**
 * @brief Starts the PWM signal generation.
 * @param htim TIM handle
 * @param Channel TIM Channels to be enabled
 * This parameter can be one of the following values:
 * @arg TIM_CHANNEL_1: TIM Channel 1 selected
 * @arg TIM_CHANNEL_2: TIM Channel 2 selected
 * @arg TIM_CHANNEL_3: TIM Channel 3 selected
 * @arg TIM_CHANNEL_4: TIM Channel 4 selected
 * @arg TIM_CHANNEL_5: TIM Channel 5 selected (*)
 * @arg TIM_CHANNEL_6: TIM Channel 6 selected (*)
 * (*) Value not defined for all devices
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{

"If you feel a post has answered your question, please click ""Accept as Solution""."
DMårtAuthor
Lead
June 22, 2021

Yes! That causes the PWM problem. Not I can light up my LED if I set 100% duty call on PWM. TIM_CHANNEL_ALL should result HAL_OK == 1, error in other words.

But DAC remains scilent.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer
waclawek.jan
Super User
June 23, 2021

> But DAC remains scilent.

DAC has low output current capability, especially without output buffer, see datasheet.

JW

DMårtAuthor
Lead
June 23, 2021

But DAC should be able to light up a LED.

STM32MP151AAC3 custom board with STM32-OS as operating system: https://github.com/DanielMartensson/STM32-ComputerSTM32MP257FAK3 custom board with STM64-OS as operating system: https://github.com/DanielMartensson/STM64-Computer