cancel
Showing results for 
Search instead for 
Did you mean: 

Zero crossing detection using AWDG

reedomneck
Associate III

I'm using stm32u535 and would like to have zero crossing detection of supply voltage. I've requirement of 6ADC channels and all are configured in differential mode and adc clock is 25Mhz and resolution is 14 bit and dma circular mode is enabled. On channel 6 i e enabled analog watchdog and written logic in isr to toggle GPIO. I proved gpio and I see deviation. Can someone help here.

Here is my code snippet:
ADC and AWDG initialization:

hadc1.Instance = ADC1;

hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc1.Init.Resolution = ADC_RESOLUTION_14B;

hadc1.Init.GainCompensation = 0;

hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;

hadc1.Init.LowPowerAutoWait = DISABLE;

hadc1.Init.ContinuousConvMode = ENABLE;

hadc1.Init.NbrOfConversion = 8;

hadc1.Init.DiscontinuousConvMode = DISABLE;

hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc1.Init.DMAContinuousRequests = ENABLE;

hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;

hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;

hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;

hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;

hadc1.Init.OversamplingMode = DISABLE;

if (HAL_ADC_Init(&hadc1) != HAL_OK)

{

Error_Handler();

}



/** Configure Analog WatchDog 1

*/

AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;

AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;

AnalogWDGConfig.Channel = ADC_CHANNEL_11;

AnalogWDGConfig.ITMode = ENABLE;

AnalogWDGConfig.HighThreshold = 8284 ;

AnalogWDGConfig.LowThreshold = 8100 ;

AnalogWDGConfig.FilteringConfig = ADC_AWD_FILTERING_NONE;

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

{

Error_Handler();

}

/** Configure Regular Channel

*/

sConfig.Channel = ADC_CHANNEL_1;

sConfig.Rank = ADC_REGULAR_RANK_1;

sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE;

sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;

sConfig.OffsetNumber = ADC_OFFSET_NONE;

sConfig.Offset = 0;

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

{

Error_Handler();

}



Interrupt ISR

if ((READ_REG(hadc->Instance->ISR) & ADC_ISR_AWD1) != RESET)

{

#if 1

volatile uint32_t ndtr = __HAL_DMA_GET_COUNTER(hadc->DMA_Handle);

volatile uint32_t safe_ndtr = ndtr % 8192;

volatile uint32_t linear_pos = (8192 - safe_ndtr) % 8192;



// Channel 7 (index 6 in each scan of ‌‌

volatile uint32_t current_scan = linear_pos / 8;

volatile uint16_t ch7_index = (current_scan * ‌‌ + 7;

ch7_index %= 8192; // Circular wrap



volatile uint16_t current_ch7 = gRawDMACircularBuffer.rawDataBuffer[ch7_index];



//volatile uint16_t current_ch7 = HAL_ADC_GetValue(hadc);

volatile static uint16_t prev_ch7 = 8192,expect = 1;



if (prev_ch7 <= 8100 && current_ch7 >= 8284) {

toggle_LED();

Zx = 1;

}

else if (prev_ch7 >= 8284 && current_ch7 <= 8100) {

toggle_LED();

Zx = 1;



}

__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD1);

prev_ch7 = current_ch7;

#endif



}
3 REPLIES 3
Saket_Om
ST Employee

Hello @reedomneck 

You mention that you enabled the analog watchdog on “channel 6”, but in the code snippet you actually configure it on ADC_CHANNEL_11:

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

@Saket_Om it's typo error.

 

TDK
Super User

Can you provide the actual code you are using? It doesn't help anyone to present code that isn't being used. Create a minimal working example and present that code.

If you feel a post has answered your question, please click "Accept as Solution".