项目需求,淘到了策海科技的DS300总线舵机(目前停产),但没有示例程序。本文根据该舵机的《内存表》和《通讯协议》编写了驱动程序。
DS300舵机
额定电压:DC12-16V 峰值扭矩:300kg*cm 通信协议:485总线 《内存表》和《通讯协议》:百度网盘链接 提取码:4mo9
驱动程序
实验平台:STM32F407ZGT6
C文件
#include "ds300.h"
#include "string.h"
#include "stdarg.h"
#include "stdio.h"
#include "usart.h"
unsigned char DS300_Instruction_Data[24] = {0};
DS300_Measure DS300_Chassis = {0};
u8 DS300_Instruction_Fun(u8 ID, u8 instruction, u8 length, ...)
{
u8 check_sum = 0;
u8 len = 0;
u8 i = 0;
len = length + 2;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = len;
DS300_Instruction_Data[4] = instruction;
if(length > 0)
{
va_list vap;
va_start(vap, length);
for(i=0; i<length; i++)
{
DS300_Instruction_Data[i+5] = va_arg(vap, int);
}
va_end(vap);
}
len = len + 3;
check_sum = DS300_Check_Sum(len);
DS300_Instruction_Data[len] = check_sum;
return len+1;
}
u8 DS300_Check_Sum(u8 len)
{
u8 i = 0;
u8 check_sum = 0;
for(i=2; i<len; i++)
{
check_sum += DS300_Instruction_Data[i];
}
check_sum = ~check_sum;
return check_sum;
}
u8 DS300_Set_ID(u8 ID_old, u8 ID_new)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID_old;
DS300_Instruction_Data[3] = 0x04;
DS300_Instruction_Data[4] = WRITE_DATA;
DS300_Instruction_Data[5] = ID_t;
DS300_Instruction_Data[6] = ID_new;
check_sum = DS300_Check_Sum(7);
DS300_Instruction_Data[7] = check_sum;
return 8;
}
u8 DS300_Set_BaudRate(u8 ID, u8 baud_rate)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x04;
DS300_Instruction_Data[4] = WRITE_DATA;
DS300_Instruction_Data[5] = BaudRate;
DS300_Instruction_Data[6] = baud_rate;
check_sum = DS300_Check_Sum(7);
DS300_Instruction_Data[7] = check_sum;
return 8;
}
u8 DS300_Ping_Instruction(u8 ID)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x02;
DS300_Instruction_Data[4] = PING;
check_sum = DS300_Check_Sum(5);
DS300_Instruction_Data[5] = check_sum;
return 6;
}
u8 DS300_Read_Feedback_Instruction(u8 ID)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x04;
DS300_Instruction_Data[4] = READ_DATA;
DS300_Instruction_Data[5] = RealAngle;
DS300_Instruction_Data[6] = 0x0F;
check_sum = DS300_Check_Sum(7);
DS300_Instruction_Data[7] = check_sum;
return 8;
}
u8 DS300_Write_Control_Instruction(u8 ID, u16 target_angle, u16 running_time, u16 running_speed)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x09;
DS300_Instruction_Data[4] = WRITE_DATA;
DS300_Instruction_Data[5] = TargetAngle;
DS300_Instruction_Data[6] = (u8)target_angle;
DS300_Instruction_Data[7] = (u8)(target_angle>>8);
DS300_Instruction_Data[8] = (u8)running_time;
DS300_Instruction_Data[9] = (u8)(running_time>>8);
DS300_Instruction_Data[10] = (u8)running_speed;
DS300_Instruction_Data[11] = (u8)(running_speed>>8);
check_sum = DS300_Check_Sum(12);
DS300_Instruction_Data[12] = check_sum;
return 13;
}
u8 DS300_Reg_Write_Control_Instruction(u8 ID, u16 target_angle, u16 running_time, u16 running_speed)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x09;
DS300_Instruction_Data[4] = REG_WRITE_DATA;
DS300_Instruction_Data[5] = TargetAngle;
DS300_Instruction_Data[6] = (u8)target_angle;
DS300_Instruction_Data[7] = (u8)(target_angle>>8);
DS300_Instruction_Data[8] = (u8)running_time;
DS300_Instruction_Data[9] = (u8)(running_time>>8);
DS300_Instruction_Data[10] = (u8)running_speed;
DS300_Instruction_Data[11] = (u8)(running_speed>>8);
check_sum = DS300_Check_Sum(12);
DS300_Instruction_Data[12] = check_sum;
return 13;
}
u8 DS300_Action_Instruction(u8 ID)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x02;
DS300_Instruction_Data[4] = ACTION;
check_sum = DS300_Check_Sum(5);
DS300_Instruction_Data[5] = check_sum;
return 6;
}
u8 DS300_Sync_Write_Control_Instruction(u8 ID1, u8 ID2, u16 target_angle, u16 running_time, u16 running_speed)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = 0xFE;
DS300_Instruction_Data[3] = 0x12;
DS300_Instruction_Data[4] = SYNC_WRITE_DATA;
DS300_Instruction_Data[5] = TargetAngle;
DS300_Instruction_Data[6] = 0x06;
DS300_Instruction_Data[7] = ID1;
DS300_Instruction_Data[8] = (u8)target_angle;
DS300_Instruction_Data[9] = (u8)(target_angle>>8);
DS300_Instruction_Data[10] = (u8)running_time;
DS300_Instruction_Data[11] = (u8)(running_time>>8);
DS300_Instruction_Data[12] = (u8)running_speed;
DS300_Instruction_Data[13] = (u8)(running_speed>>8);
DS300_Instruction_Data[14] = ID2;
DS300_Instruction_Data[15] = (u8)target_angle;
DS300_Instruction_Data[16] = (u8)(target_angle>>8);
DS300_Instruction_Data[17] = (u8)running_time;
DS300_Instruction_Data[18] = (u8)(running_time>>8);
DS300_Instruction_Data[19] = (u8)running_speed;
DS300_Instruction_Data[20] = (u8)(running_speed>>8);
check_sum = DS300_Check_Sum(21);
DS300_Instruction_Data[21] = check_sum;
return 22;
}
u8 DS300_Reset_Instruction(u8 ID)
{
u8 check_sum = 0;
DS300_Instruction_Data[0] = 0xFF;
DS300_Instruction_Data[1] = 0xFF;
DS300_Instruction_Data[2] = ID;
DS300_Instruction_Data[3] = 0x02;
DS300_Instruction_Data[4] = DS300_RESET;
check_sum = DS300_Check_Sum(5);
DS300_Instruction_Data[5] = check_sum;
return 6;
}
void DS300_Read_Feedback_Response(u8 *buf, DS300_Measure *ptr)
{
u8 i = 0;
u8 check_sum = 0;
if(buf[0]==0xFF && buf[1]==0xFF)
{
for(i=2; i<20; i++)
{
check_sum += buf[i];
}
check_sum = ~check_sum;
if(check_sum==buf[20])
{
ptr->id_real = buf[2];
ptr->angle_real = (uint16_t)(buf[5] | buf[6]<<8);
ptr->speed_real = (uint16_t)(buf[7] | buf[8]<<8);
ptr->load_real = (uint16_t)(buf[9] | buf[10]<<8);
ptr->voltage_real = buf[11];
ptr->temp_real = buf[12];
ptr->regwrite_flag = buf[13];
ptr->error_flag = buf[14];
ptr->running_flag = buf[15];
ptr->tarang_real = (uint16_t)(buf[16] | buf[17]<<8);
ptr->current_real = (uint16_t)(buf[18] | buf[19]<<8);
}
}
}
h文件
#ifndef __DS300_H
#define __DS300_H
#include "sys.h"
typedef enum
{
ID_1 = 0x01,
ID_2 = 0x02,
ID_ALL = 0xFE,
}DS300_ID;
typedef enum
{
PING = 0x01,
READ_DATA = 0x02,
WRITE_DATA = 0x03,
REG_WRITE_DATA = 0x04,
ACTION = 0x05,
SYNC_WRITE_DATA = 0x83,
DS300_RESET = 0x06,
}DS300_INSTRUCTION;
typedef enum
{
ID_t = 0x05,
BaudRate = 0x06,
}DS300_WR_SET_DATA;
typedef enum
{
TargetAngle = 0x2A,
RunningTime = 0x2C,
RunningSpeed = 0x2E,
}DS300_WR_CONTROL_DATA;
typedef enum
{
RealAngle = 0x38,
RealSpeed = 0x3A,
RealLoad = 0x3C,
RealVoltage = 0x3E,
RealTemp = 0x3F,
RegWriteFlag = 0x40,
ErrorFlag = 0x41,
RunningFlag = 0x42,
RealTarAng = 0x43,
RealCurrent = 0x45,
}DS300_R_FEEDBACK_DATA;
typedef struct
{
uint8_t id_real;
uint16_t angle_real;
uint16_t speed_real;
uint16_t load_real;
uint8_t voltage_real;
uint8_t temp_real;
uint8_t regwrite_flag;
uint8_t error_flag;
uint8_t running_flag;
uint16_t tarang_real;
int16_t current_real;
}DS300_Measure;
extern unsigned char DS300_Instruction_Data[24];
extern DS300_Measure DS300_Chassis;
u8 DS300_Instruction_Fun(u8 ID, u8 instruction, u8 length, ...);
u8 DS300_Check_Sum(u8 len);
u8 DS300_Set_ID(u8 ID_old, u8 ID_new);
u8 DS300_Set_BaudRate(u8 ID, u8 baud_rate);
u8 DS300_Ping_Instruction(u8 ID);
u8 DS300_Read_Feedback_Instruction(u8 ID);
u8 DS300_Write_Control_Instruction(u8 ID, u16 target_angle, u16 running_time, u16 running_speed);
u8 DS300_Reg_Write_Control_Instruction(u8 ID, u16 target_angle, u16 running_time, u16 running_speed);
u8 DS300_Action_Instruction(u8 ID);
u8 DS300_Sync_Write_Control_Instruction(u8 ID1, u8 ID2, u16 target_angle, u16 running_time, u16 running_speed);
u8 DS300_Reset_Data(u8 ID);
void DS300_Read_Feedback_Response(u8 *buf, DS300_Measure *ptr);
#endif
|