AnsweredAssumed Answered

Timer output toggle issue

Question asked by d_souza_mathew.neil on Oct 25, 2011
Latest reply on Nov 5, 2012 by waclawek.jan
Hi all,

I have a strange problem using Timer1 in Output Toggle mode. My objective is to generate square waves of different frequencies using the same timer. I've based my code on the 'TIM_OCToggle' example in the Standard Peripheral Library documentation.

I'm using an IAR STM32-SK Starter Kit dev board (STM32F103RB). I've also tested my code on the Olimex H-103 dev board.

When I use the example from the documentation, which uses Timer 3, the code works perfectly.

However, when I attempt to change to Timer 1 - I get absolutely no switching on the Timer 1 outputs (I'm using pins A8 and A9 - channel 1 and 2). When I run the code in Download and Debug mode, I can see that the program sequence works as I expect, and that the program enters the TIM1_CC interrupt handler. However the output does not switch.

I've ensured that pins A8 and A9 are initialised, that I'm not running any remap function, that clocks are being directed to Port A and AFIO and Timer1.

I'd appreciate any advice on what might be happening. Thanks! (I've attached my code below)





void main(void)
{
  SystemInit();  
  RCC_Configuration();
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

  NVIC_Configuration();

  GPIO_InitTypeDef GPIO_InitStructure7;
  GPIO_InitStructure7.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure7.GPIO_Mode = GPIO_Mode_FF_PP;
  GPIO_InitStructure7.GPIO_Pin = GPIO_Pin_9;
  GPIO_Init(GPIOA, &GPIO_InitStructure7);
  GPIO_InitStructure7.GPIO_Pin = GPIO_Pin_8;
  GPIO_Init(GPIOA, &GPIO_InitStructure7);

  initialiseTimers();
  
  while(1);
}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Enable the TIM1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void RCC_Configuration(void)
{
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();
  
  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);
  
  /* Wait till HSE is ready */
  if(RCC_WaitForHSEStartUp() == SUCCESS)
  {
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    
    /* PCLK2 = HCLK */
    RCC_PCLK2Config(RCC_HCLK_Div1);
    
    /* PCLK1 = HCLK/2 */
    RCC_PCLK1Config(RCC_HCLK_Div4);
    
    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    
    /* PLLCLK = 8MHz * 9 = 72 MHz */
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    /* Enable PLL */
    RCC_PLLCmd(ENABLE);
    
    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }
    
    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    
    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
}

void initialiseTimers(void)
{
  Int16U PrescalerValue = 0;
  
  TIM_TimeBaseInitTypeDef TIM1_TimeBaseInitStruct;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  TIM1_TimeBaseInitStruct.TIM_Period = 300;
  TIM1_TimeBaseInitStruct.TIM_Prescaler = PrescalerValue;
  TIM1_TimeBaseInitStruct.TIM_ClockDivision = 0;
  TIM1_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseInitStruct);

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 1000;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 1002;
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);

  TIM_Cmd(TIM1, ENABLE);
  TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
}

void TIM1_CC_IRQHandler(void)
{
  uint16_t capture;
  /* TIM1_CH1 toggling with frequency = */
  if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
  {
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC1 );
    capture = TIM_GetCapture1(TIM1);
    TIM_SetCompare1(TIM1, capture + 1000);
  }
  
  /* TIM1_CH2 toggling with frequency = */
  if (TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)
  {
    TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
    capture = TIM_GetCapture2(TIM1);
    TIM_SetCompare2(TIM1, capture + 1002);
    }
  }
}

Outcomes