找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13879|回复: 10
打印 上一主题 下一主题
收起左侧

STM32产生PWM驱动舵机详解

  [复制链接]
跳转到指定楼层
楼主
Stm32驱动舵机
一、舵机分类:数字舵机和模拟舵机
   
数字舵机
一般价格贵的舵机基本都是数字舵机,反之就是模拟舵机了。他们之间的区别就是,数字的舵机你输出脉冲后,会很清脆的到达固定的角度,不会产生异响,脉冲固定舵机不会产生吱吱的响。模拟舵机你输出的脉冲固定以后吱吱的响,在不动和动的边缘游荡。
需要驱动他们就必须输出固定的脉冲。这篇博主写的不错。(http://blog.sina.com.cn/s/blog_8240cbef01018hu1.html)总结一下,就是需要产生20ms(50Hz)基准,占空比可调的PWM波。
  
角度
  
0
45
90
135
180
占空比
0.5
1.0
1.5
2.0
2.5

根据这个表格,我们得出一个公式:一度的占空比 = 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)
{
       floattemp;
       temp =(1.0 / 9.0) * angle + 5.0;//寄存器值 = 1/9 * 角度 + 5
       TIM_SetCompare4(TIM4,(uint16_t)temp);//将角度值写入比较寄存器
}
定时器初始化代码:
void Timer4_Init(void)
{      
       GPIO_InitTypeDefGPIO_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外设  
}

IMG_20190314_092218.jpg (5.22 MB, 下载次数: 111)

电位器驱动舵机

电位器驱动舵机

舵机代码.7z

201.72 KB, 下载次数: 314, 下载积分: 黑币 -5

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:313060 发表于 2019-6-28 10:40 | 只看该作者
舵机STM32
回复

使用道具 举报

板凳
ID:282095 发表于 2019-6-28 12:09 | 只看该作者
之前用TTL电平控制过电机
回复

使用道具 举报

地板
ID:338557 发表于 2019-6-28 17:24 | 只看该作者
oh my god,没学会
回复

使用道具 举报

5#
ID:583420 发表于 2019-7-13 13:45 | 只看该作者
学习一下
回复

使用道具 举报

6#
ID:497290 发表于 2019-8-4 17:08 | 只看该作者
谢谢分享哦 ~~~
回复

使用道具 举报

7#
ID:384691 发表于 2019-8-6 20:45 | 只看该作者
谢谢楼主
回复

使用道具 举报

8#
ID:676568 发表于 2019-12-31 16:24 | 只看该作者
挺有用的,谢谢楼主
回复

使用道具 举报

9#
ID:116773 发表于 2020-1-1 20:29 | 只看该作者
已经下载学习,谢谢楼主分享!
回复

使用道具 举报

10#
ID:320525 发表于 2020-1-3 21:27 | 只看该作者
由此可以类推到呼吸灯叭 学习一下
回复

使用道具 举报

11#
ID:658039 发表于 2020-1-4 08:21 | 只看该作者
之前用过舵机,是用PWM控制的,但精度不够。希望学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

快速回复 返回顶部 返回列表