cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446 ADC modes for analog watchdog

RZige.1
Associate

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

 }

}

3 REPLIES 3

> it seems that the AWDG is not working

How do you know?

JW

RZige.1
Associate

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

> 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