×
单片机 > 单片机程序设计 > 详情

STM32控制两个舵机

发布时间:2020-05-30 发布时间:
|

原理:一个定时器的两路PWM输出

参考:正点原子代码

timer.c代码

void TIM5_PWM_Init(u16 arr,u16 psc)
{  
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;



RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);//使能定时器5时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟

 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO


 
   //初始化TIM5
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

//初始化TIM3 Channel2 PWM模式 
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM5, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2Init(TIM5, &TIM_OCInitStructure);  



TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);  //使能TIM5在CCR1上的预装载寄存器
TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable);  ////使能TIM5在CCR2上的预装载寄存器
 
 
TIM_ARRPreloadConfig(TIM5,ENABLE);
TIM_Cmd(TIM5, ENABLE);  //使能TIM5

}

main.c代码

 int main(void)
 {
  u16 led0pwmval=0;
u8 dir=1;  
delay_init();      //延时函数初始化   
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200);//串口初始化为115200
  LED_Init();      //LED端口初始化
  TIM3_PWM_Init(2999,71);//一个PWM周期为3ms,溢出值为3000
delay_ms(5000);//给单片机一些启动时间

//舵机初始化,使两个舵机连接的板子旋转到大致平衡的位置
TIM_SetCompare1(TIM5,L115);
delay_ms(3000);
TIM_SetCompare2(TIM5,L110);
delay_ms(3000);

 
 
delay_ms(3000);
delay_ms(3000);
delay_ms(3000);
delay_ms(3000);
while(1)//引脚注释 A0 ch1  ,   A1  ch2
{  
 TIM_SetCompare1(TIM5,L120);
delay_ms(3000);
TIM_SetCompare2(TIM5,L160);
delay_ms(3000);
TIM_SetCompare2(TIM5,L30);
 delay_ms(2000);
TIM_SetCompare2(TIM5,L110);
 delay_ms(2000);
}


附上舵机旋转角度定义头文件,如有错误,还请指正。

不过实际使用还得看舵机质量,有些舵机达不到这个精度,如果在主函数里让舵机1度1度的往上加,实际情况就是:舵机像要死了一样……

//一个PWM周期为3ms,溢出值为3000
//(arr+1)/3000*3ms=0.5ms+0.008*(jiaodu/0.74)
//arr=499+10.811*jiaodu
#define L0 499//0度
#define L1 510//1度
#define L2 521//2度,依此类推
#define L3 531
#define L4 542
#define L5 553
#define L6 564
#define L7 575
#define L8 585
#define L9 596
#define L10 607
#define L20 618
#define L30 823
#define L40 931
#define L45 985
#define L50 1040
#define L60 1148
#define L70 1255
#define L80 1364
#define L90 1472
#define L100 1580
#define L110 1688
#define L120 1796
#define L130 1904
#define L140 2013
#define L150 2121
#define L160 2229
#define L170 2337
#define L180 2445
#define L185 2499




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
8051单片机的函数发生器的设计