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
Go to full version