STM32 ADC conversion triggering with the falling/rising edge of the PWM signal - Page 1
Forum section: electronics / general

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 08, 2018, 01:35:11 pm
content: Hi.I want to generate a PWM pulse which might vary in terms of its frequency and duty cycle.It's easy to make it But I want to start reading ADC values using DMA (for example 100 samples) just after the pulse finished or started (falling/rising edge of the PWM signal).In the ideal case, I want to start reading 20uS after the falling edge of the PWM.is it possible to make it?I use CubeMX

author: mbless
author_rank: Regular Contributor
timestamp: July 08, 2018, 11:56:45 pm
content: Depending on the MCU and which ADC you're using, you can use timer trigger events or an external interrupt to start ADC conversion in DMA mode. You'll have to go to the Configuration tab in CubeMX and select the ADC to see which trigger options exist for your setup.As far as a 20 us delay, there's no built-in delay on the ADC side, so you'd have to delay the trigger some how. Personally, I would just throw away x number of data at the beginning of the conversion that accounts for 20 us based on the sampling time for each conversion.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 06:19:37 am
content: Quote from: mbless on July 08, 2018, 11:56:45 pmI am using STM32F407, therefore it contains all sorts of timers, advanced timers and ADCs. Yes, in the meantime I just triggered the ADC with another timer trigger out event and for that 20uS I just did the same as you mentioned, throwing the beginning of DMA acquired data in the array.I have couple of questions which have remained unsolved.1) How can I enable the ADC conversion using an external interrupt? The only triggering options I see in the list, are timer trigger or timer capture.2) is it possible to fire the ADC DMA conversion from alternative routine? I mean triggering it in the code by a command or something.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 11:56:05 am
content: I have another problem also. I put the timer trigger on 100mS. it means it triggers its interrupt and ADC every 100mS. Below is the configuration of the ADC and Timer2.I checked the TIM2 interrupt by a GPIO toggle and it gets fired every 100mS or 50Hz which is correct.BUT the ADC DMA gets fired 2 times per second, it means 2Hz. it is weird because I just put 100 for the buffer and whole sampling to fire the ADC DMA interrupt must not take more than 100 * 0.5uS = 50uS , because each ADC channel can handle the speed of 2Msps. This speed is correct if the ADC works in the continuous conversion mode, but I could not achieve this when I trigger it externally.The triggering is slow and it should not make any timing conflict, it means the conversion finishes sooner before the next trigger comes in

author: mbless
author_rank: Regular Contributor
timestamp: July 09, 2018, 02:27:56 pm
content: Quote from: VanitarNordic on July 09, 2018, 06:19:37 amAccording to Figure 51 of the reference manual, ADC1 should be able to use EXTI 11 as a trigger source. I don't have CubeMX in front of me to try it out myself.Quote from: VanitarNordic on July 09, 2018, 06:19:37 amI use HAL_ADC_Start_DMAQuote from: VanitarNordic on July 09, 2018, 11:56:05 amI'm guessing you meant 5 Hz. Either way the interrupt would be occurring at 10 Hz; toggling a GPIO would make it look like 5 Hz. Also, s = seconds, S = Siemens.Quote from: VanitarNordic on July 09, 2018, 11:56:05 amI believe the Master/Slave mode should be enabled in TIM2 configuration for it to output a trigger signal. It's disabled in the screenshot.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 03:12:56 pm
content: QuoteNo I mean 50Hz, Timer2 clock is 60MHz, therefore 60Mhz/ 60000 * 10 = 100Hz, but because of toggling it would be 50Hz. That's what I get when I toggle a GPIO Pin in Timer2 interrupt.My point is the rate of timer interrupt triggering must be the same as it goes out to trigger ADC. which is not hereQuoteI enabled master/slave, but it did not help.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 09, 2018, 04:38:49 pm
content: Start the DMA transfer inside the ISR of the timer configured for the PWM generation? (CCxIF flag)

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 05:12:38 pm
content: Quote from: SiliconWizard on July 09, 2018, 04:38:49 pmof course not. DMA has initialized by the HAL functions (HAL_DMA_Start_IT) inside the main function and the "conversion" is triggered by the timer. The timer triggering time must be the same as Timer ISR triggering. Timer ISR fired at the defined time and it is correct, but ADC triggering is not happen the same time as ISR and much slower.Another timer (TIM1) generates the PWM and TIM2 generates triggers.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 09, 2018, 05:24:04 pm
content: I'm not sure why not. Unless there is something that is not clear here.If you use HAL, the key would be to start the conversion by using HAL_ADC_Start_DMA() in the ISR, instead of starting the DMA separately. This is exactly what this function is made for. I did this in one application and it worked fine (I was triggering the acquition of a sample buffer in an EXTI ISR).

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 05:39:38 pm
content: Quote from: SiliconWizard on July 09, 2018, 05:24:04 pmYes, I can start the whole process inside the ISR but the intention of ADC DMA triggering is "just for starting the conversion" by the triggering signal, not initialization. apart from this, this function itself has around 40uS Delay which causes an unnecessary time shift and might not be suitable if we do this periodically.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 09, 2018, 06:19:37 pm
content: From what I remember, I was getting only a couple µs latency doing this, running @80 MHz, so that was fine. If your run at much lower frequencies, that may become a problem indeed.But I think you can get much lower latency than this if you rewrite the above function tailored for your needs so that only the necessary registers are written to - HAL functions are not particularly efficient since they cover a lot of cases. Fortunately, the source code is available and not that hard to grasp.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 09, 2018, 06:33:57 pm
content: Quote from: SiliconWizard on July 09, 2018, 06:19:37 pmHmmm, I have no idea. The system clock is 60MHz and ADC clock is 30MHz, which is the best high clock for the ADC as datasheet says for the F407. I measured this delay using SWV trace, or maybe I'm mistaken and I have measured whole conversion time for all samples, BUT anyway in theory this triggering implementation must work as the manufacturer claims. But I will retest your suggestion, thanks

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 10, 2018, 08:54:39 pm
content: I realized what's the problem but I can not solve it.Let me explain. Timer2 has a correct IRQ triggering. it means the Timer2 interrupt gets triggered by a frequency of 100Hz. I just put a PIn toggle inside the interrupt routine and it generated a 50Hz square pulse.The I putHAL_ADC_Start_DMA(&hadc1, (uint32_t *) buffer, 100);inside the Timer2 interrupt routine to be triggered also.then I moved the pin toggle to the ADC interrupt routine to check the conversion frequency.the frequency is correct but for a time around 0.5 just after reset, it means just after reset the ADC triggers the interrupt with a 100Hz frequency.But the DMA interrupt gets fired very slowly around once per second. why it should be like this?

author: mbless
author_rank: Regular Contributor
timestamp: November 05, 2018, 04:21:04 pm
content: Quote from: VanitarNordic on July 10, 2018, 08:54:39 pmI don't know if you solved this or not, but I came across this scenario this weekend. I believe the issue is that in your ADC setup you specify 1 conversion, so it will only do 1 conversion (rank 1) per a trigger regardless of your buffer size. So with a 100Hz trigger, the buffer of 100 points will only be filled every second hence the DMA interrupt every second.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: November 06, 2018, 08:18:28 am
content: QuoteYes, I solved but it should do continuously (for whatever buffer size) after the trigger. number of conversions cannot be exceeded to more than 16