2014-06-21 06:09 PM
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
}
2014-06-22 06:01 AM
Try to turn ADC off before programming SQRx registers.
Additionally it is safe to wait end of calibration before doing anything else.2014-06-22 07:29 AM
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?
2014-06-22 07:58 AM
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.2014-06-22 08:07 AM
Well, it works now :) To bad they don't write everything in documentation ;/
Thank you very much :) You made my day :)