Skip to main content
UKilc.1
Associate II
April 4, 2022
Question

STM32F334R8 reading ADC (single channel timer triggered) with 2us intervals

  • April 4, 2022
  • 12 replies
  • 3511 views

Hi, I'm trying to read ADC data with 2us periods using ADC interrupts on Nucleo F334R8. I'm triggering ADC with TRGO event of Timer 2. I'm toggling a pin whenever callback function is called to debug using an oscilloscope. However, I cannot observe 2us on the scope. Pin cannot be toggled below 10us. I tried DMA method and got the same result. What could I be doing wrong here?

(I'm a beginner on STM32 and using CubeMx.)

This topic has been closed for replies.

12 replies

waclawek.jan
Super User
April 4, 2022

Which STM32?

How is the ADC set, exactly, together with clocks? If the sampling+conversion time of ADC is longer than 2us (plus whatever time the software takes, and in case of Cube/HAL it may be quite a lot), then you won't be able to achieve the 2us period.

JW

UKilc.1
UKilc.1Author
Associate II
April 7, 2022

Thanks for the reply Jan.

ADC clock is 64Mhz through PLL and I chose sampling time 1.5 cycles. According to manual (stm32f334xx), 14 clocks cycle are needed for conversion which translates to about 220ns.

I also thought it might be a software related issue. What can I do to increase software speed?

RAnan.3
Associate III
April 7, 2022

Check if the maximum frequency that can be set to the system clock is 64MHz. I guess you can set it more than that. Also check if you are timer is called at 2us only.

victagayun
Senior III
April 8, 2022

I prefer to trigger ADC by HRTIMER. Can you also try?

Also pls provide a screenshot of CubeMX and source code.

Also, check how fast you can toggle the pin without any code.

You can try how fast you can toggle by adding these code snippets in while(1).

You have guidance on how fast the GPIO can toggle here.

https://github.com/VictorTagayun/STM32F334_HAL_LL_REG_GPIO

UKilc.1
UKilc.1Author
Associate II
April 19, 2022

Hi,

Thanks for the replies. I attached the source code. I'm going to try to to toggle the GPIO the way you suggested.

victagayun
Senior III
April 19, 2022

For GPIO toggling speed, you can create a project that toggles the IO, and check how fast it can toggle in the while(1) loop.

For ADC, you may need to add

HAL_ADC_Start

before using the ADC.

UKilc.1
UKilc.1Author
Associate II
April 21, 2022

I tried to toggle an IO pin in while loop and saw that it can be toggled at over 1Mhz frequency. I think my problem is with duration of the interrupt function. I looked inside the HAL_ADC_IRQHandler function, there is a lot of code in there. How can I simplify it to increase speed?

KnarfB
Super User
April 21, 2022

First, review/debug-step the HAL code and find the relevant pieces for your use case. Then, add your code to the original IRQ Handler in *_it.c file. Add your code in the first user code section and end it with a return. Leave the call to the HAL handler intact. It will never be called anymore, because you return early, but it will always be regenerated by the tools.

Edit: you might wrap the IRQ handler in

#pragma GCC push_options
#pragma GCC optimize ("O3")
...
#pragma GCC pop_options

to gain more speed.

hth

KnarfB

victagayun
Senior III
April 22, 2022

You did not start the timer, did you?

HAL_TIM_Base_Start_IT(&htim2);

UKilc.1
UKilc.1Author
Associate II
April 22, 2022

I cut some irrelevant parts of the code before uploading here to simplify. I start the timer of course (must have forgotten it). I figured IRQ handler creates the issue as I said. I edited it and measured interrupt duration which lasts 2us now. Not great but ok for my application.

victagayun
Senior III
April 22, 2022

I did this experiment.

 HAL_ADC_Start_IT(&hadc1);
 HAL_TIM_Base_Start(&htim2);
void ADC1_2_IRQHandler(void)
{
	/* USER CODE BEGIN ADC1_2_IRQn 0 */
	GPIOC->BSRR = (1<<8); // Set
	/* USER CODE END ADC1_2_IRQn 0 */
	HAL_ADC_IRQHandler(&hadc1);
	/* USER CODE BEGIN ADC1_2_IRQn 1 */
	GPIOC->BRR = (1<<8); // Reset
	/* USER CODE END ADC1_2_IRQn 1 */
}

The duration is already 3.4uS.

Ton = 3.4uS

Toff = 340nS

UKilc.1
UKilc.1Author
Associate II
April 23, 2022

I commented out HAL_ADC_IRQHandler function.

Basically what I'm doing inside ADC1_2_IRQHandler now is this;

Set a pin high with HAL_GPIO_WritePin, clear EOS and EOC flag, get ADC value with HAL_ADC_IGetValue and set that pin low with HAL_GPIO_WritePin.

Now getting 2us pin high duration.

Do you think it is OK, or am I missing something?