一、伺服驱动器
型号命名
DS5L1-22P3-PTA
1、信捷伺服控制器的四个按钮:
INC相当于加1、DEC相当于减1
ENTER相当于确认键
屏幕显示的含义
2、脉冲、方向输入输出信号接口
COM接地
P-脉冲数输入
D-方向输入
SI1使能
3、驱动器编码器接口
编码器接口接向伺服电机
4、RS-232通信接口
连接PC进行通信
5、拨码开关
拨码 1 代表脉冲输入电压切换;
拨码 2 代表脉冲方向电压切换。
默认拨码 1 和拨码 2 都置 OFF,对应输入脉冲为集电极 24V;
拨码 1 和拨码 2 都置 ON,对应输入脉冲为差分 5V。
6、整体
二、参数设置
结合屏幕下按钮进行设置:
按钮一(STA/ESC):设置PX或FX或UX;返回;
按钮二(INC):参数数值加1;
按钮三(DEC):参数数值减1;
按钮四(ENTER):切换后两位参数的设置;长按进入内部参数设置;内部参数设置完长按确认;
简单参数内容:
1、对驱动运行的模式进行选择,6和7参数是使用外部PLC或者单片机进行脉冲控制
2、选用驱动器使能的方式为IO口、上位机或总线以及停止驱动器的使能
3、设定电机的顺(逆)时针的旋转方向
4、选择电机接收多少个脉冲转一圈
5、驱动器使能方式
00为驱动器始终关闭、01为从SI1口输入正信号触发驱动器使能(后面参数与其相同)、10为驱动器始终开启、11为从SI1口输入反信号触发驱动器使能(若不输入信号,相当于输入反信号,后面参数与其相同)
三、驱动器与单片机的接线方式
1、驱动器电源的接线方式
2、驱动器电机和编码器接口
编码器未接,屏幕会显示报错
3、光耦放大电路与驱动器接线
驱动器内部也有光耦电路,使PWM脉冲能准确及时的发送
(尽量使用24V电源进行放大,5V也可以,但暂时只能进行PWM的调速控制,方向转换和驱动器使能功能没有实现,24V则可以完全实现)
注意:在使用24V接线时要将驱动器侧面两个拨码拨到上,否则驱动器易烧坏。
4、接线
四、单片机的代码实现
主控使用的STM32F103C8T6
1、主要实现功能
电机速度分为四挡,按键进行控制,按键1短按可将驱动器使能,并将电机从0档无级变速至1档,再次短按可将电机继续升档,在电机运行过程中长按按钮1可将任意档位无级变速至0档,电机停止后驱动器被关闭。当电机档位为0时,短按按钮2可将电机转换旋转方向,直接短按按钮1启动即可。
2、代码实现
电机换向的函数(Motor.c)
//使能电机
void NABLE_Motor(uint8_t numb) //1使能,0失能
{
if(numb)
{
GPIO_SetBits(GPIOA,GPIO_Pin_5);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}
}
//电机方向
void DIR_Motor(uint8_t numb) //1正转,0反转
{
if(numb)
{
GPIO_SetBits(GPIOA,GPIO_Pin_4);
}
if(!numb)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
}
}
按键长按短按和无级变速的处理(main.c)
uint8_t KeyNum = 0; //定义用于接收按键键码的变量
uint8_t Key_LongTIM = 0; //长按的标志位
#define KeyNum0_SetARR 1000 - 1
#define KeyNum1_SetARR 1000 - 1 //75rpm(步进电机驱动设置为800脉冲一转)
#define KeyNum2_SetARR 700 - 1 //107.14rpm
#define KeyNum3_SetARR 400 - 1 //187.5rpm
#define KeyNum4_SetARR 200 - 1 //375rpm
#define KeyNum4_PWM 150 //PWM的占空比
//按键处理
void SET_Key_Num(void)
{
//读按键电平来设置模式
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0)
{
TIM_Cmd(TIM3,ENABLE); //开启长按按钮的定时器
uint16_t Temp_PWM = 0;
uint16_t Temp_ARR = 0;
uint8_t NUM = 0; //缓慢加速的标志位(为了不使用延时函数)
Delay_ms(20); //延时消抖
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) //等待按键松手
{
//按钮被长按
if(Key_LongTIM == 3)
{
if(KeyNum == 1)
{
Temp_ARR = KeyNum1_SetARR;
while(Temp_ARR < 2500)
{
Delay_ms(5);
//改变ARR寄存器的值,来调整脉冲频率,进而调整电机速度
//可根据变速快慢的需要进行无级变速的调整
//(当前为梯形变速,有能力也可用算法进行S曲线变速)
TIM_SetAutoreload(TIM2,Temp_ARR += 2);
OLED_ShowNum(4,2,Temp_ARR,4);
}
}
if(KeyNum == 2)
{
Temp_ARR = KeyNum2_SetARR;
while(Temp_ARR < 2500)
{
Delay_ms(5);
TIM_SetAutoreload(TIM2,Temp_ARR += 2);
OLED_ShowNum(4,2,Temp_ARR,4);
}
}
if(KeyNum == 3)
{
Temp_ARR = KeyNum3_SetARR;
while(Temp_ARR < 2499)
{
Delay_ms(5);
TIM_SetAutoreload(TIM2,Temp_ARR += 2);
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 0;
}
if(KeyNum == 4)
{
Temp_ARR = KeyNum4_SetARR;
while(Temp_ARR < 2499)
{
Delay_ms(2);
TIM_SetAutoreload(TIM2,Temp_ARR++);
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 0;
}
KeyNum = 0;
PWM_SetCompare2(0); //占空比为0
NABLE_Motor(0); //驱动器关闭使能
}
}
Delay_ms(20);
//按钮短按
if(KeyNum == 4 && Key_LongTIM == 0) //短按按钮并且当前档位为4
{
Temp_ARR = KeyNum4_SetARR;
while(Temp_ARR < 2499)
{
Delay_ms(2);
TIM_SetAutoreload(TIM2,Temp_ARR++);
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 0;
PWM_SetCompare2(0); //PWM的占空比,不要直接关闭使能,否则电机会突停
}
else if(KeyNum == 0 && Key_LongTIM == 0) //短按按钮并且当前档位为0
{
NABLE_Motor(1);
PWM_SetCompare2(KeyNum4_PWM); //PWM的占空比
Temp_ARR = 2499;
while(Temp_ARR > KeyNum1_SetARR)
{
TIM_SetAutoreload(TIM2,Temp_ARR--);
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 1;
}
else if(KeyNum == 1 && Key_LongTIM == 0) //短按按钮并且当前档位为1
{
Temp_ARR = KeyNum1_SetARR;
while(Temp_ARR > KeyNum2_SetARR)
{
if(NUM % 2)
{
TIM_SetAutoreload(TIM2,Temp_ARR--);
}
NUM++;
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 2;
NUM = 0;
}
else if(KeyNum == 2 && Key_LongTIM == 0) //短按按钮并且当前档位为2
{
Temp_ARR = KeyNum2_SetARR;
while(Temp_ARR > KeyNum3_SetARR)
{
if(NUM % 2)
{
TIM_SetAutoreload(TIM2,Temp_ARR--);
}
NUM++;
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 3;
NUM = 0;
}
else if(KeyNum == 3 && Key_LongTIM == 0) //短按按钮并且当前档位为3
{
Temp_ARR = KeyNum3_SetARR;
while(Temp_ARR > KeyNum4_SetARR)
{
if(NUM % 2)
{
TIM_SetAutoreload(TIM2,Temp_ARR--);
}
NUM++;
OLED_ShowNum(4,2,Temp_ARR,4);
}
KeyNum = 4;
NUM = 0;
}
}
Key_LongTIM = 0;
}
旋转方向的控制(main.c)
//旋转方向控制
void Set_Dir(void)
{
//读按键电平来设置方向
//当当前档位为0时才能进行更改方向
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0 && KeyNum == 0)
{
Delay_ms(20); //延时消抖
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2) == 0); //等待按键松手
Delay_ms(20); //延时消抖
//如果是正向就改为反向,如果是反向就改为正向
if(GPIO_ReadOutputDataBit(GPIOA ,GPIO_Pin_4))
{
//相当于GPIO_ResetBits(GPIOA,GPIO_Pin_4);
DIR_Motor(0); //反转
}
else
{
//相当于GPIO_SetBits(GPIOA,GPIO_Pin_4);
DIR_Motor(1); //正转
}
}
}
长按按钮的功能实现
//开启定时器
#include "stm32f10x.h" // Device header
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //ARR自动装载
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //PSC预分频
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
}
//在定时中断中进行定时处理
void TIM3_IRQHandler()
{
if(TIM_GetFlagStatus(TIM3,TIM_IT_Update) == SET)
{
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0 && Key_LongTIM < 3)
{
Key_LongTIM++;
OLED_ShowNum(4,16,Key_LongTIM,1);
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
PWM生成(PWM.c)
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 1000 - 1; //ARR自动装载
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC预分频
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(TIM2, Compare);
}
总结:
信捷的伺服驱动在寻找资料的时候大部分是PLC进行编程控制的,而且使用PLC可能会更好更稳定,因为需要才简单设计的嵌入式控制,感觉发射5V的信号没有特别的稳定,也有可能是软件或者硬件某些地方没有做好。使用单片机控制的资料几乎没有,所以我简单实现了所要的需求,有能力的可以相互交流,有什么问题可以随时提出,全是本人实际经历和分享,希望能帮助到需要的人。
(后附代码全文,信捷上位机软件可在官网下载)
通过网盘分享的文件:单片机控制伺服驱动器
链接: https://pan.baidu.com/s/1vYZHYjp8Mi8Dg5GaKWL7Hw?pwd=qwer 提取码: qwer