2013-09-13 05:04 PM
Hello,
I tried to read two analog inputs from PA3(ADC1_IN3) and PA5(ADC1_IN5). I expected tmpADC[0] has the input data of PA3 and tmpADC[1] has the input data of PA5. However, both tmpADC[0] and tmpADC[1] always have the input data of PA3. I read reference manual multiple times, but I couldn't figure out what is wrong. Please let me know what is problem. I attached my code below(only ADC part). Thanks &sharpinclude <stm32f4xx.h> void ADC_Init(void) { GPIOA->MODER |= (3UL<<6)|(3UL<<10); /*Set PA3 as an analog input, ADC1_IN3, Set PA5 as an analog input ADC1_IN5*/ GPIOA->PUPDR &= ~((3UL<<6)|(3UL<<10)); /*No Pull up and down resistor*/ RCC->APB2ENR =(1<<8); /*ADC1 clk enable*/ ADC1->CR1 = 0; ADC1->CR2 = (1UL<<0)| /*ADC1 power on */ (1UL<<1); /*Continuous conversion*/ ADC1->SMPR1 = 0; ADC1->SMPR2 = 0; ADC1->SQR1 = (1<<20); /* sequence length: two regular conversions*/ ADC1->SQR2 = 0; ADC1->SQR3 = (3UL<<0)|(5UL<<5); /*1st conversion = ADC1_lN3, 2nd conversion = ADC1_IN5*/ ADC->CCR = (1UL<<16); /*fpclk2/4 = 21Mhz */ } short unsigned int get_ADC(void) { ADC1->CR2 |= (1<<30); while(!(ADC1->SR & 0x2)); return ADC1->DR; } int main (void) { tmpADC[0] = get_ADC(); // expecting have data from ADC1_IN3 tmpADC[1] = get_ADC(); //expecting have data from ADC1_IN5 } #stm32f4 #discovery-board #adc-dma2013-09-13 05:41 PM
You'll want to be using DMA
Something like this should suffice// STM32F2/4 Two Channel ADC1 Loop - sourcer32@gmail.com
#include <
stdio.h
>
#include <
stdlib.h
>
#include <
string.h
>
#include ''stm32f4xx.h''
//******************************************************************************
volatile uint16_t ADCConvertedValues[2];
//******************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* Configure ADC1 Channel3 & 5 pins as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//******************************************************************************
void ADC1_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* Enable peripheral clocks *************************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* DMA2_Stream0 channel0 configuration **************************************/
DMA_DeInit(DMA2_Stream0);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel configuration ******************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_480Cycles); // PA3
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_480Cycles); // PA5
/* 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);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
}
//******************************************************************************
int main(void)
{
GPIO_Configuration();
ADC1_Configuration();
puts(''ADC Testing'');
while(1)
{
if (ADCConvertedValues[1] != 0xFFFF)
{
printf(''%03X %03
X'', ADCConvertedValues[0], ADCConvertedValues[1]);
ADCConvertedValues[1] = 0xFFFF;
}
}
while(1); /* Infinite loop */
}
2013-09-25 09:42 AM
Thank you for the reply.
I'm studying DMA setup now with over 1000 pages reference manual.. By the way, DMA should be used in order to read multi channels of ADC input?? Thanks again,2013-09-25 09:53 AM
By the way, DMA should be used in order to read multi channels of ADC input??
It's the prescribed method, for slow speed you might be able to service the EOC2013-10-02 03:41 PM
Yes, I figured out both way, using DMA and EOC multi channel ADC reading.
I couldn't make it work without your help. Thanks again. I attached my code for someone who has similar questions even if I 'm really entry level. this code does blinking LD4 every 1sec withtime2 interrupt, control brightness of LD3with timer4 of PWM mode based on ADC1_In3 input, and turn on and off of LD5 and LD6 depending on ADC1_In5 input. ________________ Attachments : ADC_DMA.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzsV&d=%2Fa%2F0X0000000bRZ%2FaUcuuCv4EfDTsTtyPEt52e8TTUxbSI72CqhLNT9BQ6M&asPdf=false2013-10-02 03:57 PM
The TIM SR register is cleared with a single write, not a read-modify-write (&=)
TIM2->SR = ~1; // Clear flag2013-10-03 09:16 AM
Thank you for the comment for the mistake.
2013-10-07 05:40 PM
I'm trying to achieve a four channel adc with dma. I used the code that clive1 provided but I'm getting the following issues:
Values only on the first 2 elements of the array (All four ports are connected to the same voltage). I'm getting values larger than 12-bits in the elements.Here's the my set-up code below. Any thoughts?Thanks,ChrisGPIO_InitTypeDef GPIO_InitStructure;ADC_InitTypeDef ADC_InitStructure;ADC_CommonInitTypeDef ADC_CommonInitStructure;DMA_InitTypeDef DMA_InitStructure;//#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)volatile uint16_t ADCConvertedValues[4] = {0,0,0,0};void startUp(void){ //ADC Pins RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 4; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_Cmd(DMA2_Stream0, ENABLE); //ADCs ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_ExternalTrigConv = 0; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 4; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_480Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_480Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_480Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 4, ADC_SampleTime_480Cycles); ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_SoftwareStartConv(ADC1);}2013-10-07 06:04 PM
I'm not sure those are particularly good pin choices for the STM32F4-Discovery board.
Might I suggest: PA1 Ch1 PA2 Ch2 PA3 Ch3 PB0 Ch8 PB1 Ch9 PC1 Ch11 PC2 Ch12 PC4 Ch14 PC5 Ch152013-10-07 08:06 PM
Thank you for the prompt reply. I plan on using the rmii ethernet feature so some of those pins will be blocked. I tried using PA3, PB0, PB1, PC2 and I'm still getting the same issue. Only one pin is connected and I only see values for the first two elements of my array and they are giving me values >2^12. Is this some sort of memory issue perhaps?
Thanks