cancel
Showing results for 
Search instead for 
Did you mean: 

triggering adc1 from Timer 1 Capture Compare Interupt

gareth
Associate II
Posted on December 16, 2008 at 13:27

triggering adc1 from Timer 1 Capture Compare Interupt

14 REPLIES 14
gareth
Associate II
Posted on May 17, 2011 at 12:51

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

Gareth

brianforde9
Associate II
Posted on May 17, 2011 at 12:51

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.

brianforde9
Associate II
Posted on May 17, 2011 at 12:51

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.

gareth
Associate II
Posted on May 17, 2011 at 12:51

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

Gareth

brianforde9
Associate II
Posted on May 17, 2011 at 12:51

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.

gareth
Associate II
Posted on May 17, 2011 at 12:51

Have just changed that to disable, and no difference. was playing around with that one yesterday as i assumed the same.

cheers

Gareth D

brianforde9
Associate II
Posted on May 17, 2011 at 12:51

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.

brianforde9
Associate II
Posted on May 17, 2011 at 12:51

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?).

gareth
Associate II
Posted on May 17, 2011 at 12:51

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