Author Topic: STM32F405RG ADC problem  (Read 1551 times)

0 Members and 1 Guest are viewing this topic.

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
STM32F405RG ADC problem
« on: September 07, 2020, 07:41:04 am »
Hi I am trying to sample an external signal with the ADC inside STM32F405RG MCU.

 

You can see the code below.

Code: [Select]
#include "main.h"
#include "SysClockConfiguration.h"
 
uint16_t ADC_Buffer0[1000];
uint16_t ADC_Buffer1[1000];
 
void Dummy_Delay(uint32_t x)
{
 
while(x)
{
x--;
}
 
 
}
void Initialization()
{
//---------Clock Configuration---------//
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Enable ADC Clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable GPIOA Clocks
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; //Enable DMA2 Clock
 
//---------GPIO Configuration---------//
GPIOA->MODER |= GPIO_MODER_MODE2; //Set PA2 as Analog
 
 
//---------ADC Configuration---------//
ADC1->CR2 &= ~(ADC_CR2_ADON); //Disable ADC
ADC->CCR |= (0b01<<ADC_CCR_ADCPRE_Pos);//ADC clock divided by 4
ADC1->CR2 |= ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_DDS; //Enable DMA and Set ADC mode as Continuous, DMA requests are issued as long as data are converted and DMA=1
 
/*
* Fadcclk
* Sampling Time  = -----------------------------------------------
* Sampling Cycle(3 Default) + 12 Cycle Conversion
*/
 
ADC1->SQR3 |= (2<<ADC_SQR3_SQ1_Pos);
 
ADC1->CR2 |= ADC_CR2_ADON; //Enable ADC
Dummy_Delay(505); //Wait until tstab
 
//---------DMA Configuration---------//
 
DMA2_Stream0->CR &= ~(DMA_SxCR_EN); //Disable DMA2_Stream0
 
// Double Buffer  VHigh Prio.    16bit data transfer Mem.   16bit data transfer Periph.  Increment Mem.  Circular Mode    Transfer Complete Interrupt enable.
DMA2_Stream0->CR |= DMA_SxCR_DBM | DMA_SxCR_PL | (0b01<<DMA_SxCR_MSIZE_Pos) | (0b01<<DMA_SxCR_PSIZE_Pos) | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE;
DMA2_Stream0->NDTR = 1000; //Number of Data to transfer
 
DMA2_Stream0->PAR  = (uint32_t) &ADC1->DR; //Peripheral Address
DMA2_Stream0->M0AR = (uint32_t) ADC_Buffer0; //First Buffer
DMA2_Stream0->M1AR = (uint32_t) ADC_Buffer1; //Second Buffer
 
DMA2_Stream0->CR |= DMA_SxCR_EN; //Enable DMA2_Stream0
 
//---------NVIC Configuration---------//
NVIC_EnableIRQ(DMA2_Stream0_IRQn); //Enable DMA2 Stream0 Interrupt
 
 
}
 
 
int main(void)
{
 
  HAL_Init();
  SystemClock_Config();
 
  Initialization();
  ADC1->CR2 |= ADC_CR2_SWSTART; //Start Conversion of regular channels.
 
  while (1)
  {
 
  }
 
}
 
 
void DMA2_Stream0_IRQHandler()
{
if(DMA2->LISR & DMA_LISR_TCIF0) //Check Transfer Complete Interrupt Flag
{
DMA2->LIFCR |= DMA_LIFCR_CTCIF0; //Clear Transfer complete Interrupt flag
 
 
}
 
}

ADCCLK = Peripheral clock 84MHz/4 = 21MHz. Sampling rate = 21MHz/15 =1.4Msps

 

ADC is set 12bit configuration.

DMA is in Double buffer Mode.

 

I have two problems.

 

I. When I debug the code and set breakpoint inside the DMA interrupt, both buffers are full with data, despite DMA triggering for the first time. Shouldn't only one buffer be full?

 

II. ADC reads the signal wrong. When I don't give any input signal ADC reads approximately 980. When I set the ADC in scan mode with two channels ADC reads 450 for one and 65 for the other channel(Again with no input). Something seems to be wrong.

 

Has anyone encountered this type of problem?

 

Thank you

 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: STM32F405RG ADC problem
« Reply #1 on: September 07, 2020, 07:56:16 am »
Hi

It is difficult to debug isr with break points and stepping through.
Humans just do not operate at the speed of micros.

It is likely that the 2nd buffers filled up in the time that it took to go look.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: STM32F405RG ADC problem
« Reply #2 on: September 07, 2020, 08:58:11 am »
Hi

It is difficult to debug isr with break points and stepping through.
Humans just do not operate at the speed of micros.

It is likely that the 2nd buffers filled up in the time that it took to go look.

Yes it seems like so. I set and reset the GPIO pin in ISR and observed right timing in Oscilloscope.

What about ADC configuration? Why am I reading wrong data?
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: STM32F405RG ADC problem
« Reply #3 on: September 07, 2020, 11:44:10 am »
Leaving inputs floating is not going to give you anything sensible.
They are high impeadance whuch means when left floating, they will just pick up random noise.
Put some know voltage and see if the ADC value gives somethung sensible.
Does short to 0V give 0 adc count? Etc.
 

Offline Alti

  • Frequent Contributor
  • **
  • Posts: 404
  • Country: 00
Re: STM32F405RG ADC problem
« Reply #4 on: September 07, 2020, 04:20:07 pm »
If you want to debug this ISR then you have to halt ADC while stepping through breakpoints, otherwise it triggers DMA requests continuously. This halt can be made by triggering each single conversion of ADC by a timer event and setting the timer to stop when in debug mode. Otherwise each time you read DMA buffer you get different values.

If you have problems with connecting ADC to an IO pin then STM32 micros have several ADC channels wired inside of the chip (do not require any IOs). I am sure your chip has some channels tied to Temp sensor, Aref, maybe even Vbat or Vcc/2.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: STM32F405RG ADC problem
« Reply #5 on: September 10, 2020, 12:49:35 pm »
After connecting pins to sources voltage reads are close to real values but wrong.

For example I have a voltage divider circuit which has 100k and 10k resistors. I apply 18.5V to voltage divider and get 1.7V at ADC pin (I check this with oscilloscope). ADC must read 1.7/3(Vref)*4096 = 2321 but it reads 2595 which corresponds to higher voltages.

When I apply 5V to voltage divider I get 0.454V at ADC pin. ADC reads 631 which corresponds to 631/4096*3 = 0.462 also corresponds 5.08V at voltage divider input. Value is close enough for low voltage levels but as the voltage level increases the error is increasing also.

I am sampling 8 channels in scan mode at 800ksps (100ksps for each channel).

Is this error due to ADC?
« Last Edit: September 10, 2020, 12:55:06 pm by syntax333 »
 

Online iMo

  • Super Contributor
  • ***
  • Posts: 5751
  • Country: li
Re: STM32F405RG ADC problem
« Reply #6 on: September 10, 2020, 01:56:11 pm »
Quote
ADC must read 1.7/3(Vref)*4096 = 2321 but it reads 2595 which corresponds to higher voltages.
Where your Vref=3V comes from?
Readers discretion is advised..
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: STM32F405RG ADC problem
« Reply #7 on: September 11, 2020, 04:55:29 am »
Vdd is connected to Vdda and Vdd is connected to 3V
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3468
  • Country: gb
Re: STM32F405RG ADC problem
« Reply #8 on: September 11, 2020, 10:17:09 am »
A 3 cycle acquisition time may not be long enough, especially if you divider is not bypassed.  Trying increasing this.
 

Offline syntax333Topic starter

  • Regular Contributor
  • *
  • Posts: 158
  • Country: 00
Re: STM32F405RG ADC problem
« Reply #9 on: September 11, 2020, 01:18:07 pm »
I changed the supply 3.3V and measured it. Vcc was 3.25 instead of 3.3V. This small error with Voltage divider amplified my overall error.  :palm:

After calculating the voltages with Vref 3.25V everything seems to be correct. 
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf