Skip to main content
RZige.1
Associate
April 25, 2020
Question

STM32F446 ADC modes for analog watchdog

  • April 25, 2020
  • 3 replies
  • 1627 views

Hello,

I'd like to use my STM32F446 in the following way:

  1. ADC 1&2 are connected to an analog sensor
  2. Once the sensor connected to ADC 1 passes a certain voltage, start using DMA to transfer ADC 1&2 values to buffers.
  3. Once the transfer is complete, stop the DMA and execute a function
  4. Do steps 2-3 over and over again

I managed to achieve the above by using an external Th-crossing circuit I've built, now I'd like to get rid of this circuit and change implementation to using the integrated Analog Watchdog in ADC1.

I tried at first enabling ADC1 in polling mode, waiting for the AWDG to be triggered and then enabling the DMA transfer but it seems that the AWDG is not working when the ADC is in polling mode. Is that correct or am I missing something here?

Please help me figure it out :)

My ADC initialization functions (using CubeMX):

/* ADC1 init function */

static void MX_ADC1_Init(void)

{

 ADC_MultiModeTypeDef multimode;

 ADC_AnalogWDGConfTypeDef AnalogWDGConfig;

 ADC_ChannelConfTypeDef sConfig;

  /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 

  */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.ScanConvMode = ENABLE;

 hadc1.Init.ContinuousConvMode = ENABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 1;

 hadc1.Init.DMAContinuousRequests = ENABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

  /**Configure the ADC multi-mode 

  */

 multimode.Mode = ADC_DUALMODE_REGSIMULT;

 multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;

 multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;

 if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

  /**Configure the analog watchdog 

  */

 AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;

 AnalogWDGConfig.HighThreshold = 2500;

 AnalogWDGConfig.LowThreshold = 0;

 AnalogWDGConfig.Channel = ADC_CHANNEL_10;

 AnalogWDGConfig.ITMode = ENABLE;

 if (HAL_ADC_AnalogWDGConfig(&hadc1, &AnalogWDGConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

  /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 

  */

 sConfig.Channel = ADC_CHANNEL_10;

 sConfig.Rank = 1;

 sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

}

/* ADC2 init function */

static void MX_ADC2_Init(void)

{

 ADC_ChannelConfTypeDef sConfig;

  /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 

  */

 hadc2.Instance = ADC2;

 hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

 hadc2.Init.Resolution = ADC_RESOLUTION_12B;

 hadc2.Init.ScanConvMode = ENABLE;

 hadc2.Init.ContinuousConvMode = ENABLE;

 hadc2.Init.DiscontinuousConvMode = DISABLE;

 hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc2.Init.NbrOfConversion = 1;

 hadc2.Init.DMAContinuousRequests = ENABLE;

 hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;

 if (HAL_ADC_Init(&hadc2) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

  /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 

  */

 sConfig.Channel = ADC_CHANNEL_11;

 sConfig.Rank = 1;

 sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;

 if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

}

This topic has been closed for replies.

3 replies

waclawek.jan
Super User
April 25, 2020

> it seems that the AWDG is not working

How do you know?

JW

RZige.1
RZige.1Author
Associate
April 26, 2020

Because the AWD bit in the ADC's CR1 register is not being set, also the AWDG interrupt isn't being executed

waclawek.jan
Super User
April 26, 2020

> AWD bit in the ADC's CR1 register is not being set,

Isn't AWD bit in ADC_SR?

And ADC_SR.EOC gets set?

If yes, what is the content of ADC_DR/ADC_HTR/ADC_LTR registers (i.e. does the measured value justify the watchdog to fire)?

Also, read out and check/post content of ADC_CR1 register, especially the fields related to the watchdog.

JW