cancel
Showing results for 
Search instead for 
Did you mean: 

help me. timer 1 stm32f4 discovery don't work

41001051
Associate II
Posted on October 15, 2014 at 11:56

i want to control 4 rc servo. i used timer 1, 4 channel, PE9, PE11, PE13, PE14. of course, it don't working. it runs messy. i'm doing robot arm. can you help me find error?

#include ''stm32f4xx.h''

TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;

TIM_OCInitTypeDef          TIM_OCInitStructure;

GPIO_InitTypeDef           GPIO_InitStructure;

void Delay(__IO uint32_t nCount);

void RC_Servo_Init(void);

int main(void)

{

  RC_Servo_Init();

  TIM1->CCR1 = 2200;  

   Delay(10000000);

  TIM1->CCR2 = 2700; 

   Delay(10000000);

   TIM1->CCR3 = 1500;

   Delay(10000000);

   TIM1 ->CCR4 = 2800;

  while (1)

  {}

}

void RC_Servo_Init(void)

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOE, ENABLE);

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11| GPIO_Pin_13 | GPIO_Pin_13;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOE, &GPIO_InitStructure); 

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1);

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1); 

  GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_TIM1);

  

  /* Time base configuration */

  TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/1000000-1;

  TIM_TimeBaseStructure.TIM_Period = 20000;

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

//TIM_OCStructInit(&TIM_OCInitStructure);

/* Servo 1 */

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; 

  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;

  TIM_OC1Init(TIM1, &TIM_OCInitStructure);  

  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

/* Servo 2 */

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC2Init(TIM1, &TIM_OCInitStructure);

TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

/* Servo 3 */

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC3Init(TIM1,&TIM_OCInitStructure);

TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);

/* Servo 4 */

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OC4Init(TIM1,&TIM_OCInitStructure);

TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM1, ENABLE);

  /* TIM1 enable counter */

  TIM_Cmd(TIM1, ENABLE);

  TIM_CtrlPWMOutputs(TIM1, ENABLE);

}

void Delay(__IO uint32_t nCount)

{

  while(nCount--)

  {

  }

}

#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\r\n'', file, line) */

  while (1)

  {}

}

#endif

8 REPLIES 8
Posted on October 15, 2014 at 12:35

I don't know what that means, what does the signal on the scope look like? and how does that relate to the specifications of the servos used?

For TIM1, you might want to look at the RepetitionCount and make sure the initialization structure is fulled completely.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
41001051
Associate II
Posted on October 15, 2014 at 12:57

i'm using tower mg996r, it work distance 1-3 ms, period 20 ms. In main, i've put in the value to CCR1, CCR2,CCR3,CCR4  for control servo. It turn circle then go to desired location.

Posted on October 15, 2014 at 13:01

You initialize them with no pulse, if you want them to go home (top centre) then program them with that value instead of zero.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
41001051
Associate II
Posted on October 15, 2014 at 13:11

You can help me adjust? i want to pick up and bring. i'm starting with STM32f4

Posted on October 15, 2014 at 13:29

TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // N-1

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // For TIM1/TIM8

...

TIM_OCInitStructure.TIM_Pulse = 2000; // Not ZERO, 2 ms
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
The Hung
Associate
Posted on April 18, 2017 at 17:56

i think that problem is caused by electricity

Posted on April 18, 2017 at 18:58

If you declare 2ms pulse available then in the main using TIMx-> CCRx pulse level servo loan, the number will be calculated according to the formula TIMx-> CCRx = 2000 + pulse_width; right?

Posted on April 18, 2017 at 20:32

No, the value in CCRx IS the pulse width, which given the configuration, it is a value whose units are micro-seconds. Thus for a servo expecting  1-3ms is 1000 to 3000us, with a centre position at 2000us (2ms). I reality the span might be 1300-2700, but really depending on the specific servos

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..