2013-01-21 05:53 AM
Hi
friends
I use this program to Read ADC1 Value connected to PC2 portof my
''stm32f4discovery'' card
./****************************************************************************************/
void
ADC_setup( void ){
/* Enable ADC clock (This seems to be a duplicate statement) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/*********************************************************/
/* Configure ADC Channel 12 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*** ADC1 regular channel 12 configuration ***/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
/*Read potentiometer (voltage) value*/
int
POTGetValue( void ){
ADC_SoftwareStartConv(ADC1);
while
(ADC_GetSoftwareStartConvStatus(ADC1));return
ADC_GetConversionValue(ADC1);}
/****************************************************************************************/
int
main( void ){
ADC_setup();
int
val1 = POTGetValue();puts(val1);
}
It works
, Now i want to display many ADC
conversion for example i want to connect
4 signal to 4 port PC0
, P
C
1,
PC2A
ND PC3.
what are the
modifications to do please ?
I found in d
atasheet t
hat PC2 represent
ADC_Channel_12
that's why i use it
And i use in ligne 19 onenumbe
r
of
conversion
Thank you
#stm32f4discovery #adc2013-01-21 06:14 AM
The F4 Standard Peripheral Library example ADC3_DMA provides an example for ADC1 Channel 12. Change the DMA buffer size and number of ADC channels to 4. Change ADCConvertedValue to a 4 word buffer. Configure 3 more GPIOs as analog input. Add 3 more ADC channel configuration statements.
Unless I have overlooked something, that should do it. Cheers, Hal2013-01-21 06:25 AM
Thank you for your replay
I change the program and add PC0,1,2,3 But i don't know how to read conversion value from Channel 1 or 2... Because i don't see a specific command that read actualy from channel 1 this is my program/****************************************************************************************/
void
ADC_setup(
void
)
{
/* Enable ADC clock (This seems to be a duplicate statement) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/*********************************************************/
/* Configure ADC Channel 12 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*** ADC1 regular channel 12 configuration ***/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_3Cycles);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
/*Read potentiometer (voltage) value*/
int
POTGetValue(
void
)
{
ADC_SoftwareStartConv(ADC1);
while
(ADC_GetSoftwareStartConvStatus(ADC1));
return
ADC_GetConversionValue(ADC1);
}
/****************************************************************************************/
int
main(
void
)
{
ADC_setup();
int
val1 = POTGetValue();
puts(val1);
}
I mean that this function
int
POTGetValue(
void
)
{
ADC_SoftwareStartConv(ADC1);
while
(ADC_GetSoftwareStartConvStatus(ADC1));
return
ADC_GetConversionValue(ADC1);
}
Read automatically from channel 1 how to change it to read the others channels please ?
2013-01-21 06:44 AM
The modification I listed are to be made to the ADC1 part of the Library example, which includes initializing DMA. The ADC3 code in the Library Example can be tossed out.
The results are stored in ADCConvertedValue[] in the regular channel configuration sequence. A GetConvertedValue statement is then not needed. I did overlook one thing. Not all ADC channels are freely available on the Discovery Kit. Select from 1,2,3,8,9,11,12,14,15. Cheers, Hal2013-01-22 01:45 AM
Hello
I tried to change the program with the example used in documentation but it gives always ADC value = 0 :(/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC1ConvertedValue = 0;
void
ADC_setup(
void
)
{
/* Enable ADC clock (This seems to be a duplicate statement) */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_2;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
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_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_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);
/*********************************************************/
/* Configure ADC Channel 12 pin as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* 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 regular channel 12 configuration ***/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel12 configuration *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 2, ADC_SampleTime_3Cycles);
/* 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
)
{
ADC_setup();
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
Puts (ADC1ConvertedValue);
}
2013-01-22 04:20 AM
You must not leave main()
The array you write the values too can't be too short for the DMA. You must wait for the values to get loaded/converted. You can't puts() binary values.2013-01-22 04:59 AM
Yes friend i use while(0) of course ,
And the puts i have program it to be able to read value Are there other problem in DMA or ADC code ?2013-01-22 05:26 AM
And the puts i have program it to be able to read value
puts() is no function to ''read values''. It does not accept binary values as parameter.
Are there other problem in DMA or ADC code ?
Yes. Once you fired up the ADC and DMA, it runs in parallel to the code execution in main. What do you think will finish first ?
2013-01-22 06:47 AM
Are there other problem in DMA or ADC code ?
Yes. In DMA initialization, MemoryInc needs to be enabled in order to store the second conversion in the second location of the converted values array. Also, to avoid problems you haven't encountered yet, add the following to ADC1 initialization: ADC_InitStructure.ADC_ExternalTrigConv = 0; Cheers, Hal2013-01-22 07:37 AM