2012-08-23 03:41 PM
stm32f4-discovery
I am impressed with the built-in 12bit adc. I want eventually to read 12 voltages at 10Hz or greater. I am going to simplify the problem to 2 channel add and expand to 12 once that is working. I read with great interest:http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00258017.pdfIn particular article 1.2Multichannel (scan), single conversion mode
but unfortunately it says:this application note is not delivered with a firmware example of this mode.
So I tried to merge projects across the web but it doesn't quite work yet (it just converts one analog input, the other one is 0 all the time). Can anyone provide a sample code or scrutinize my approach:__IO uint32_t ADC3ConvertedVoltage[2] = {0,0};void ADC3_DMA_Config(void){ ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable ADC3, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); /* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStructure.DMA_Channel = DMA_Channel_2; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC3_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC3ConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // u32 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); /* Configure ADC3 Channel12 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); /* ADC3 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_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 2; ADC_Init(ADC3, &ADC_InitStructure); /* ADC3 regular channel12 configuration *************************************/ ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 2, ADC_SampleTime_15Cycles); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE); /* Enable ADC3 DMA */ ADC_DMACmd(ADC3, ENABLE); /* Enable ADC3 */ ADC_Cmd(ADC3, ENABLE);}Debugger:Breakpoint 1, main () at main.c:2727 }4: /x ADC3ConvertedValue = {0x550, 0x0}3: /x ADC3ConvertedValue = {0x540, 0x0}2: /x ADC3ConvertedValue = {0x550, 0x0}1: ADC3ConvertedValue = {1408, 0}(gdb) #multichannel-adc-stm32f4 #read-function2012-08-23 07:29 PM
A half word is 16-bits.
2012-08-24 06:23 AM
While the F4 version on the Discovery board has 16 ADC channels, only 9 are free due to pin assignments to other board functions. See the Discovery manual for pin assignments. You should still be able to learn with what you have before making your own board.
You need to initialize PC1 and PC2, not PC2 and PC3. Channel 13 (PC3) is not a free channel And, you need to add the following statement to prevent strange behavior: ADC_InitStructure.ADC_ExternalTrigConv = 0; Cheers, Hal2012-08-24 11:31 AM
I switched to PC1 and PC2 and it behaved the same way.
After a little messing around, I found another post and changed to this:DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
And it is working now. Thanks for the help.2013-06-08 11:26 PM
Jon,
Could you post your main.c implementation...that is, how you are reading the data? I successfully ran single ADC input project with output to serialmonitor, but your code(with corrections posted) shows only 0 in serial monitor. I can confirm voltages correct by multitester and debugger shows appropriate responses(changing data) in the ADC3->DR. So I guess it's my implentation of 'get data' function.2013-06-08 11:33 PM
(sorry...tried posting from tablet...go figure...)
2013-06-09 04:47 AM
Please just top post responses, it is not necessary to quote the original message.
The Microsoft forum software does not permit posting from most mobile devices2013-06-09 09:40 AM
Yeah, I supposed the embedded Word(tm) Editor thing might work on a Surface, who has one of those, but it doesn't work on a Nexus 7?
At a glance the code needs a couple of tweaks, most notably a ''volatile uint16_t'' for the receiving data structure, peripheral inc disabled and a correct pin/channel association