cancel
Showing results for 
Search instead for 
Did you mean: 

Reading multiple channels of ADC

IMumt.1
Associate II

I am almost new to STM32 boards and need to read the multiple channels of ADC.Firstly,can someone tell me that am I allowed to read voltage from more than 16 pins(as there are 16 channels of ADC). Moreover, I have the following code to read 2 ADC channels using DMA. I am not getting that when ADC channel 1 is read where it's value is stored and how would I retrieve it to compare it with some predefined value?Same case for ADC channel2.Which function to use to read ADC channel 1 value.This is the code.Please give me some starting point:

#include "stm32f4xx.h"

#include "stm32f4_discovery.h"

uint16_t ADC1ConvertedValue[2] = {0,0};//Stores converted vals

void DMA_config()

{

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 ,ENABLE);

DMA_InitTypeDef    DMA_InitStruct;

DMA_InitStruct.DMA_Channel = DMA_Channel_0;

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) 0x4001204C;//ADC1's data register

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;

DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStruct.DMA_BufferSize = 2;

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Reads 16 bit values

DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//Stores 16 bit values

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Priority = DMA_Priority_High;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;

DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_Init(DMA2_Stream0, &DMA_InitStruct);

DMA_Cmd(DMA2_Stream0, ENABLE);

}

void ADC_config()

{

/* Configure GPIO pins ******************************************************/

ADC_InitTypeDef    ADC_InitStruct;

ADC_CommonInitTypeDef ADC_CommonInitStruct;

GPIO_InitTypeDef   GPIO_InitStruct;

RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC1 is connected to the APB2 peripheral bus

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;// PA0,PA1

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;//The pins are configured in analog mode

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;//We don't need any pull up or pull down

GPIO_Init(GPIOA, &GPIO_InitStruct);//Initialize GPIOA pins with the configuration

/* ADC Common Init **********************************************************/

ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;

ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonInitStruct);

/* ADC1 Init ****************************************************************/

ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit int (max 4095)

ADC_InitStruct.ADC_ScanConvMode = ENABLE;//The scan is configured in multiple channels

ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//Continuous conversion: input signal is sampled more than once

ADC_InitStruct.ADC_ExternalTrigConv = DISABLE;

ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//Data converted will be shifted to right

ADC_InitStruct.ADC_NbrOfConversion = 2;

ADC_Init(ADC1, &ADC_InitStruct);//Initialize ADC with the configuration

/* Select the channels to be read from **************************************/

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles);//PA0

ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_144Cycles);//PA1

/* Enable DMA request after last transfer (Single-ADC mode) */

ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

/* Enable ADC1 DMA */

ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

}

int main(void)

{

DMA_config();

ADC_config();

while(1)

{

ADC_SoftwareStartConv(ADC1);

}

return 0;

}

2 REPLIES 2

uint16_t ADC1ConvertedValue[2] = {0,0};//Stores converted vals

JW

IMumt.1
Associate II

This code finally works for reading two channels but is giving issue for reading 4 channels(in case of 4 channels it shows data of only 2 channels i-e channel 0 and channel 1 but not showing for channel 3 and channel 4 ).Can someone tell why?

#include "stm32f4xx.h"

#include "stm32f4_discovery.h"

volatile uint16_t ADC1ConvertedValue[4] = {0,0,0,0};//Stores converted vals [2] = {0,0}

void DMA_config()

{

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 ,ENABLE);

DMA_InitTypeDef    DMA_InitStruct;

DMA_InitStruct.DMA_Channel = DMA_Channel_0;

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) 0x4001204C;//ADC1's data register

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;

DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStruct.DMA_BufferSize = 4;//2

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//Disable originally

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Reads 16 bit values _HalfWord

DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//Stores 16 bit values _Halfword

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Priority = DMA_Priority_High;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;

DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;//_HalfFull

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_Init(DMA2_Stream0, &DMA_InitStruct);

DMA_Cmd(DMA2_Stream0, ENABLE);

}

void ADC_config()

{

/* Configure GPIO pins ******************************************************/

ADC_InitTypeDef    ADC_InitStruct;

ADC_CommonInitTypeDef ADC_CommonInitStruct;

GPIO_InitTypeDef   GPIO_InitStruct;

RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//ADC1 is connected to the APB2 peripheral bus

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;// PA0,PA1,PA2,PA3

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;//The pins are configured in analog mode

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;//We don't need any pull up or pull down

GPIO_Init(GPIOA, &GPIO_InitStruct);//Initialize GPIOA pins with the configuration

/* ADC Common Init **********************************************************/

ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;

ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonInitStruct);

/* ADC1 Init ****************************************************************/

ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;//Input voltage is converted into a 12bit int (max 4095)

ADC_InitStruct.ADC_ScanConvMode = ENABLE;//The scan is configured in multiple channels

ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//Continuous conversion: input signal is sampled more than once

ADC_InitStruct.ADC_ExternalTrigConv = DISABLE;

ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//Data converted will be shifted to right

ADC_InitStruct.ADC_NbrOfConversion = 4;

ADC_Init(ADC1, &ADC_InitStruct);//Initialize ADC with the configuration

/* Select the channels to be read from **************************************/

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_144Cycles);//PA0

ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_144Cycles);//PA1

ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_144Cycles);//PA2

ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_144Cycles);//PA3

/* Enable DMA request after last transfer (Single-ADC mode) */

ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

/* Enable ADC1 DMA */

ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */

ADC_Cmd(ADC1, ENABLE);

}

int main(void)

{

DMA_config();

ADC_config();

while(1)

{

ADC_SoftwareStartConv(ADC1);

//value=ADC_Read();

}

return 0;

}