2014-04-25 01:55 PM
Dear friends,
I need an help about multichannel ADC reading with scan mode. When I configure ADC, unfortunately interrupt routine can occure only one time. And I can not read the other channels.Do you think what is the problem? Why can not I use Scan mode? Best wishes. Öztürk, Metin.RCC_ADCCLKConfig(RCC_PCLK2_Div2);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 11; ADC_Init(ADC1, &ADC_InitStructure); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5); - - ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 11, ADC_SampleTime_55Cycles5); ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE);2014-04-25 02:33 PM
The prescribed method is to use DMA, not the EOC interrupt.
2014-05-26 02:33 AM
Dear friend,
Thank you very much for your supports. Is it meaning that if we want to use scan mode, do we have to use DMA? best wishes. Ozturk, Metin.2014-05-26 12:32 PM
Yes, use DMA, and the use the HT (double size buffer) or TC interrupt from the DMA to act as a group EOC for your collection of samples. Use circular mode, and if you have a desired periodicity trigger the ADC with a TIM channel to start sampling the group.
The reason not to do it with ADC EOC interrupts is the rate at which they will occur is too high to be practical. I'm not even sure ST supports it, as I've never seen a reason to try, but we do occasionally see people wanting to try.2014-05-27 07:40 AM
Dear friend,
Thank you very much for your kind replay. Yes I can read in scan mode with DMA.(I can check the ADC datas in debug mode) At this point what is the best way to evaluate channel values? 1- In my opinion, when the DMA interrupt occurs, I have to stop DMA interrupt and DMA function. And read the datas.ADC_DMACmd(ADC1, DISABLE);
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, DISABLE); 2- And after an internal or external event, I can start DMA again. ADC_DMACmd(ADC1, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);But when I do this, data' s order change. What do I have to do?
best wishes.void DMA1_Channel1_IRQHandler(void){
DMA_ClearITPendingBit(DMA1_IT_TC1);
ADC_DMACmd(ADC1, DISABLE); DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, DISABLE); }/******************************************************************************/void EXTI0_IRQHandler(void){ if(EXTI_GetITStatus(EXTI_Line0) != RESET){
EXTI->PR = EXTI_Line0; //EXTI_ClearITPendingBit(EXTI_Line4);
ADC_DMACmd(ADC1, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE); }}2014-05-27 08:46 AM
You can make the ADC trigger off EXTI11
You can do a software trigger You can copy the values in the DMA TC interrupt You can double the buffer size, and process the first half at DMA HT, and the second half at DMA TC If I had to use EXTI0, then I'd set the ADC in Scan:ENABLE, Continuous:DISABLE, DMA to circular, pointing at my buffer, and enable it ONCE. In the EXTI0 interrupt I would trigger a ''start conversion'', and process the data in the DMA TC interrupt.2014-05-28 10:34 PM
Dear friend,
In discontinuous and scan mode I triggered start conversion in EXTI0. And I can read datas properly. Thank a lot. with my best wishes Ozturk, Metin.