第3-10讲:SG90舵机驱动
-
- 学习目的
- 了解SG90舵机的相关参数、控制方式。
- 编程用PWM驱动SG90舵机,通过按键改变舵机旋转角度。
- 舵机简介
- 规格参数
- 舵机简介
“舵机”这个名号其实是一个俗称,是那些玩航模、船模的人起的名字,因为这种电机常被用于舵面控制。舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的闭环控制执行模块。
舵机是一个闭环控制系统。控制电路板接收来自信号线的控制信号,控制电机转动,电机带动一系列齿轮组,减速后传动至输出舵盘。舵机的输出轴与位置反馈电位计相连,舵盘转动的同时带动位置反馈电位计,电位计将输出一个电压信号到控制电路板进行反馈,然后控制电路板根据所在位置决定电机转动的方向和速度,从而达到目标停止。
我们学习舵机时,通常以经典款模拟舵机SG90入门,SG90是一种微型舵机,具有便宜、小巧的特点,常用于小型模型、玩具或智能小车等。
SG90舵机规格参数如下图所示。
图1:SG90规格参数
-
-
- 接口信号
-
图2:SG90舵机接口信号
-
-
- 驱动方式
-
SG90舵机通常使用PWM驱动:用单片机的定时器或者PWM外设生成一个周期为20ms的PWM波,按照下图的占空比即可驱动舵机旋转到相应的角度。
图3:SG90舵机旋转角度和脉冲宽度关系
- 注意事项:驱动舵机时,不同的占空比(高电平持续时间)是驱动舵机旋转到对应的角度,而不是旋转对应的角度。如2.5%的占空比(高电平持续时间0.5ms),舵机会旋转到0度,之后,一直保持该占空比输出,舵机是不会继续旋转的。
- 软件设计
- SG90舵机驱动实验
- 软件设计
- 注:本节的实验是在“实验2-15-1:PWM输出波形”的基础上修改,本节对应的实验源码是:“实验3-10-1:SG90舵机驱动(按键改变旋转角度)”。
-
-
- 实验内容
-
-
使用STC8A8K64D4单片机的PWM通道6的P1.6引脚输出频率为50Hz(周期20ms)的波形,通过开发板上的按键修改PWM输出波形的占空比,实现控制SG90旋转。
- 按键KEY1:舵机旋转到45度。
- 按键KEY2:舵机旋转到90度。
- 按键KEY3:舵机旋转到135度。
- 按键KEY4:舵机旋转到180度。
-
-
- 代码编写
-
-
- 配置PWM
本例中,通道6,选择P1.6为通道6的输出引脚,频率:50Hz,占空比2.5%(让舵机初始化旋转到0度),代码清单如下。
代码清单:初始化PWM
- /**********************************************************************************
- 功能描述:初始化PWM模块。
- :使用通道6,选择P1.6为通道6的输出引脚,频率:50Hz,占空比2.5%
- 参 数:无
- 返 回 值:无
- ***********************************************************************************/
- void pwm_config(void)
- {
- PWMSET |= 0x01; //使能PWM模块,必须先使能后面的配置才能生效
- /*---------------------PWMCFG-----------------------------------
- 位7 位6 位5 位4 位3 位2 位1 位0
- -- -- -- -- PWMCBIF EPWMCBI EPWMTA PWMCEN
- x x x x 0 0 0 0
- PWMCBIF:PWM计数器归零中断标志位,需软件清零
- PEPWMCBI=0:使能PWM计数器归零中断
- EPWMTA = 0:PWM与ADC不关联
- PWMCEN = 0:PWM停止计数
- ---------------------------------------------------------------*/
- PWMCFG = 0x00;
- P_SW2 |= 0x80; //将EAXFR位置1,允许访问扩展RAM区特殊功能寄存器(XFR)
- /*---------------------PWMCKS-----------------------------------
- 位7 位6 位5 位4 位3~0
- -- -- -- SELT2 PWM_PS[3:0]
- 1 0 x 0 1011
- SELT2=0:PWM 时钟源为系统时钟经分频器分频之后的时钟
- PWM_PS[3:0]=1111:系统时钟的1/16,(24/16)MHz = 1.5MHz
- ---------------------------------------------------------------*/
- PWMCKS = 0x0F;
- /*---------------------PWM6CR-----------------------------------
- 位7 位6 位5 位4~3 位2 位1 位0
- ENO INI -- C0_S[1:0] ENI ENT2I ENT1I
- 1 1 x 00 0 0 0
- ENO = 1:PWM的通道6相应PWM端口为 PWM 输出口
- INI = 0:PWM的通道6初始电平为低电平
- C0_S[1:0] =01:选择P1.6为PWM通道6输出脚
- ENI = 0:使能PWM通道6的PWM中断
- ENT2I = 0:关闭PWM的通道6在第2个触发点中断
- ENT1I = 0:关闭PWM的通道6在第1个触发点中断
- ---------------------------------------------------------------*/
- PWM6CR = 0x88;
- PWMC = 29999; //设置 PWM 周期为 20ms
- PWM6T1 = 0; //第1触发点设置为0
- PWM6T2 = SG90_90D_PWM_VAL; //设置第2触发点,让舵机旋转到0度
- P_SW2 &= 0x7F; //将EAXFR位置0,禁止访问XFR
- PWMCFG |= 0x01; //将PWMCEN位置1,使能PWM波形发生器,PWM计数器开始计数
- }
- 修改PWM占空比
为了方便控制舵机旋转角度,我们编写一个根据角度修改PWM占空比的函数以便于应用程序调用。首先,定义出舵机旋转角度对应的PWM第2触发点的值,如下所示。
代码清单:定义舵机旋转角度对应的PWM第2触发点的值
- #define SG90_0D_PWM_VAL 29250 //旋转到0度时PWM第2触发点的值
- #define SG90_45D_PWM_VAL 28500 //旋转到45度时PWM第2触发点的值
- #define SG90_90D_PWM_VAL 27750 //旋转到90度时PWM第2触发点的值
- #define SG90_135D_PWM_VAL 27000 //旋转到135度时PWM第2触发点的值
- #define SG90_180D_PWM_VAL 26250 //旋转到180度时PWM第2触发点的值
驱动舵机旋转到某个角度,也就是将PWM占空比修改为角度对应的值,即修改PWM第2触发点的值,代码清单如下。
代码清单:驱动舵机旋转到指定的角度
- /**********************************************************************************
- 功能描述:驱动舵机旋转到指定的角度。
- 参 数:angle[in]:角度的编号
- 返 回 值:无
- ***********************************************************************************/
- void set_angle(u8 angle)
- {
- P_SW2 |= 0x80; //将EAXFR位置1,允许访问扩展RAM区特殊功能寄存器(XFR)
- switch (angle)
- {
- case SG90_0_DEGREE:
- PWM6T2=SG90_0D_PWM_VAL; //第2触发点设置为29250,对应占空比为2.5%,即高电平持续时间0.5ms
- break;
- case SG90_45_DEGREE:
- PWM6T2=SG90_45D_PWM_VAL; //第2触发点设置为28500,对应占空比为2.5%,即高电平持续时间0.5ms
- break;
- case SG90_90_DEGREE:
- PWM6T2=SG90_90D_PWM_VAL; //第2触发点设置为27750,对应占空比为2.5%,即高电平持续时间0.5ms
- break;
- case SG90_135_DEGREE:
- PWM6T2=SG90_135D_PWM_VAL;//第2触发点设置为27000,对应占空比为2.5%,即高电平持续时间0.5ms
- break;
- case SG90_180_DEGREE:
- PWM6T2=SG90_180D_PWM_VAL;//第2触发点设置为26250,对应占空比为2.5%,即高电平持续时间0.5ms
- break;
- }
- P_SW2 &= 0x7F; //将EAXFR位置0,禁止访问XFR
- }
- 主函数
主函数中完成相关的初始化,之后,在主循环中扫描按键状态,根据扫描到的键值驱动舵机旋转到对应的角度,代码清单如下。
代码清单:主函数
- /**********************************************************************************
- 功能描述:主函数
- 参 数:无
- 返 回 值:int类型
- ***********************************************************************************/
- int main(void)
- {
- u8 button_num;
- P2M1 &= 0xBF; P2M0 &= 0xBF; //设置P2.6为准双向口(指示灯D1)
- P1M1 &= 0xBF; P1M0 |= 0x40; //设置P1.6为推挽
- P3M1 &= 0x3F; P3M0 &= 0x3F; //设置P3.6~P3.7为准双向口(按键KEY2和KEY1)
- P0M1 &= 0x5F; P0M0 &= 0x5F; //设置P0.5,P0.7为准双向口(按键KEY4和KEY3)
- pwm_config(); //初始化PWM
- while(1)
- {
- button_num = buttons_scan(0); //获取开发板用户按键检测值,不支持连按
- if(button_num == BUTTON1_PRESSED) //按键KEY1按下
- {
- set_angle(SG90_45_DEGREE); //舵机旋转到45度
- }
- else if(button_num == BUTTON2_PRESSED) //按键KEY2按下
- {
- set_angle(SG90_90_DEGREE); //舵机旋转到90度
- }
- else if(button_num == BUTTON3_PRESSED) //按键KEY3按下
- {
- set_angle(SG90_135_DEGREE); //舵机旋转到135度
- }
- else if(button_num == BUTTON4_PRESSED) //按键KEY4按下
- {
- set_angle(SG90_180_DEGREE); //舵机旋转到180度
- }
- delay_ms(100);
- }
- }
-
-
- 硬件连接
-
-
如下图所示,将SG90舵机安装到开发板上。
图4:硬件连接
-
-
-
- 实验步骤
-
-
- 解压“…\第3部分:配套例程源码”目录下的压缩文件“实验3-10-1:SG90舵机驱动(按键改变旋转角度)”,将解压后得到的文件夹拷贝到合适的目录,如“D\STC8”(这样做的目的是为了防止中文路径或者工程存放的路径过深导致打开工程出现问题)。
- 双击“…\sg90_pwm\project”目录下的工程文件“sg90_pwm.uvproj”。
- 点击编译按钮编译工程,编译成功后生成的HEX文件“sg90_pwm.hex”位于工程的“…\sg90_pwm\Project\Object”目录下。
- 打开STC-ISP软件下载程序,下载使用内部IRC时钟,IRC频率选择:24MHz。
- 程序运行后,分别按下KEY1~ KEY4,可以观察到:
- 按下按键KEY1:舵机旋转到45度。
- 按下按键KEY2:舵机旋转到90度。
- 按下按键KEY3:舵机旋转到135度。
- 按下按键KEY4:舵机旋转到180度。