STM32F302 ADC Problem - Page 1
Forum section: electronics / projects

author: Glenn0010
author_rank: Regular Contributor
timestamp: November 22, 2019, 10:32:20 pm
content: 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 ADRDYWhen 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 CKMODERCC->CFGR2 = RCC_CFGR2_ADC1PRES_DIV12; // ADC Prescaler /1 i.e. ADC Clock = 64MhzRCC->AHBENR |= RCC_AHBENR_ADC1EN; // Enable ADC1 clockADC1_COMMON->CCR = 0x0; // Resetting CKMODEGPIOB->MODER |=0x0000000F; // GPIOB PB1 set to Analog Mode ADC1_IN12, ADC1_IN11// Calibration procedureADC1->CR |= ADC_CR_ADVREGEN_1;ADC1->CR &= ~ADC_CR_ADVREGEN;ADC1->CR |= ADC_CR_ADVREGEN_0; // ADC Voltage regulator enabledfor(x=0;x<5000;x++); // Delay for ADC to stabilizeADC1->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 donecalibration_value = ADC1->CALFACT; // Get Calibration Value ADC1ADC1->ISR |= ADC_ISR_ADRDY; //clearing ADCRDYADC1->CR |= ADC_CR_ADEN; // Enable ADC1while ((ADC1->ISR & ADC_ISR_ADRDY) != ADC_ISR_ADRDY){}; // wait for ADRDYADC1->SQR1 = 0xB301; // Channel 12 first, Channel 11 second, two in sequenceADC1->SMPR2 = 0x0; // Channel 11 and 12 Minimum conversion timeADC1->CFGR = ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_CONT; // ADC DMA Enableed and set to circular mode and ADC in continous modeDMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR)); // Passing the pheripheral address of the data register into DMA Channel 1DMA1_Channel1->CMAR = (uint32_t)ADC_Samples; // Passing the address of the arry to store the data inDMA1_Channel1->CNDTR = 2; // " sets of data being passedDMA1_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 bitDMA1_Channel1->CCR |= DMA_CCR_EN; // Enabling DMAADC1->CR |= ADC_CR_ADSTART; // Start ADC1 Software Conversion

author: thm_w
author_rank: Super Contributor
timestamp: November 22, 2019, 11:17:52 pm
content: 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 CKMODEThis 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?

author: Glenn0010
author_rank: Regular Contributor
timestamp: November 23, 2019, 09:18:12 am
content: Looks like I found the issue.From the manualQuoteAfter 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