2012-12-20 08:27 AM
Hi,
I am trying to use the 3 ADC in simultaneous mode. I receive correctly every data but I am not able to catch any interruption in order to drive data on the good place. When I have my table I want to dispatch adc_channel_1to a table, adc_channel_2 to a other table etc... But I have no interruption. Here is my code to init DMA:void DMA_Config(void)
{ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); /* DMA2 Stream0 channel0-11-12 configuration **************************************/ DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCTripleConvertedDemiVal; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = 180; 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_Enable; 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); /** Test de l'interruption sur la fin du transfert **/ DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_TE, ENABLE);/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE); } My code to init GPIO: void ADC_Gpio_Config(void) { /* Enable peripheral clocks */ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE); /* Configure ADC Channel 0 - 3 - 4 - 5 pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure ADC Channel 6 - 8 - 9 pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure ADC Channel 10 - 12 - 13 pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_13; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); } And my code to init ADC:void ADC_Config(void)
{ ADC_Gpio_Config(); DMA_Config(); /* Enable peripheral clocks */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE); /*******************************************************************************/ /* ADCs configuration: triple simultaneous with 10cycles delay */ /*******************************************************************************/ /* ADC Common Init */ ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult ; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles; ADC_CommonInit(&ADC_CommonInitStructure);/**< ADC1 regular channels 0 and 3 and 4 (and 5) configuration */
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 = 3; ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channels 0 and 3 and 4 (and 5) configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_3Cycles); // ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_15Cycles); /**< ADC2 regular channels 6 and 8 and 9 configuration */ ADC_Init(ADC2, &ADC_InitStructure);/* ADC2 regular channels 6 and 8 and 9 configuration */
ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 2, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 3, ADC_SampleTime_3Cycles); /**< ADC3 regular channels 10, 12 and 13 configuration */ ADC_Init(ADC3, &ADC_InitStructure);/* ADC3 regular channels 10, 12 and 13 configuration */
ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 2, ADC_SampleTime_3Cycles); ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_3Cycles); /* Enable EOC Interrupt */ ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); /* Enable DMA request after last transfer (Multi-ADC mode) */ ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); /* Enable ADC1 & ADC2 & ADC3 */ ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_Cmd(ADC3, ENABLE); } And my handler: void ADC1_IRQHandler(void) { cptADCIt++; } void DMA2_Stream0_IRQHandler(void) { DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0 | DMA_IT_TEIF0); cptDMAIt++; } The cptXXXIt never increase... Can someone help me? Thanks.2012-12-20 09:26 AM
You are not getting correct values for ADC 2 and 3. The correct pin assignments are:
ADC2 CH8 is PB0 ADC2 CH9 is PB1 ADC3 CH10 is PC0 ADC3 CH12 is PC2 ADC3 CH13 is PC3 This isn't the cause of missing interrupts. I will take a look and see if I can find that problem. Cheers, Hal2012-12-20 09:38 AM
You are missing the command to connect ADC1 to DMA
/* Enable ADC1 DMA since ADC1 is the Master*/ ADC_DMACmd(ADC1, ENABLE); and to start conversion /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1); Cheers, Hal2012-12-20 10:12 AM
Hello,
I do this in my main, that I have not copy... But for the channel I will take a look, I have some difficulties to understand the pin assignment explication on data sheet. Thanks for the informations. Jérome2012-12-20 10:57 AM
I'm not familiar with F4 but in my F1 I had to enable NVIC:
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
2012-12-20 11:20 AM
Perhaps this will help understanding:
PC0 assigned to ADC123_IN10 means that pin PC0 is available as channel 10 on all three ADCs. PA4 assigned to ADC12_IN4 means that pin PA4 is available as channel 4 on ADC1 and 2. If you had a 144 pin count or higher F4, PF3 for example is available only as ADC3 channel 9. Note that there is no channel 9 on ADC123. Cheers, Hal2012-12-20 11:08 PM
Hello,
This is part of my main : NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn | DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);ADC_Config(); //Which is shown is firt message.
while (!DMA_GetCmdStatus(DMA2_Stream0)) { i++; } /* Start ADC1 Software Conversion */ ADC_SoftwareStartConv(ADC1); After that I enter in my infinite loop. I check my project on microXplorer and you are right a do mistake on pin assignment!!! I correct that thx..2012-12-21 12:27 AM
Just for who need it, here is the correction of the pin assignment in accordance with microXplorer for a STM32F407VG.
void ADC_Gpio_Config(void) { /* Enable peripheral clocks */ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE); /* Configure ADC Channel 0 - 3 - 4 - 5 - 6, GPIOA pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure ADC Channel 8 - 9, GPIOB pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure ADC Channel 10 - 12 - 13, GPIOC pin as analog input */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3; //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOC, &GPIO_InitStructure); }2012-12-21 12:52 AM
Have you tried to clear the adc flag in adc handler like you do in dma handler?
Does it work when you disable adc irq?2012-12-21 12:58 AM
Hello knik,
Yes I do but as I never detect the interruption nothing update. void ADC1_IRQHandler(void) { if ( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) ) { ADC_ClearFlag(ADC1, ADC_FLAG_EOC); } cptADCIt++; } But I detect the flag (and reset it) in infinite loop and it increase correctly my cpt... On the other side, I am not sure to use the good handler. Jerome