| 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 |
| Message Index |