cancel
Showing results for 
Search instead for 
Did you mean: 

ADC setup with DMA and timer

Hwstar
Associate II

 

I'm having some trouble setting up ADC1 on an STM32F401CEU6 to use DMA and pacing the conversions with a timer.

I want to use 2 channels in scan mode with each ADC channel doing conversion every other time the timer triggers the channel. In other words, for each rising edge of TRGO I want the channels to be sampled and converted in an interleaved fashion.

I have  timer3 set to 16 kHz and I verified its output by enabling channel 2 to go to pin PA7. I verified with a scope that the output has edges at the 16 kHz rate. Channel 1 is set to PWM with no output.

With ADC1 set up as follows:

Scan Conversion Mode: Enabled

Continuous Conversion Mode: Disabled

Discontinuous  Conversion Mode: Disabled

DMA Continuous Requests: Enabled:

 

I see data being transferred to the buffer and channels 0 and 1 are being sampled, but sample rate isn't 8 kHz per channel. I verified this with a 1Khz square wave being fed into ADC0 and I see a varying number of high and low samples. I should see 8 samples for each cycle. To me it looks like the ADC trigger is not being paced properly by the timer or the DMA is transferring to many conversions.

 

I've attached the generated code (main.c)  and the ioc file (adc-dma.ioc) so someone can take a look at what MX as generated. To see if there are any glaring errors.

 

1 ACCEPTED SOLUTION

Accepted Solutions

Yes, after each channel conversion complete event (EOC) adc is triggering dma transaction, so if 7 channels are active and ranked from 1 to 7 than dma memory buffer would be filled with 7-th consequtive results repeated, 

ch-xx (rank 1), ch-xx (rank 2), ch-xx (rank 3), ch-xx (rank 4), ch-xx (rank 5), ch-xx (rank 6), ch-xx (rank 7),

ch-xx (rank 1), ch-xx (rank 2), ch-xx (rank 3), ch-xx (rank 4), ch-xx (rank 5), ch-xx (rank 6), ch-xx (rank 7),

.... and so on.  

Get RM0368 

https://www.st.com/resource/en/reference_manual/rm0368-stm32f401xbc-and-stm32f401xde-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

page. 218-220.  

Also, don't hesitate to read comments in HAL_ driver. Example related to adc:

 uint32_t ScanConvMode;          /*!< Configure the sequencer of ADC groups regular and injected.
                                       This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts.
                                       If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1).
                                                    Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1).
                                       If enabled:  Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion' or 'InjectedNbrOfConversion' and rank of each channel in sequencer).
                                                    Scan direction is upward: from rank 1 to rank 'n'.
                                       This parameter can be a value of @ref ADC_Scan_mode */

it's out of stm32g4xx_hal_adc.h , but you 've got an idea 

View solution in original post

3 REPLIES 3
MasterT
Senior III

Seems uCPU overclocked to 96 MHz? DS says 84.

" I verified this with a 1Khz square wave being fed into ADC0 and I see a varying number of high and low samples. I should see 8 samples for each cycle. "

Likely misunderstanding how adc is working. High -low samples you see are associated to ch-0 & ch-1. Each timer trigger initiates a "sequence" of samples, in this case 2. So, overall you have 32 ksps, interleaved. 1 kHz squre would produce trail of 16 samples high-low & 16 samples low-low if no voltage applyed to ch-1.

Regarding the CPU frequency It's set up for Power Regulator Voltage Scale = 1 which is 100 MHz max. 96 MHz should be OK.

To clarify point 2. Does this mean that there are 2 half word DMA transfers  for each timer TRGO pulse? If that is true, then my timer output should be set to 8 KHz and not 16KHz.

Ifter I sent the initial message, I tried ADC discontinuous mode but I'm still seeing an unequal number of samples in for the 1Khz square wave high and low portions in the buffer.

Yes, after each channel conversion complete event (EOC) adc is triggering dma transaction, so if 7 channels are active and ranked from 1 to 7 than dma memory buffer would be filled with 7-th consequtive results repeated, 

ch-xx (rank 1), ch-xx (rank 2), ch-xx (rank 3), ch-xx (rank 4), ch-xx (rank 5), ch-xx (rank 6), ch-xx (rank 7),

ch-xx (rank 1), ch-xx (rank 2), ch-xx (rank 3), ch-xx (rank 4), ch-xx (rank 5), ch-xx (rank 6), ch-xx (rank 7),

.... and so on.  

Get RM0368 

https://www.st.com/resource/en/reference_manual/rm0368-stm32f401xbc-and-stm32f401xde-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

page. 218-220.  

Also, don't hesitate to read comments in HAL_ driver. Example related to adc:

 uint32_t ScanConvMode;          /*!< Configure the sequencer of ADC groups regular and injected.
                                       This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts.
                                       If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1).
                                                    Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1).
                                       If enabled:  Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion' or 'InjectedNbrOfConversion' and rank of each channel in sequencer).
                                                    Scan direction is upward: from rank 1 to rank 'n'.
                                       This parameter can be a value of @ref ADC_Scan_mode */

it's out of stm32g4xx_hal_adc.h , but you 've got an idea