cancel
Showing results for 
Search instead for 
Did you mean: 

GPIO, ADC and DAC not simultaneous

RShre.2
Associate III

I am using stm32 g071 and what I have done in the code is to toggle pin and send the value through adc and finally output through dac. Theoretically, the GPIO output and DAC output should be simultaneous but due to processing time and all, there will be delay, however, in this case, this is inverted. Could anyone help me explain this behavior?

In the picture, the blue signal is from GPIO pin from MCU and red signal is the adc signal converted to dac. 

 

void TIM2_IRQHandler(void)
{

if (TIM2->SR & TIM_SR_UIF)
{

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
adc = HAL_ADC_GetValue(&hadc1);
DAC1->DHR12R1 = adc;

TIM2->SR = ~TIM_SR_UIF;  /* Clear all interrupts */

}
}
 

 

 

Screenshot (48).png

1 ACCEPTED SOLUTION

Accepted Solutions

get the current value instantly?

The ADC takes 3 clock cycles plus one clock cycle per bit of precision, plus however many sampling cycles are in the configuration for that channel.

Check the End Of Conversion flag for completion, then use the GetValue function.

View solution in original post

13 REPLIES 13

What do we see on that picture and why is it not what you expect?

JW

TDK
Guru

Lots of things left unexplained here. HAL_ADC_GetValue gets the value currently in the ADC's data register. If the ADC is converting PA6, this will most likely be from before the pin was toggled.

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

As I expect the red signal should just be delayed by a small fraction and display the toggle pin value but not be inverted entirely as the cycle of the toggling state is in ms and it is quite large. the red should have started quite early but not at the same point when toggling started, if that makes sense. 

 

RShre.2
Associate III

why is it that the value is from previous pin toggled? Could you explore a bit more the reason? The timer interrupt has sampling rate of 1KHz which is slow enough for the adc to finish the process, no?

TDK
Guru

You are misinterpreting what HAL_ADC_GetValue does. It does not sample the channel, then return a value. It only returns the value currently in the ADC. Look at the function definition.

If you have your ADC set up in continuous mode, you will need to wait for it to complete a conversion before the value will be updated. Non-continous triggers are started with HAL_ADC_Start().

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

And here is the driver code that requires a conversion before GetValue

uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
{
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));

/* Note: EOC flag is not cleared here by software because automatically */
/* cleared by hardware when reading register DR. */

/* Return ADC converted value */
return hadc->Instance->DR;

RShre.2
Associate III

So if i have chosen conversion mode, there is no way to get the current value instantly? Is there a way to solve this problem? If using non continuous mode will help. 

get the current value instantly?

The ADC takes 3 clock cycles plus one clock cycle per bit of precision, plus however many sampling cycles are in the configuration for that channel.

Check the End Of Conversion flag for completion, then use the GetValue function.

> So if i have chosen conversion mode, there is no way to get the current value instantly?

No, ADC conversions are not instant.

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