Electronics > Projects, Designs, and Technical Stuff

STM32F302 ADC Problem

(1/1)

Glenn0010:
So in the manual it states the following:



When I run the code, it get's stuck somewhere and I can't find exactly why even while de-bugging. However I narrowed it down to the following line of code:


  while ((ADC1->ISR & ADC_ISR_ADRDY) != ADC_ISR_ADRDY){}; // wait for ADRDY
When I comment this line the code works flawlessly, however I cannot understand why, to me this line looks good. The full ADC code is listed below.
Anyone has any idea what I am doing wrong?



--- Code: ---

ADC1_COMMON->CCR = 0x0; // Resetting CKMODE
RCC->CFGR2 = RCC_CFGR2_ADC1PRES_DIV12; // ADC Prescaler /1 i.e. ADC Clock = 64Mhz
RCC->AHBENR |= RCC_AHBENR_ADC1EN; // Enable ADC1 clock
  ADC1_COMMON->CCR = 0x0; // Resetting CKMODE
GPIOB->MODER |= 0x0000000F; // GPIOB PB1 set to Analog Mode ADC1_IN12, ADC1_IN11

  // Calibration procedure
  ADC1->CR |= ADC_CR_ADVREGEN_1;
  ADC1->CR &= ~ADC_CR_ADVREGEN;
  ADC1->CR |= ADC_CR_ADVREGEN_0; // ADC Voltage regulator enabled
  for(x=0;x<5000;x++); // Delay for ADC to stabilize

  ADC1->CR &= ~ADC_CR_ADCALDIF; // calibration in Single-ended inputs Mode.
  ADC1->CR |= ADC_CR_ADCAL; // Start ADC calibration
  // Read at 1 means that a calibration in progress.
  while ( (ADC1->CR & ADC_CR_ADCAL)== ADC_CR_ADCAL){}; // wait until calibration done
calibration_value = ADC1->CALFACT; // Get Calibration Value ADC1


ADC1->ISR |= ADC_ISR_ADRDY; //clearing ADCRDY
  ADC1->CR |= ADC_CR_ADEN; // Enable ADC1
  while ((ADC1->ISR & ADC_ISR_ADRDY) != ADC_ISR_ADRDY){}; // wait for ADRDY

  ADC1->SQR1 = 0xB301; // Channel 12 first, Channel 11 second, two in sequence
ADC1->SMPR2 = 0x0; // Channel 11 and 12 Minimum conversion time
ADC1->CFGR = ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_CONT; // ADC DMA Enableed and set to circular mode and ADC in continous mode

DMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR)); // Passing the pheripheral address of the data register into DMA Channel 1
  DMA1_Channel1->CMAR = (uint32_t)ADC_Samples; // Passing the address of the arry to store the data in
DMA1_Channel1->CNDTR = 2; // " sets of data being passed
DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0; // Channel 1 Circular Mode, Memory Increment , P size = 16bit, M size = 16 bit
DMA1_Channel1->CCR |= DMA_CCR_EN; // Enabling DMA

  ADC1->CR |= ADC_CR_ADSTART; // Start ADC1 Software Conversion

--- End code ---

thm_w:
Are you using SWD debugging? You say "it gets stuck somewhere" but if you have that line in and you pause operation, is it stuck waiting on that line or is it somewhere else?

Can you view the ADC1->ISR register in your debugger, to see if the state of the ADRDY bit is as you expect?


--- Code: ---ADC1_COMMON->CCR = 0x0; // Resetting CKMODE
--- End code ---

This doesn't look right as you are writing all bits of the CCR register as 0, this is *probably* ok looking at the datasheet but may or may not be what you intended?

Glenn0010:
Looks like I found the issue.

From the manual

--- Quote ---ADEN bit cannot be set during ADCAL=1 and 4 ADC clock cycle after the ADCAL bit is
cleared by hardware(end of the calibration).
--- End quote ---

After ADC cal was = 0. I went straight to enable the ADC and wasn't waiting for the 4 clock cycles. So now I added a for loop to delay and it seems to be working fine. I guess that explains the intermittent errors I was getting.

With regards to "getting stuck somewhere", it was getting stuck in the start up file

Navigation

[0] Message Index

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod