2013-03-30 03:59 PM
So I am having an interesting issue with configuring the ADC to work with anything but PortA. I can hook it to any pin on port A, change the ADC channel, and it will work. However, I have tried doing the same on PortB and PortC, but it doesn't seem to work. I enable the PortB/C clock, configure the pins on those ports appropriately, but still nothing. Here is my configuration code:
void ADC_Configuration(void){ ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); /* DMA channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 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_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel6 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE);} #gpio #dma #stm32f2 #adc2013-03-30 04:13 PM
Suggest a part number, and a pin number that doesn't work.
2013-03-30 04:34 PM
Not sure what you mean by part number, but I am using an STM32F103RE, and the devboard is a Waveshare Open103R. For instance, if I want to connect my analog input to another pin on PortA, I simply change the Lines:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5);
To correspond with whatever pin I am using. However, I tried to use PortB (and PortC) unsuccessfully by changing these lines:RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
But I don't read anything on the ADC when using another port.2013-03-30 05:10 PM
I wanted to know what STM32 you were using to contain the universe of answers to your specific situation, and pull the right Data Manual.
PA3 is ADC123_IN3, this is Channel 3 PB3 isn't connected to an ADC, it's apt to be used for JTAG (JTDO)and specifically SWO on the Discovery boards. PC4 is ADC12_IN14, this is Channel 14, usable by ADC1 PB0 is ADC12_IN8, this is Channel 8, usable by ADC1 PB1 is ADC12_IN9, this is Channel 9, usable by ADC1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB, &GPIO_InitStructure); .. ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);2013-03-30 05:33 PM
Thanks! I appreciate the info. Where did you find those mappings? I can't seem to find it in the reference manual. Thanks.
2013-03-30 07:18 PM
The pin assignment details can be found in the Data Sheet for the part
http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1031/LN1565/PF164485
http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/CD00191185.pdf
2014-02-13 06:11 AM
2014-02-13 06:33 AM
Glad it helped, appreciate the thanks.
2014-10-07 06:37 AM
@clive1 Quick question for you can ADC12_IN3 also be used for ADC2 or is it just ADC1?
Also, If I have several pins that can both be used for ADC1 can I enable them one at a time?Your replies so far have been very useful. Thank-you. Cheers, - Lux2014-10-07 10:04 AM
The nomenclature means it's usable by ADC1 and/or ADC2
I guess you could, the normal method would be to set up all the channels you want to use, and enable scanning, reading samples via DMA. If you want to read samples at exactly the same time, then you can use ADC1 and ADC2 in parallel.