I am using the MCBSTM32 board from Keil (STM32F103RBT6), Blinky example. I has only one AD channel defined where the potmeter is connected (PA1, ADC1). I need more ports as AD inputs, PA2 to PA7 (ADC2-ADC7). I am a newbe to this and do not know al the registers (and hopefully do not need to know). Can somebody please help me set this up? Best regards Hans
unsigned short int ADC_ConvertedValue; /*------------------------------------------------------------------------------ Initialises the Analog/Digital converter PA1 (ADC Channel1) is used as analog input use DMA Channel1 for ADC1 (see DMA request mapping) *------------------------------------------------------------------------------*/ void adc_Init (void) { // GPIOA->CRL &= ~0x0000000F; // set PIN1 as analog input (see stm32_Init.c) RCC->AHBENR |= (1<<0); // enable periperal clock for DMA DMA1_Channel1->CMAR = (u32)&ADC_ConvertedValue;// set channel1 memory address DMA1_Channel1->CPAR = (u32)&(ADC1->DR); // set channel1 peripheral address DMA1_Channel1->CNDTR = 1; // transmit 1 word DMA1_Channel1->CCR = 0x00002520; // configure DMA channel DMA1_Channel1->CCR |= (1 << 0); // DMA Channel 1 enable RCC->APB2ENR |= (1<<9); // enable periperal clock for ADC1 ADC1->SQR1 = 0x00000000; // only one conversion ADC1->SMPR2 = 0x00000028; // set sample time channel1 (55,5 cycles) ADC1->SQR3 = 0x00000001; // set channel1 as 1st conversion ADC1->CR1 = 0x00000100; // use independant mode, SCAN mode ADC1->CR2 = 0x000E0103; // use data align right,continuous conversion // EXTSEL = SWSTART // enable ADC, DMA mode, no external Trigger ADC1->CR2 |= 0x00500000; // start SW conversion } Main loop: AD_value = ADC_ConvertedValue; // Read AD value
The data sheets or user manuals for the processors are nice documents written specifically to help people who don't already know all registers. By the way - every programmer who starts using a processor will start from a situation where we don't know the registers. Some of the things we may then memorize but most of the time we will work with the data sheets constantly open as cross references.
... you could, instead, use ST's Standard Peripheral Library.
Keil inlcude a version with the installation; for the latest, check the ST site.
I got this to work by reading the manual :-). The 4 inputs are in ADC_ConvertedValue [0] to [3] Here comes the code:
unsigned short int ADC_ConvertedValue[4]; /*------------------------------------------------------------------------------ Initialises the Analog/Digital converter PA1 (ADC Channel1) is used as analog input use DMA Channel1 for ADC1 (see DMA request mapping) *------------------------------------------------------------------------------*/ void adc_Init (void) { // GPIOA->CRL &= ~0x0000000F; // set PIN1 as analog input (see stm32_Init.c) GPIOA->CRL &= 0xFFFF0000; // Port A 0-7 input and analog input RCC->AHBENR |= (1<<0); // enable periperal clock for DMA DMA1_Channel1->CMAR = (u32)&ADC_ConvertedValue;// set channel1 memory address DMA1_Channel1->CPAR = (u32)&(ADC1->DR); // set channel1 peripheral address DMA1_Channel1->CNDTR = 4; // transmit 4 word PA1-PA4 DMA1_Channel1->CCR = 0x000025A0; // configure DMA channel DMA1_Channel1->CCR |= (1 << 0); // DMA Channel 1 enable RCC->APB2ENR |= (1<<9); // enable periperal clock for ADC1 ADC1->SQR1 = 0x00300000; // four conversion ADC1->SQR2 = 0x00000000; ADC1->SMPR2 = (5<<12)|(5<<9)|(5<<6)|(5<<3); // 0x00000028; set sample time channel1 (55,5 cycles) ADC1->SQR3 = (4<<15)|(3<<10)|(2<<5)|(1<<0); // 0x00000001; set channel order 1-2-3-4 ADC1->CR1 = 0x00000100; // use independant mode, SCAN mode ADC1->CR2 = 0x000E0103; // use data align right,continuous conversion // EXTSEL = SWSTART // enable ADC, DMA mode, no external Trigger ADC1->CR2 |= 1 << 3; // Initialize calibration registers while (ADC1->CR2 & (1 << 3)); // Wait for initialization to finish ADC1->CR2 |= 1 << 2; // Start calibration while (ADC1->CR2 & (1 << 2)); // Wait for calibration to finish ADC1->CR2 |= 0x00500000; // start SW conversion }