Skip to main content
sanjib
Associate III
February 6, 2014
Question

Using external clock for adc triggered

  • February 6, 2014
  • 10 replies
  • 1849 views
Posted on February 06, 2014 at 04:42

How to use external clock for adc triggered. Any help will be highly appreciated

    This topic has been closed for replies.

    10 replies

    Tesla DeLorean
    Guru
    February 6, 2014
    Posted on February 06, 2014 at 05:43

    I'd suppose you could connect TIMx_CHx pins in input capture mode, and use those, or check the configuration options for EXTI line mappings.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    sanjib
    sanjibAuthor
    Associate III
    February 6, 2014
    Posted on February 06, 2014 at 13:34

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6ns&d=%2Fa%2F0X0000000bvo%2FCD7VhFywbhuz5Wc_wYQo15OlB4AvW8DDAGPzggZNoNU&asPdf=false
    sanjib
    sanjibAuthor
    Associate III
    February 6, 2014
    Posted on February 06, 2014 at 13:36

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6nx&d=%2Fa%2F0X0000000bvq%2FaqChIuBTP6RMhWH3ua4.y2cQJKivCOuez2imJZuYHrg&asPdf=false
    sanjib
    sanjibAuthor
    Associate III
    February 6, 2014
    Posted on February 06, 2014 at 14:32

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6lY&d=%2Fa%2F0X0000000but%2FTkXPn2ef0IzTo8mx42yvDvzSnl8C2aiasiOSL_tXll8&asPdf=false
    Tesla DeLorean
    Guru
    February 6, 2014
    Posted on February 06, 2014 at 15:57

    Here's at tip, when testing new ideas keep the code very simple, when you've proved the method integrate it back into your more complicated structure.

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_TIM4); // Needs to be GPIOD for PD12

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    sanjib
    sanjibAuthor
    Associate III
    February 7, 2014
    Posted on February 07, 2014 at 05:27

    Thanks Clive

    I will really implement your tip in my next experiment.

    I have made the change which you have seen. If Timer3 received external clock pulse from timer4 the adc will get triggered and enter  DMA2_Stream0_IRQHandler . For test purpose I have made the LED on but it not glowing. DAC,DMA and ADC was working fine with TRIGGER Internally, I just made change in output compare (TIM 4) ,Input capture (TIME 3) , Configure related pins and this line 

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_CC1  ; After tha it's not working. Please say me what wrong I am doing
    sanjib
    sanjibAuthor
    Associate III
    February 7, 2014
    Posted on February 07, 2014 at 13:15

    Please Help clive. I need it badly

    sanjib
    sanjibAuthor
    Associate III
    February 10, 2014
    Posted on February 10, 2014 at 04:58

    I don't know what misake I am doing please help me anybody

    Tesla DeLorean
    Guru
    February 10, 2014
    Posted on February 10, 2014 at 17:07

    I don't have the time to wade through your code. I can however demonstrate clocking an ADC from an external source.

    // STM32 ADC Sample @ 200 KHz (PC.1) STM32F4 Discovery - sourcer32@gmail.com
    // Strap PC6 (200 KHz) to PA15 (Trigger)
    // Assumptions per system_stm32f4xx.c CPU @ 168 MHz, APB2 @ 84 MHz (/2), APB1 @ 42 MHz (/4)
    #include ''stm32f4_discovery.h''
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    // ADC Channel 11 -> PC1
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    // TIM2_CH1 PA15
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Connect TIM2 pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2); // CH1
    // TIM3_CH1 PC6 200 KHz Clock Source Output
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    /* Connect TIM3 pins to AF */
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); // CH1
    }
    /**************************************************************************************/
    void ADC_Configuration(void)
    {
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_InitTypeDef ADC_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);
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 1 Channel
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversions Triggered
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
    /* ADC1 regular channel 11 configuration */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_15Cycles); // PC1
    /* Enable DMA request after last transfer (Single-ADC mode) */
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
    /* Enable ADC1 DMA */
    ADC_DMACmd(ADC1, ENABLE);
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);
    }
    /**************************************************************************************/
    #define BUFFERSIZE 400 // 200KHz x2 HT/TC at 1KHz
    __IO uint16_t ADCConvertedValues[BUFFERSIZE];
    static void DMA_Configuration(void)
    {
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
    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);
    /* Enable DMA Stream Half / Transfer Complete interrupt */
    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
    /* DMA2_Stream0 enable */
    DMA_Cmd(DMA2_Stream0, ENABLE);
    }
    /**************************************************************************************/
    void TIM2_Configuration(void)
    {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM_ICInitStructure;
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = -1; // Maximal
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    /* Configure Input Capture */
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; // PA15 TIM2_CH1
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInit(TIM2, &TIM_ICInitStructure);
    /* TIM2 TRGO selection */
    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC1); // ADC_ExternalTrigConv_T2_TRGO
    /* TIM2 enable counter */
    TIM_Cmd(TIM2, ENABLE);
    }
    /**************************************************************************************/
    void TIM3_Configuration(void)
    {
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    uint16_t Period, Prescaler;
    Prescaler = 1;
    Period = ((SystemCoreClock / 2) / 200000) - 1; // 200 KHz, from 84 MHz TIM3CLK (ie APB1 = HCLK/4, TIM3CLK = HCLK/2)
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = Period - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    /* TIM PWM1 Mode configuration */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = Period / 4; // 25%
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    /* Output Compare PWM1 Mode configuration: Channel 1 */
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    /* TIM3 enable counter */
    TIM_Cmd(TIM3, ENABLE);
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the DMA Stream IRQ Channel */
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    void DMA2_Stream0_IRQHandler(void) // Called at 1 KHz for 200 KHz sample rate, LED Toggles at 500 Hz
    {
    /* Test on DMA Stream Half Transfer interrupt */
    if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0))
    {
    /* Clear DMA Stream Half Transfer interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
    /* Turn LED3 off: Half Transfer */
    STM_EVAL_LEDOff(LED3);
    // Add code here to process first half of buffer (ping)
    }
    /* Test on DMA Stream Transfer Complete interrupt */
    if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
    {
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
    /* Turn LED3 on: End of Transfer */
    STM_EVAL_LEDOn(LED3);
    // Add code here to process second half of buffer (pong)
    }
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    GPIO_Configuration();
    NVIC_Configuration();
    TIM2_Configuration(); // Input Capture - External ADC Trigger Source - PA15
    TIM3_Configuration(); // Test bench clock source on PC6
    DMA_Configuration();
    ADC_Configuration();
    STM_EVAL_LEDInit(LED3); // Configure LEDs to monitor program status
    STM_EVAL_LEDOn(LED3); // Turn LED3 on, 500 Hz means it working
    ADC_SoftwareStartConv(ADC1); // Start ADC1 Software Conversion
    while(1); // Don't want to exit
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    /* Infinite loop */
    while (1)
    {
    }
    }
    #endif
    /**************************************************************************************/

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    sanjib
    sanjibAuthor
    Associate III
    February 11, 2014
    Posted on February 11, 2014 at 06:38

    Thanks a lot clive.

    You are really a master