2014-10-15 02:56 AM
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) {}}#endif2014-10-15 03:35 AM
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.2014-10-15 03:57 AM
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.
2014-10-15 04:01 AM
You initialize them with no pulse, if you want them to go home (top centre) then program them with that value instead of zero.
2014-10-15 04:11 AM
You can help me adjust? i want to pick up and bring. i'm starting with STM32f4
2014-10-15 04:29 AM
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // N-1
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // For TIM1/TIM8 ... TIM_OCInitStructure.TIM_Pulse = 2000; // Not ZERO, 2 ms2017-04-18 08:56 AM
i think that problem is caused by electricity
2017-04-18 11:58 AM
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?
2017-04-18 01:32 PM
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