cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405RG ADC problem

KHoca.1
Associate

Hi I am trying to sample an external signal with the ADC inside STM32F405RG MCU.

You can see the code below.

#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

2 REPLIES 2
TDK
Guru

> 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?

Are you sure they're both full as opposed to just one full and the other is just starting to be filled? I would expect a few values to be in the second buffer by the time it hits your breakpoint.

> 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.

With nothing hooked up to the ADC, why do you care what it reports? The measurement of an infinite impedance source doesn't make a lot of sense.

If you feel a post has answered your question, please click "Accept as Solution".

> I would expect a few values to be in the second buffer by the time it hits your breakpoint.

What's the sampling rate? DMA won't stop... so few might quite well be all the second buffer.

JW