2013-01-19 05:33 PM
Hello All,
My ideal setup would be to use adc1, read channels 11,12,13 and the temp as half words then store them in a buffer at a certain memory location. I think the way to do this is to enable the ADC and then hook it up to the DMA, set the dma to have a buffersize of 4, in circular mode. Then have the ADC read each channel and after finishing trigger the dma to store the next value. Been trying to do that for a few days with no luck. I always end up with the OVR flag set in my ADC. The best I have been able to get is one adc channel working at a time. I'm really confused, if i get an error in ADC like ''ovr'' i can clear that flag and reinit, do i need to clear the error flags in the dma also and re init ? When you init a perph does it reset all of the error flags ? This is what I have that does not work, sorry, so sorry for my choice of define prefix. /** * ADC perph defines */#define ZANAL_ADC ADC3#define ZANAL_DR ((uint32_t)0x4001224C)#define ZANAL_ADCCLK RCC_APB2Periph_ADC3#define ZANAL_PIN1 GPIO_Pin_1#define ZANAL_PIN2 GPIO_Pin_2#define ZANAL_PIN3 GPIO_Pin_3#define ZANAL_PIN1_PORT GPIOC#define ZANAL_GPIO1CLK RCC_AHB1Periph_GPIOC#define ZANAL_ADCCHAN1 ADC_Channel_11#define ZANAL_ADCCHAN2 ADC_Channel_12#define ZANAL_ADCCHAN3 ADC_Channel_13#define ZANAL_DMA_CHAN DMA_Channel_2#define ZANAL_DMA_CLK RCC_AHB1Periph_DMA2#define ZANAL_DMA_STREAM DMA2_Stream0void initADC(){ ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable ADC3, DMA2 and GPIO clocks ****************************************/ RCC_AHB1PeriphClockCmd(ZANAL_DMA_CLK | ZANAL_GPIO1CLK, ENABLE); RCC_APB2PeriphClockCmd(ZANAL_ADCCLK, ENABLE); /* DMA2 Stream0 channel0 configuration **************************************/ DMA_InitStructure.DMA_Channel = ZANAL_DMA_CHAN; DMA_InitStructure.DMA_PeripheralBaseAddr = ZANAL_DR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&mygVars->ADCIN1; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; 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_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(ZANAL_DMA_STREAM, &DMA_InitStructure); DMA_Cmd(ZANAL_DMA_STREAM, ENABLE); /* Configure ADC3 Channel12 pin as analog input ******************************/ GPIO_InitStructure.GPIO_Pin = ZANAL_PIN1 | ZANAL_PIN2;// | ZANAL_PIN3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(ZANAL_PIN1_PORT, &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 = DISABLE; 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 = 1; ADC_Init(ZANAL_ADC, &ADC_InitStructure); /* ADC3 regular channel12 configuration *************************************/ ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN2, 1, ADC_SampleTime_3Cycles ); //ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN2, 2, ADC_SampleTime_3Cycles ); //ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN3, 3, ADC_SampleTime_15Cycles ); ADC_DMARequestAfterLastTransferCmd(ZANAL_ADC, ENABLE); /* Enable ADC3 DMA */ ADC_DMACmd(ZANAL_ADC, ENABLE); /* Enable ADC3 */ ADC_Cmd(ZANAL_ADC, ENABLE); ADC_SoftwareStartConv(ZANAL_ADC);}2013-01-19 07:32 PM
This blind example for 3 channels should be workable, or pretty close
/**
* ADC perph defines
*/
#define ZANAL_ADC ADC3
#define ZANAL_DR ((uint32_t)&ADC3->DR)
#define ZANAL_ADCCLK RCC_APB2Periph_ADC3
#define ZANAL_PIN1 GPIO_Pin_1
#define ZANAL_PIN2 GPIO_Pin_2
#define ZANAL_PIN3 GPIO_Pin_3
#define ZANAL_PIN1_PORT GPIOC
#define ZANAL_GPIO1CLK RCC_AHB1Periph_GPIOC
#define ZANAL_ADCCHAN1 ADC_Channel_11
#define ZANAL_ADCCHAN2 ADC_Channel_12
#define ZANAL_ADCCHAN3 ADC_Channel_13
#define ZANAL_DMA_CHAN DMA_Channel_2
#define ZANAL_DMA_CLK RCC_AHB1Periph_DMA2
#define ZANAL_DMA_STREAM DMA2_Stream0
uint16_t Samples[3];
void initADC()
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADC3, DMA2 and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(ZANAL_DMA_CLK | ZANAL_GPIO1CLK, ENABLE);
RCC_APB2PeriphClockCmd(ZANAL_ADCCLK, ENABLE);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_InitStructure.DMA_Channel = ZANAL_DMA_CHAN;
DMA_InitStructure.DMA_PeripheralBaseAddr = ZANAL_DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Samples[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 3;
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(ZANAL_DMA_STREAM, &DMA_InitStructure);
DMA_Cmd(ZANAL_DMA_STREAM, ENABLE);
/* Configure ADC3 Channel12 pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = ZANAL_PIN1 | ZANAL_PIN2 | ZANAL_PIN3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(ZANAL_PIN1_PORT, &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 = DISABLE;
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 = 3;
ADC_Init(ZANAL_ADC, &ADC_InitStructure);
/* ADC3 regular channel12 configuration *************************************/
ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN1, 1, ADC_SampleTime_15Cycles );
ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN2, 2, ADC_SampleTime_15Cycles );
ADC_RegularChannelConfig(ZANAL_ADC, ZANAL_ADCCHAN3, 3, ADC_SampleTime_15Cycles );
ADC_DMARequestAfterLastTransferCmd(ZANAL_ADC, ENABLE);
/* Enable ADC3 DMA */
ADC_DMACmd(ZANAL_ADC, ENABLE);
/* Enable ADC3 */
ADC_Cmd(ZANAL_ADC, ENABLE);
ADC_SoftwareStartConv(ZANAL_ADC);
}
2013-01-20 07:54 AM
If you mean ''temp'' to be internal temperature, it is available only on ADC1 channel 16.
Cheers, Hal2013-01-21 03:52 PM
For some reason I'm still getting the ORE error. I can see that the adc->dr changes but the DMA stops working. I end up with
ADC->SR:0x30 ADC->DR:0x364 ADC->CR1:0x0 || DMA2->LISR:0x38 DMA2->HISR:0x0 Could it be that I'm using dma for something else ? What happens if I init this before or after something else that de inits the dma2 ? I'm using the stm32f4 discovery board. I do use other dma channels for several other things. I'm using a camera on dma2 stream1, maybe they conflict and that causes the error ? Thanks for the help so far, maybe I will just have to leave the dma alone and use 1 adc. or setup the other adc's and use adc2 and adc3 for the other channels and just read their dr on a loop.