這是主函數(shù):
int?main(void) { ????NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); ????Delay_Init(); ????USART_Printf_Init(115200); ????PWM_Init(2000-1,?720-1); ????while(1) ????{ ????????Delay_Init(); ????????Servo_SetAngle2(0); ????????Delay_Ms(1000); ????????Servo_SetAngle2(45); ????????Delay_Ms(1000); ????????Servo_SetAngle2(90); ????????Delay_Ms(1000); ????????Servo_SetAngle2(135); ????????Delay_Ms(1000); ????????Servo_SetAngle2(180); ????????Delay_Ms(1000); ????} }
按照程序,舵機的角度應該從0°開始,依次變?yōu)?5°、90°、135°、180°,然后循環(huán)往復。但實際情況是舵機不能穩(wěn)定地實現(xiàn)上述過程,如本應該:0°(停頓1000ms)->45°(停頓1000ms)->90°(停頓1000ms)->135°(停頓1000ms)->180°(停頓1000ms)······,但實際情況卻可能是0°(停頓1000ms)->45°(停頓1000ms)->90°(停頓1000ms)->135°(停頓時間超過1000ms)->90°。
尤其是板子剛上電的時候,舵機常常在兩個固定的角度上不斷來回運動,復位幾次后會穩(wěn)定到預計過程,但是運行幾個周期后又會亂跑,然后再次穩(wěn)定到預計過程,這樣不斷循環(huán)。
下面是舵機控制函數(shù)
void?PWM_Init(u16?arr,?u16?psc) { ????/*------------------------GPIO初始化-----------------------*/ ????????GPIO_InitTypeDef??GPIO_InitStructure; ????????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,?ENABLE); ????????//設置該引腳為復用輸出功能,輸出TIM1?CH1的PWM脈沖波形???GPIOA.8 ????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_8;???????//TIM1_CH1 ????????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;?????//復用推挽輸出 ????????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz; ????????GPIO_Init(GPIOA,?&GPIO_InitStructure); ????????//設置該引腳為復用輸出功能,輸出TIM1?CH3的PWM脈沖波形???GPIOA.10 ????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_10;//TIM1_CH2 ????????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;?????//復用推挽輸出 ????????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz; ????????GPIO_Init(GPIOA,?&GPIO_InitStructure); ????????//?開啟定時器時鐘,即內部時鐘CK_INT=72M ????????RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); ????????RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,?ENABLE);??//打開管腳復用AFIO時鐘 ????????/*--------------------定時器時基結構體初始化------------------*/ ????????TIM_TimeBaseInitTypeDef??TIM_TimeBaseStructure; ????????TIM_TimeBaseStructure.TIM_Period?=?arr; ????????TIM_TimeBaseStructure.TIM_Prescaler?=?psc; ????????TIM_TimeBaseStructure.TIM_ClockDivision?=?TIM_CKD_DIV1;//不分頻 ????????TIM_TimeBaseStructure.TIM_CounterMode?=?TIM_CounterMode_Up;//?計數(shù)器計數(shù)模式,設置為向上計數(shù) ????//????TIM_TimeBaseStructure.TIM_RepetitionCounter?=?0;//?重復計數(shù)器的值,沒用到不用管 ????????TIM_TimeBaseInit(TIM1,?&TIM_TimeBaseStructure);//初始化定時器 ????????/*-------------------------輸出比較結構體初始化---------------------------------*/ ????????????TIM_OCInitTypeDef??TIM_OCInitStructure; ????????????TIM_OCInitStructure.TIM_OCMode?=?TIM_OCMode_PWM1; ????????????TIM_OCInitStructure.TIM_OutputState?=?TIM_OutputState_Enable;//比較輸出使能 ????????????TIM_OCInitStructure.TIM_OCPolarity?=?TIM_OCPolarity_High;//?輸出通道電平極性配置 ????????????//PA8設置 ????????????TIM_OCInitStructure.TIM_Pulse?=?0;//設置占空比大小 ????????????TIM_OC1Init(TIM1,?&TIM_OCInitStructure); ????????????TIM_OC1PreloadConfig(TIM1,?TIM_OCPreload_Enable);//使能TIM1在CCR1上的預裝載寄存器 ????????????TIM_ARRPreloadConfig(TIM1,?DISABLE);//允許或禁止在定時器工作時向ARR(自動重裝載值)的緩沖器中寫入新值,以便在更新事件發(fā)生時載入覆蓋以前的值,此處為不允許 ????????????//PA10設置 ????????????TIM_OCInitStructure.TIM_Pulse?=?0;//設置占空比大小 ????????????TIM_OC3Init(TIM1,?&TIM_OCInitStructure); ????????????TIM_OC3PreloadConfig(TIM1,?TIM_OCPreload_Enable);//使能TIM1在CCR1上的預裝載寄存器 ????????????TIM_ARRPreloadConfig(TIM1,?DISABLE);//允許或禁止在定時器工作時向ARR(自動重裝載值)的緩沖器中寫入新值,以便在更新事件發(fā)生時載入覆蓋以前的值,此處為不允許 ????????????TIM_Cmd(TIM1,?ENABLE); ????????????TIM_CtrlPWMOutputs(TIM1,?ENABLE);//?主輸出使能,當使用的是通用定時器時,這句不需要 } /********************************************************************* ?*?@fn??????Servo_SetAngle1 ?* ?*?@brief???舵機1的角度控制 ?* ?*?@return??none ?*/ void?Servo_SetAngle1(float?angle) { ????u16?ccp=50+angle/0.9; ????TIM_SetCompare1(TIM1,ccp); ????Delay_Ms(100); } /********************************************************************* ?*?@fn??????Servo_SetAngle1 ?* ?*?@brief???舵機2的角度控制 ?* ?*?@return??none ?*/ void?Servo_SetAngle2(float?angle) { ????if(angle?>?180) ????{ ????????angle?=?180; ????} ????if(angle?<?0?) ????{ ????????angle?=?0; ????} ????u16?ccp=50+angle/0.9; ????TIM_SetCompare3(TIM1,ccp); } /*********************************************************************