数字舵机 通用驱动(换基于C语言的芯片移植难度小,宏定义适用于各种型号舵机)

     今天在做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

希望能对大家有所帮助!大笑

猜你喜欢

转载自blog.csdn.net/weixin_41094315/article/details/80146032