今天在做SG90舵机的驱动软件,本着开发效率的原则,先上网查一波资料。然后发现这玩意太简单,大佬们都不削于写。然后?我就自己写了一个比较系统且实用性强,移植简单的多级驱动程序。贴出来和大家分享!希望对大家有帮助!
废话不多说我是小杜,我给大家贴代码!
( 注:这里是基于STM32F10系列芯片 GS90舵机的,如需修改成其他芯片或其他型号舵机的,只需要修改 末尾有
“ /*改*/ ”注释的语句即可,其他部分均为逻辑部分。)
.C文件
#include "delay.h" /*改*/
#include "stm32f10x.h" /*改*/
#include "steeringgear.h"
#include "time1ch34pwm.h"
#define PrimaryAngle 0.011111111111 /*改*/ // 脉宽0.5ms-2.5ms对应的角度-90到+90度,则每一度增加脉宽(2.5-0.5)ms / 180 = PrimaryAngle
#define MaxAngle 90.0 /*改*/ // SG90型号舵机 运动范围-90到+90度
#define MinAngle -90.0
#define MinPulseWidth 0.5 /*改*/ // SG90型号舵机 最小 高电平脉宽为0.5毫秒
#define MaxPulseWidth 2.5 /*改*/ // SG90型号舵机 最大 高电平脉宽为2.5毫秒
#define SteeringGear_ControlPeriod 20.0 /*改*/ // SG90型号舵机 PWM控制信号周期20ms
float ZeroPulseWidth =(MaxPulseWidth+MinPulseWidth)/2.0; // SG90型号舵机 0度 高电平脉宽为1.5毫秒
float SteeringGear1_Angle_Distance; // 舵机1初始化到下一次初始化之前 所转过的相对于0度的路程
float SteeringGear2_Angle_Distance; // 舵机2初始化到下一次初始化之前 所转过的相对于0度的路程
// G90舵机特性
/*
SG90一共三根线,红线接 3.3v~5v 电源,棕线GND。黄线为数据控制线,该线接到GPIO上
SG90 脉冲周期为20毫秒(millisecond) 不是20微秒(Microsecond),两者差1000倍呢!
也就是说最多1秒钟内可以转动50次,但是考虑到每次转动还要耗时,所以实际达不到50次。
PWM控制信号周期20ms,脉宽0.5ms-2.5ms对应的角度-90到+90度,范围180度(3度左右偏差),
当脉宽1.5ms时舵机在中立点(0度),我们直接用Python的GPIO提供的PWM控制。
脉宽0.5ms-2.5ms 对应的占空比为2.5% - 12.5% (脉宽/周期=0.5/20-2.5/20). 理论上,10%的空间可以提供180度的线性分割。
*/
/*********************************************************************************
函数名称:SteeringGear_Int
函数功能:初始化两个舵机的PWM输出 是tim1的 通道3 和 通道4
并对舵机进行初始化校准。
-> Motor1 PE13
-> Motor2 PE14
入口参数:无
返回值:无
作者:DU98
*********************************************************************************/
void SteeringGear_Int(void)
{
TIM1_PWM3_4_Init_control(SteeringGear_ControlPeriod,0.1); // SG90型号舵机 脉冲周期为SteeringGear_ControlPeriod ms
SteeringGear1_Angle_Distance =0; // 舵机1转过的相对于0度的路程
SteeringGear2_Angle_Distance =0; // 舵机2转过的相对于0度的路程
SteeringGear1_AbsoluteAngle(0); // Motor1 舵机校准 0度
SteeringGear2_AbsoluteAngle(0); // Motor2 舵机校准 0度
}
/*********************************************************************************
函数名称:SteeringGear1_AbsoluteAngle
函数功能:控制 舵机1 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
入口参数:angle 舵机绝对旋转角
返回值:无
作者:DU98
*********************************************************************************/
// -> Motor1 PE13
void SteeringGear1_AbsoluteAngle(float angle)
{
float HightTime; // 高电平持续时间
float DutyRatio; // 脉冲占空比
if(angle<=MaxAngle && angle>=MinAngle) // SG90型号舵机 运动范围-90到+90度
{
SteeringGear1_Angle_Distance=angle;
if(angle==0) HightTime=ZeroPulseWidth; // SG90型号舵机 0度 高电平脉宽为1.5毫秒
else if(angle>0) HightTime=ZeroPulseWidth+angle*PrimaryAngle;
else
{
angle=angle-MinAngle;
HightTime=MinPulseWidth+angle*PrimaryAngle;
}
DutyRatio=HightTime/SteeringGear_ControlPeriod; // SG90型号舵机 PWM控制信号周期20ms
TIM1_PWM3_DutyRatio(DutyRatio); /*改*/ // TIM1_CH3输出PWM
}
}
/*********************************************************************************
函数名称:SteeringGear2_AbsoluteAngle
函数功能:控制 舵机2 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
入口参数:angle 舵机绝对旋转角
返回值:无
作者:DU98
*********************************************************************************/
// -> Motor2 PE14
void SteeringGear2_AbsoluteAngle(float angle)
{
float HightTime; // 高电平持续时间
float DutyRatio; // 脉冲占空比
if(angle<=MaxAngle && angle>=MinAngle) // SG90型号舵机 运动范围-90到+90度
{
SteeringGear2_Angle_Distance=angle;
if(angle==0) HightTime=ZeroPulseWidth; // SG90型号舵机 0度 高电平脉宽为1.5毫秒
else if(angle>0) HightTime=ZeroPulseWidth+angle*PrimaryAngle;
else
{
angle=angle-MinAngle;
HightTime=MinPulseWidth+angle*PrimaryAngle;
}
DutyRatio=HightTime/SteeringGear_ControlPeriod; // SG90型号舵机 PWM控制信号周期20ms
TIM1_PWM4_DutyRatio(DutyRatio); /*改*/ // TIM1_CH4输出PWM
}
}
/*********************************************************************************
函数名称:SteeringGear1_RelativeAngle
函数功能:控制 舵机1 的相对旋转角度(相对当前的角度SteeringGear1_Angle_Distance的)
入口参数:angle 舵机相对旋转角
返回值:无
作者:DU98
*********************************************************************************/
void SteeringGear1_RelativeAngle(float angle)
{
if( angle<=MaxAngle-SteeringGear1_Angle_Distance && angle>=MinAngle-SteeringGear1_Angle_Distance ) // SG90型号舵机 运动范围-90-路程 到 +90度-路程
{
if(angle==0) SteeringGear1_Angle_Distance=SteeringGear1_Angle_Distance; //相对位移 0度 舵机不动
else SteeringGear1_Angle_Distance+=angle;
SteeringGear1_AbsoluteAngle(SteeringGear1_Angle_Distance);
}
}
/*********************************************************************************
函数名称:SteeringGear2_RelativeAngle
函数功能:控制 舵机2 的相对旋转角度(相对当前的角度SteeringGear2_Angle_Distance的)
入口参数:angle 舵机相对旋转角
返回值:无
作者:DU98
*********************************************************************************/
void SteeringGear2_RelativeAngle(float angle)
{
if( angle<=MaxAngle-SteeringGear2_Angle_Distance && angle>=MinAngle-SteeringGear2_Angle_Distance ) // SG90型号舵机 运动范围-90-路程 到 +90度-路程
{
if(angle==0) SteeringGear2_Angle_Distance=SteeringGear2_Angle_Distance; //相对位移 0度 舵机不动
else SteeringGear2_Angle_Distance+=angle;
SteeringGear2_AbsoluteAngle(SteeringGear2_Angle_Distance);
}
}
.h文件
#ifndef __STEERINGGEAR_H
#define __STEERINGGEAR_H
#include "sys.h"
void SteeringGear_Int(void); // 初始化两个舵机的PWM输出 是tim1的 通道3 和 通道4 ,并对舵机进行初始化校准。
void SteeringGear1_AbsoluteAngle(float angle); // 控制 舵机1 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
void SteeringGear2_AbsoluteAngle(float angle); // 控制 舵机2 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
void SteeringGear1_RelativeAngle(float angle); // 控制 舵机1 的相对旋转角度(相对当前的角度SteeringGear1_Angle_Distance的)
void SteeringGear2_RelativeAngle(float angle); // 控制 舵机2 的相对旋转角度(相对当前的角度SteeringGear2_Angle_Distance的)
#endif
好了,以上就是所有代码啦!
如果有需要STM32F10X与上面程序配套的PWM输出程序的童鞋,请移步到小杜的另一篇博客
https://blog.csdn.net/weixin_41094315/article/details/80145657
如果有想要整个完整文工程的的同学请移步到:
https://download.csdn.net/download/weixin_41094315/10383336
以上就是这些啦!如果觉得好的话,别忘点个赞。老铁!关注一波哈!
/****************************华丽分割线******************************************/
更新一波
->上面是双舵机驱动,要改单舵机驱动也简单,下面贴出单电机驱动。
-> 文中又说方便移植。现在就贴出一个将本模块移植到KEA128系列芯片的驱动舵 机代码实例。
(注意:实例是基于讯飞科技的KEA128库函数实现的舵机操控,编辑软件是 IAR , 其实和MDK5差别不大,只 是配工程的流程不同)
实例代码:
/*****************<main文件>********************/
#include "headfile.h" // 注意再次头文件里 已声明本模块 头文件#include"steeringgear.h"
void main(void)
{
SteeringGear_Int();
SteeringGear1_AbsoluteAngle(0);
delay(500);
delay(500);
while(1)
{
FTM_PWM_Duty(CFTM2,FTM_CH0,3);
delay(500);
delay(500);
delay(500);
delay(500);
FTM_PWM_Duty(CFTM2,FTM_CH0,12);
delay(500);
delay(500);
delay(500);
delay(500);
}
}
/*****************<.c文件>********************/
#include "steeringgear.h"
#define PrimaryAngle 0.011111111111 /*改*/ // 脉宽0.5ms-2.5ms对应的角度-90到+90度,则每一度增加脉宽(2.5-0.5)ms / 180 = PrimaryAngle
#define MaxAngle 90.0 /*改*/ // SG90型号舵机 运动范围-90到+90度
#define MinAngle -90.0
#define MinPulseWidth 0.5 /*改*/ // SG90型号舵机 最小 高电平脉宽为0.5毫秒
#define MaxPulseWidth 2.5 /*改*/ // SG90型号舵机 最大 高电平脉宽为2.5毫秒
#define SteeringGear_ControlPeriod 20.0 /*改*/ // SG90型号舵机 PWM控制信号周期20ms
float ZeroPulseWidth =(MaxPulseWidth+MinPulseWidth)/2.0; // SG90型号舵机 0度 高电平脉宽为1.5毫秒
float SteeringGear1_Angle_Distance; // 舵机1初始化到下一次初始化之前 所转过的相对于0度的路程
/*********************************************************************************
函数名称:SteeringGear_Int
函数功能:初始化两个舵机的PWM输出 是tim1的 通道3 和 通道4
并对舵机进行初始化校准。
-> Motor1 CH0 PTF0
入口参数:无
返回值:无
作者:DU98
*********************************************************************************/
void SteeringGear_Int(void)
{
// TIM1_PWM3_4_Init_control(20.0,0.1); // SG90型号舵机 脉冲周期为20ms
//PWM输出初始化 设置FTM通道为2 选择0 1 2 3口 0 1一对 2 3一对可以实现电机的正反转输出
//设置PWM精度为10000 初始输出PWM为0
//PWM精度设置在ftm.h中FTM_PRECISON这个变量
FTM_PWM_init(CFTM2, FTM_CH0, 1000/SteeringGear_ControlPeriod , 0); /*改*/ //CH0 PTF0 电机驱动 时钟频率5HZ/S
SteeringGear1_Angle_Distance =0; // 舵机1转过的相对于0度的路程
SteeringGear1_AbsoluteAngle(0); // Motor1 舵机校准 0度
}
/*********************************************************************************
函数名称:SteeringGear1_AbsoluteAngle
函数功能:控制 舵机1 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
入口参数:angle 舵机绝对旋转角
返回值:无
作者:DU98
*********************************************************************************/
// -> Motor1 PE13
void SteeringGear1_AbsoluteAngle(float angle)
{
float HightTime; // 高电平持续时间
uint32_t DutyRatio; // 脉冲占空比
if(angle<=MaxAngle && angle>=MinAngle) // SG90型号舵机 运动范围-90到+90度
{
SteeringGear1_Angle_Distance=angle;
if(angle==0) HightTime=ZeroPulseWidth; // SG90型号舵机 0度 高电平脉宽为1.5毫秒
else if(angle>0) HightTime=ZeroPulseWidth+angle*PrimaryAngle;
else
{
angle=angle-MinAngle;
HightTime=MinPulseWidth+angle*PrimaryAngle;
}
DutyRatio=(HightTime/SteeringGear_ControlPeriod+0.005)*100; // SG90型号舵机 PWM控制信号周期20ms
// TIM1_PWM3_DutyRatio(DutyRatio); /*改*/ // TIM1_CH3输出PWM
OLED_PrintValueI(20,2,DutyRatio); //在列20行2显示浮点数,3表示显示3个数字
FTM_PWM_Duty(CFTM2,FTM_CH0,17); /*改*/
}
}
/*********************************************************************************
函数名称:SteeringGear1_RelativeAngle
函数功能:控制 舵机1 的相对旋转角度(相对当前的角度SteeringGear1_Angle_Distance的)
入口参数:angle 舵机相对旋转角
返回值:无
作者:DU98
*********************************************************************************/
void SteeringGear1_RelativeAngle(float angle)
{
if( angle<=MaxAngle-SteeringGear1_Angle_Distance && angle>=MinAngle-SteeringGear1_Angle_Distance ) // SG90型号舵机 运动范围-90-路程 到 +90度-路程
{
if(angle==0) SteeringGear1_Angle_Distance=SteeringGear1_Angle_Distance; //相对位移 0度 舵机不动
else SteeringGear1_Angle_Distance+=angle;
SteeringGear1_AbsoluteAngle(SteeringGear1_Angle_Distance);
}
}
/*****************<.h文件>********************/
#ifndef __STEERINGGEAR_H
#define __STEERINGGEAR_H
#include "headfile.h" /*改*/
void SteeringGear_Int(void); // 初始化两个舵机的PWM输出 是tim1的 通道3 和 通道4 ,并对舵机进行初始化校准。
void SteeringGear1_AbsoluteAngle(float angle); // 控制 舵机1 的绝对旋转角度(相对于舵机0度ZeroPulseWidth的)
void SteeringGear1_RelativeAngle(float angle); // 控制 舵机1 的相对旋转角度(相对当前的角度SteeringGear1_Angle_Distance的)
#endif
希望能对大家有所帮助!