2014-11-16 08:25 AM
Hi all,
For a school project we need to work with theSTM32LDiscovery board. We want to make a kind of plantcare system that reads the temperature and light in analog values. Now we got to the part that we can configure the ADC to convert the value from one pin but we also need to read the other sensor. And that's where we are stuck. I found something where we could use the DMA to put all read values in but it doesn't work. We use the following code for the configuration.void ADC_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_HSICmd(ENABLE);
/* Configure PA5 as an ADC input */
/* Pin 5 of port A is internally connected with ADC channel 5 */
/* See page 24 of the stm32L discovery user manual */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitTypeDef ADC_InitStructure;
//ADC1 configuration
//select continuous conversion mode
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
//We will convert multiple channels
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
//we will convert one time
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //!
//select no external triggering
//right 12-bit data alignment in ADC data register
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//2 channels conversion
ADC_InitStructure.ADC_NbrOfConversion = 8;
//load structure values to control and status registers
ADC_Init(ADC1, &ADC_InitStructure);
/* Now do the setup */
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_48Cycles);
ADC_Cmd(ADC1, ENABLE);
//enable DMA for ADC
ADC_DMACmd(ADC1, ENABLE);
// Wait until ADC is ready
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET)
;
}
void DMAInit(void) {
//enable DMA1 clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//create DMA structure
DMA_InitTypeDef DMA_InitStructure;
//reset DMA1 channe1 to default values;
DMA_DeInit(DMA1_Channel1);
//channel will be used for memory to memory transfer
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
//setting normal mode (non circular)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//medium priority
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//source and destination data size word=32bit
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//automatic memory destination increment enable.
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//source address increment disable
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//Location assigned to peripheral register will be source
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//chunk of data to be transfered
DMA_InitStructure.DMA_BufferSize = ARRAYSIZE;
//source and destination start addresses
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC1_DR;
//adc values is: volatile uint16_t ADC_values[ARRAYSIZE];
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) ADC_values;
//send values to DMA registers
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// Enable DMA1 Channel Transfer Complete interrupt
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1
NVIC_InitTypeDef NVIC_InitStructure;
//Enable DMA1 channel IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Can anyone help us?
Thanks in advance!
Rick
#board #adc #adc #stm32 #adm #discovery
2014-11-16 10:34 AM
If you want to have 8 channels, then you're going to need to decide which pins you're going to use, configure them as analogue inputs, and then enumerate all 8, with rank numbers 1-8 to the scanning list.
So far you've got one, with rank #2, and a bunch of missing code and defines.2014-11-17 08:32 AM
Hi thanks for your reply! So if i want to use only 2 channels i could change the eights to 2's and configure an extra channel? I tried that but it didn't work. the
ADC_values array
doesnt get filled.2014-11-17 09:24 AM
ADC_InitStructure.ADC_NbrOfConversion = 2;
//load structure values to control and status registers ADC_Init(ADC1, &ADC_InitStructure); /* Now do the setup */ ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_48Cycles); // #1 CH4ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_48Cycles); // #2 CH5
I'd rework the example, but it's incomplete.2014-11-17 09:36 AM
[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/STM32%20ADC%20DMA%20Circular%20Mode&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=225]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Discovery%2FSTM32%20ADC%20DMA%20Circular%20Mode&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F¤tviews=225
Single up example2014-11-24 09:11 AM
After some trial and error I got everything working based on your link! Thanks :D