立即注册 登录
返回首页

uid:215520的个人空间

日志

stm32驱动舵机

已有 685 次阅读2019-3-13 12:35 |个人分类:模块程序

一、舵机分类:数字舵机和模拟舵机

一般价格贵的舵机基本都是数字舵机,反之就是模拟舵机了。他们之间的区别就是,数字的舵机你输出脉冲后,会很清脆的到达固定的角度,不会产生异响,脉冲固定舵机不会产生吱吱的响。模拟舵机你输出的脉冲固定以后吱吱的响,在不动和动的边缘游荡。

需要驱动他们就必须输出固定的脉冲。这篇博主写的不错。(http://blog.sina.com.cn/s/blog_8240cbef01018hu1.html)总结一下,就是需要产生20ms(50Hz)基准,占空比可调的PWM波。


根据这个表格,我们得出一个公式:一度的占空比 = 1 / 90 * 角度 + 0.5

搞明白这些,我们就要去让stm32产生这样的PWM的就可以驱动舵机了。

二、STM32产生PWM

       产生PWM就要用到定时器了,Stm32内部的定时器资源非常丰富。

这里我们用通用定时器。

初始化的话,正常配置就可以。

强调一下:stm32定时器的时钟频率是72MHz,这里想问一下是8MHz * 9 = 72MHz来的吗?

看下时钟树:

看这里 ,是由APB1的分频系数决定的。APB1的外设桥的时钟最大频率是36MHz,如果AHB的频率是72MHz的话,

APB1的分频系数必定为2,TIM2,3,4的时钟频率是36MHz*2得来的。

时钟频率怎么来的知道了的话。

这样的话,咱们就知道了定时器的时钟频率为72MHz。通过配置PSC预分频器寄存器R自动重装载寄存器(它们都是16位的寄存器),就可以设置到咱们需要的PWM波了。

目标是50Hz的PWM波形,72000000 / 7200(PSC) / 200(ARR) = 50Hz

这只是一组PSC和ARR的组合,读者可以自己选择。这样的话,前面的计算公式就要相应改变了,放大10倍:ARR = 1 / 9 * 角度 + 5

根据这个公式就可以算得,ARR自动重装的值了。(输出极性:TIM输出比较极性低)

下面贴出代码:

舵机控制代码

void Servo_Control(uint16_t angle)

{

       float temp;

       temp = (1.0 / 9.0) * angle + 5.0;//寄存器值 = 1/9 * 角度 + 5

       TIM_SetCompare4(TIM4, (uint16_t)temp);//将角度值写入比较寄存器

}

定时器初始化代码:

void Timer4_Init(void)

{    

       GPIO_InitTypeDef GPIO_InitStructure;

       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

       TIM_OCInitTypeDef  TIM_OCInitStructure;

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);//使能PB外设和AFIO复用功能模块时钟使能

                                                                                  

   //设置该引脚为复用输出功能,输出TIM4的CH4的PWM脉冲波形

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TIM4_CH4

       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       GPIO_Init(GPIOB, &GPIO_InitStructure);

       /****************** 72MHz / 200 / 7200 = 50Hz*******************/

       TIM_TimeBaseStructure.TIM_Period = 200 - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值

       TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1; //设置用来作为TIMx时钟频率除数的预分频值

       TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim

       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

       TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

       

       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2

       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高

    TIM_OCInitStructure.TIM_Pulse = 0;//初始状态占空比为0

       TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

     

       TIM_Cmd(TIM4, ENABLE);  //使能TIM4外设

}

欢迎大家拍砖

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

返回顶部