2008-12-16 04:27 AM
triggering adc1 from Timer 1 Capture Compare Interupt
2011-05-17 03:51 AM
Hi all,
I am having an issue triggering an ADC regular group conversion from an external trigger. I have setup Timer 1 to produce a capture compare interuput (CC3) when an external line goes high (after a time delay). This interupt is being correctly generated and can be observed to call the NVIC routine void TIM1_CC_IRQHandler(void) if the NVIC function is enabled. So the problem seems to be in getting the adc to recognise the interupt has occured and act upon it! my code for the adc is :- ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 5; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ 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_2, 3, ADC_SampleTime_55Cycles5); /*enable temperature sensor and vref internal channel*/ ADC_TempSensorVrefintCmd(ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 4, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 5, ADC_SampleTime_55Cycles5); /*enable adc1 extetanl trigger conversion*/ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); can anybody help me with this? I am fairly new to this processor but will be using it alot over next 12 months so hopefully i shall be able to return the favour one day. Cheers all Gareth2011-05-17 03:51 AM
I'm doing somthing quite similar, but with a different timer, and it is working for me. The code I have is almost identical you yurs, but with the following additions, at the end (after calibration is complete).
. . . ADC_Cmd(ADC1, ENABLE); TIM_Cmd(TIM1, ENABLE); Brian F.2011-05-17 03:51 AM
You need to call ADC_Cmd() twice, once to wake the ADC from powerdown, and a second time to start conversion.
Refer to Manual, Section 10.12.3, ADON.2011-05-17 03:51 AM
Hi Brian,
Thankyou for the reply. Adding those two lines at then end causes the adc to repeatedly trigger. I assume it is because the ADC is beign enabled a second time (once before the calibration). The Timer1 enable is currently implimented in the timer module but have tried putting it at end of this section too. No luck. Thankyou again for ideas though. p.s to be very cheeky would it be possible to see a copy of the working code for another timer? might help me debug this one. regards Gareth2011-05-17 03:51 AM
No, the reason it is repeatedly triggering is that you have
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; If you set this to DISABLE, then only one trigger will occur per CC3 edge. Brian F.2011-05-17 03:51 AM
Have just changed that to disable, and no difference. was playing around with that one yesterday as i assumed the same.
cheers Gareth D2011-05-17 03:51 AM
I tried to attach a file, but no joy.
Try putting RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_DeInit(ADC1); immediately before your call to ADC_Init(). I don't think this will make a difference, as the ADC is converting for you, albeit not triggered. Another thing you might try is a single triggered conversion (i.e. only one channel), just to check is the triggering working. The problem might be channel 16 & 17, as I have never used these. In your code, you are using channels 0, 1, 2, 15, & 16. Is this your intention? Temperature & Vref are connected to channels 16 & 17. Brian F.2011-05-17 03:51 AM
Another thing;
I don't see where you are initialising the DMA. I don't know what effect not initialising the DMA correctly will have on the operation of the ADC (i.e. if ADC1_DR is not read, does the scan conversion halt?).2011-05-17 03:51 AM
cheers for the replies.
as you suspected adding those lines made no difference, the adc conversion and dma routine are setup correctly i believe as have tested them with software triggers. but here is the code jst incase :) void DMA1_Configuration(void) { /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = DMA_ADC1_Base_Address; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 5; 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_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 Channel1 complete transfer interrupt */ DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); } i appreciate your comments, any ideas atm are all welcome. thanks