cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 ADC+DMA problem

maciek
Associate II
Posted on June 22, 2014 at 03:09

Hi!

I would like to ask you for some help- I wrote a code to get ADC values from 8 channels (regular group). After each conversion there has to be of course DMA request. I wrote everything and... all I get is value from PA0 (1st channel). All table CAN_adc is filled with this value. I dont know what is wrong, I was writing code with reference manual, after that with exemples in the web and i still have no clue. I bet there is some stupid mistake, like always.

#include ''ADC_init.h''
#include ''stm32f10x.h''
unsigned 
int
CAN_adc[8];
void
ADC_setup()
{
RCC->CFGR |= RCC_CFGR_ADCPRE_DIV6; 
// 72 MHz/6 = 12 MHz (must not exceed 14 MHz)
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN 
// ADC clock ON
| RCC_APB2ENR_IOPAEN; 
// GPIOA clock ON
GPIOA->CRL &= ~(GPIO_CRL_CNF0
| GPIO_CRL_CNF1
| GPIO_CRL_CNF2
| GPIO_CRL_CNF3
| GPIO_CRL_CNF4
| GPIO_CRL_CNF5
| GPIO_CRL_CNF6
| GPIO_CRL_CNF7); 
// PA0..7 analog mode
ADC1->CR2 |= ADC_CR2_ADON; 
// ADC on, wakes up from power down mode, to start conversion ADON x2
ADC1->CR2 |= ADC_CR2_CAL 
// ADC calibration
| ADC_CR2_CONT; 
// Continous conversion mode
ADC1->CR2 &= ~(ADC_CR2_ALIGN); 
// Right align mode
ADC1->SQR1 |= (ADC_SQR1_L & (8 << 20)); 
// 8 regular conversions
ADC1->SQR3 |= (ADC_SQR3_SQ1 & (0 << 0))
| (ADC_SQR3_SQ2 & (1 << 5))
| (ADC_SQR3_SQ3 & (2 << 10))
| (ADC_SQR3_SQ4 & (3 << 15))
| (ADC_SQR3_SQ5 & (4 << 20))
| (ADC_SQR3_SQ6 & (5 << 25));
ADC1->SQR2 |= (ADC_SQR2_SQ7 & (6 << 0))
| (ADC_SQR2_SQ8 & (7 << 5)); 
// Regular group 0-1-2-3-4-5-6-7 channel
ADC1->SMPR2 |= (ADC_SMPR2_SMP0 & (7<<0)) 
// 5 cycles sample time
| (ADC_SMPR2_SMP1 & (7<<3))
| (ADC_SMPR2_SMP2 & (7<<6))
| (ADC_SMPR2_SMP3 & (7<<9))
| (ADC_SMPR2_SMP4 & (7<<12))
| (ADC_SMPR2_SMP5 & (7<<15))
| (ADC_SMPR2_SMP6 & (7<<18))
| (ADC_SMPR2_SMP7 & (7<<21));
ADC1->CR1 |= ADC_CR1_SCAN; 
// Scan mode enable
ADC1->CR2 |= ADC_CR2_DMA; 
// DMA access enable
// DMA START CONFIGURATION
RCC->AHBENR |= RCC_AHBENR_DMA1EN; 
// Clock for DMA
DMA1_Channel1->CCR |= DMA_CCR1_MINC 
// Memory increment ENABLE
| DMA_CCR1_PSIZE 
// Peripheral 32-bit size
| DMA_CCR1_MSIZE 
// Memory 32-bit size
| DMA_CCR1_PL 
// Priority: very high
| DMA_CCR1_CIRC; 
// Circular mode
DMA1_Channel1->CCR &= ~(DMA_CCR1_DIR 
// Read from peripheral
| DMA_CCR1_PINC); 
// Peripheral increment mode DISABLE
DMA1_Channel1->CPAR = (unsigned 
int
)0x4001244C; 
// Peripheral adress on DR in ADC1
DMA1_Channel1->CMAR = (unsigned 
int
)CAN_adc; 
// Memory adress
DMA1_Channel1->CNDTR = 8; 
// 8 data to transfer (8 ADC channels)
DMA1_Channel1->CCR |= DMA_CCR1_EN; 
// Channel 1 Enable
// DMA END CONFIGURATION
ADC1->CR2 |= ADC_CR2_ADON; 
// Start conversions
}

4 REPLIES 4
stm322399
Senior
Posted on June 22, 2014 at 15:01

Try to turn ADC off before programming SQRx registers.

Additionally it is safe to wait end of calibration before doing anything else.

maciek
Associate II
Posted on June 22, 2014 at 16:29

ADC1->CR2 |= ADC_CR2_ADON; 
// ADC on, wakes up from power down mode, to start conversion ADON x2
ADC1->CR2 |= ADC_CR2_RSTCAL;
while
(ADC1->CR2 & ADC_CR2_RSTCAL);
ADC1->CR2 |= ADC_CR2_CAL; 
// ADC calibration
while
(ADC1->CR2 & ADC_CR2_CAL);
ADC1->CR2 |= ADC_CR2_ADON; 
// Start conversions

I changed it, just how you said. I am configuring all registers before powering on ADC, I turn on calibration and finally I switch on ADC. The result is weird- if I connect PA0 to GND (rest of pins arent connected to anything) I get 0 value in random CAN_adc cell. And sometimes I get spikes (0x0FFD fo exemple). But I never get stable 0 value in CAN_adc[0]. Any other ideas?
stm322399
Senior
Posted on June 22, 2014 at 16:58

I insist, I already had issue when ADC was on at the moment I configured SQRx. Shut ADC before writing those registers.

One other reason it does not work is that  SQR1_L must be programmed with 7 to perform 8 conversions.

maciek
Associate II
Posted on June 22, 2014 at 17:07

Well, it works now :) To bad they don't write everything in documentation ;/

Thank you very much :) You made my day :)