cancel
Showing results for 
Search instead for 
Did you mean: 

How to take ADC data at 166ksps with calculation

ms10
Associate

I want to take ADC data at 166ksps but I am getting after 2 second. Can anyone suggest How can I take ADC data and also perform calculation ? Please give some guidance. 

I am attaching my main.c file.

3 REPLIES 3
Hl_st
ST Employee

Hello,

if I understand right to your problem, program need to read data from ADC and at the same time need to compute some data. For this need there is a DMA which can transfer data from ADC to memory independently on the running program:

Getting started with ADC - stm32mcu

Also in your code MCU is computing average of ADC results in program. That can be partially replaced by using longer sampling time in ADC settings and reduce CPU load.

 

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.

Hi @Hl_st 

Thank you for your response. I have tried as you say by using DMA and using longer ADC sampling time. But it is taking more time.
As I am using STM32F030F4P6 its clock frequency is 48MHz and 12 bit ADC. It can read ADC up to 1 Mbps.

I want to read at 166ksps first I was using timer trigger of 6.024 to read adc in that I am getting 166K adc sample at 1 sec but after adding averaging calculation it is giving data after 2 sec.

is it possible to read adc calculation output at 1 sec ?
Here I am attaching the DMA ADC code that you have suggest.  Please review if I am doing something wrong.

Hello,

you can try to configure DMA in circular mode and ADC using timer trigger, it will be continuously transferring adc results into the buffer. If the buffer will be for example for 16 values, program can pooling in while loop and based on DMA position in the buffer (DMA1_Channelx->CNDTR) can compute average from every last 8 values. So the code should looks like this:

 

uint16_t adc_data[16] = {0};
/* Start ADC and circular DMA transfer */
HAL_TIM_Base_Start(&htim1);
HAL_ADC_Start_DMA(&hadc1, adc_data, 16);
 
uint8_t buf_avrg_ptr = 8;
while (1){
      if (buf_avrg_ptr == 8 && DMA1_Channel1->CNDTR <= 8){
            /* Compute average from adc_data[0],..., adc_data[7]*/
            buf_avrg_ptr = 16;
      }else if (buf_avrg_ptr == 16 && DMA1_Channel1->CNDTR > 8){
            /* Compute average from adc_data[8],..., adc_data[15]*/
            buf_avrg_ptr = 8;
      }
}

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.