拓达TSDA-C21B,通过单片机串口发命令控制电机转向


前言

拓达TSDA-C21B伺服是我的研究生课题平衡车的项目,用来做电机转向控制用的驱动器,网上没有单片机控制的驱动程序可参考,咨询卖家也没有相关的程序提供,所以只有自己看官方的用户手册自己写控制转向的驱动程序。本文介绍拓达伺服TSDA-C21B使用单片机来控制电机转向角方案,以官方的手册为参考,从硬件的接线到软件的设计进行讲解。


下面以STM32F4单片机为例,来介绍控制电机转向的方案。
你需要的材料有:24-80V直流电源、TSDA-C21B和配套的电机和配件、串口母头、STM32F4单片机模块、STM32F4数据手册、TSDA-C21B 伺服用户手册

驱动器的参数配置

关于驱动器参数的调试软件这里不多做介绍,官方的手册和客服都能帮忙处理。若通讯故障则为硬件接线问题。
这里 我们选的模式选择的参数后文中有解释。1、2参数是电机加减速的时间,3是比例增益增大它能使电机反应更灵敏。图中的参数值可供参考。配置好之后电机下载设置写入驱动器即可

在这里插入图片描述

一、硬件准备

1、驱动器的硬件的接线硬件的接线
此处参考官方手册的接线。注意:此处PB、RB可暂时不接在这里插入图片描述
实物接线图 (控制接口可暂时不接,后面需要测速时可接到单片机用于测电机的转速)
在这里插入图片描述
2、网口线插入标有RS232的端口,另一端再接一个串口母头,引出的杜邦线接STM32的串口(注意RXT接单片机串口的TXD,TXD接单片机的RXD)
在这里插入图片描述

二、软件的设计

1.看官方的数据手册确定写软件的方案

(1)、控制模式、与控制来源的选择的选择

我们要设计的是控制电机转向。看官方数据手册的控制方式,有位置控制模式、速度控制模式、力矩控制模式。这里我们选择位置控制模式,由5.2知必须选择PC数字输入。所以在上文驱动器参数的配置里选择 位置调试模式-PC数字输入
图1
图2

(2)、通过官方手册上的说明来搞懂使用RS232发命令的方法和步骤

看下图(1)知道控制器接收数据命令的格式为 地址(A1) + 数据高八位(A2) + 数据低八位(A3) + 数据校验和(A1+A2+A3的低八位值)
看下图(4)并结合下下图中黄线标注的地方知道我们发送的是一个长度为32位的数据,发送时需要分解为高16位和低16位发送。发送高16位的数据地址(A1)为0x50,发送低16位的数据地址(A1)为0x05。校验和取(A1+A2+A3)前8位。其中16位数据也要分高8位和低八位进行发送(由下图1(1)知先发送高八位再发送低八位)。
在这里插入图片描述
在这里插入图片描述
我们通过上述对数据手册的分析来验证一下官方给的RS232通讯发命令的方法:

1、给定-10000转化为16进制为 0xFFFF FFFF FFFF D8F0,取32位数据即后32位 FFFF D8F0,高16位为FFFF,低16位为D8F0。其中高16位的高8位为FF,低8位为FF;低16位的高8位为D8,低8位为F0。
高16位校验和的计算方法为(0x50+0xFF+0xFF)&0xFF计算得0x4E,低16位校验和的计算方法为(0x05+0xD8+0xF0)&0xFF计算得0xCD。

2、按照上图1(1)知发送数据命令的格式为地址(A1) + 数据高八位(A2) + 数据低八位(A3) + 数据校验和 所以先在地址0x50发数据高16位,且要分高八位、低八位发送,最后发送校验和。在地址0x05发数据低16位,且要分高八位、低八位发送,最后发送校验和。

3、由上图1(1)知每帧数据指令之间要有5ms以上的等待,所以上面发送高16位和低16数据时需要有延时。

4、由上述的分析可得出 RS232发送的命令为:
0x50 0xFF 0xFF 0x4E 延时10ms 0x05 0xD8 0xF0 0xCD
为了安全在发送两帧数据之间延时10ms。与下图中官方给定的发送命令一致。
在这里插入图片描述

(3)、自己动手写串口发送数据的函数

1、发送数据函数的结构分析
根据上面所总结的发送数据的方法,我们知道发送数据一次发送32位,需要分不同地址发送它的高16位和低16位,并且高16位和低16位也是按高8位和低8位发送的。所以可以先写发16位数据命令的函数(其中要嵌套发送A1、A2、A3、校验和后8位),然后再在发32位数据函数中嵌套调用发16位数据命令的函数。
2、发送16位数据命令函数的写法分析
根据上面的总结,我们可以将发送命令函数的参数定为 地址和8位数据,类似这种伪代码

void SendCmd(u8 addr, u16 val)
{
	发送 addr(A1);
	发送val的高8位(A2);
	发送val的低8位(A3);
	发送校验和的后8位((A1+A2+A3)&0xFF);
}

3、发送32位数据函数写法分析
根据上面的总结与分析,发送数据函数的参数定为一个32位的数据值,伪代码类似于这种

void SendData(u32 data)
{
	调用SendCmd函数在0x50处发送data的高16位;
	delay_10ms();	
	调用SendCmd函数在0x05处发送data的低16位;
}

2、具体总的代码具体实现如下

// 通过串口4给驱动器发送16位数据命令函数
void SendCmd(u8 addr,u16 val)						// 函数参数为 数据地址和 16位值
{
	u8 gao,di,chk;									// 定义8位数据gao、di、chk用于存储16位数据的高8位、低8位、和校验和的低8位
	gao=(val>>8)&0xff;							    // 得到实参val的高8位
	di=val&0xff;									// 得到实参val的低8位
	chk=(addr+gao+di)&0xff;					        // 得到校验和的低8位
	while((UART4->SR&0X40)==0); 			        //  等待数据发送完成,完成时跳出while,执行下一条语句
	UART4->DR =addr; 								// 向串口发送数据地址(A1)
	while((UART4->SR&0X40)==0); 				    //  等待数据发送完成,完成时跳出while,执行下一条语句
	UART4->DR =gao;  								// 向串口发送数据的高8位
	while((UART4->SR&0X40)==0); 					// 等待数据发送完成,完成时跳出while,执行下一条语句
	UART4->DR =di;  								// 向串口发送数据的低8位
	while((UART4->SR&0X40)==0); 					// 等待数据发送完成,完成时跳出while,执行下一条语句
	UART4->DR =chk;  								// 向串口发送校验和低8位
}

// 通过串口4给驱动器发送32位数据函数
void SendData(u32 data)
{
	u16 gao,di;						// 定义16位数据gao和di,用于存储函数参数的高16位和低16位
	if(data<0){						// 如果要发送的数据data是小于0的值,则需要将data变为补码的形式(因为负数在内存中是以补码的形式存储的)
		data=data*(-1);				// 负数的补码的计算方法为:其相应正数的反码加1。此行是求它相应的正数
		data=~data+1;				// 此行是取反加1, 得到计算机中 “真正意义的” 负数
	}
	gao=(data>>16)&0xffff;			// 得到实参data的高16位
	di=data&0xffff;					// 得到实参data的低16位
	SendCmd(0x50,gao);				// 调用SendCmd函数将高16位值从相应的地址(0x50)处发送 
	delay_ms(15);					// 每帧数据指令要延时5ms以上,避免出错
	SendCmd(0x05,di);				// 调用SendCmd函数将低16位值从相应的地址(0x05)处发送 
}

基础知识补充:
(1)、>> 操作符即将数据的2进制右移,每移动一位左边最高位都补0,(val>>8)&0xff,此句命令即将val的高位移到低8位,&0xff即得到低8位(0xxxxxx&0xff = 0xxx)。

(2)、正数在内存中以源码的形式存储的,负数则以补码的形式存储的,要将负数写入UART->DR,则要写入其补码。

(3)、如果你不懂上述串口的操作,你可以打开STM32F4的数据手册。
1.搜索USART_SR到如下图所示的页面
在这里插入图片描述
看红框框柱的地方为USART的第6位为TC寄存器(可读可清零,可以通过写‘0’来清零)。该位默认值为1,看下面的红线部分知道,为0表示传送未完成 ,1表示传送已完成。读取USART_SR,然后写入USART_DR会将此位软件清零。
所以在传输数据前需要等待上次的传输完成,利用while内的 UART4->SR&0X40==0 用于判断UART寄存器的第6位TC是否等于0,即判断上次数据是否已发送完成。如果完成则执行下一行语句,如果未完成则一直执行空语句等待。

2.搜索USART_DR到如下图所示页面
在这里插入图片描述
可以看到USART的DR寄存器的描述,为8位,能读能写。
所以我们能像 UART4->DR =gao; 这样对它进行写操作。

3、main函数调用SendData()函数实现角度转向

这里我们在电机上接了一个64:1的减速器。

............
int main(void)
{
				SendData(20000);		// 以启动时刻为机械零点,电机往正方向转4圈,减速器64:1,即向正方向转22.5°,到+22.5°位置
				delay_ms(2000);			// 延时2000ms
				SendData(-20000);		// 以启动时刻为机械零点,电机往反方向转8圈,即转45°,到相对机械零点-22.5°位置
				delay_ms(2000);			// 延时2000ms
}

代码解读:看数据手册的下面2图知:2500线编码器 ==》 10000脉冲 ==》 转1圈。
我们的编码器是1250线的,所以 5000脉冲,转1圈。 发送 200000脉冲即转4圈。用了64:1的减速器乘以减速比1/64再乘1/360即可求出转向角为22.5°。由于是位置模式的绝对位置,所以发送-20000时转到 -22.5°的位置。
在这里插入图片描述

在这里插入图片描述

三、总结

以上便是用STM32控制TSDA-C21B驱动器控制位置转向过程,这个方案我们用过。优点是使用串口操作相对比较简单,缺点是每发一帧命令都需要延时10ms,而单片机执行指令是微秒级的,而且驱动器还需要对发送的数据进行响应需要一定的时间,所以在每次给驱动器发数据时都需要延时等待几十毫秒的时间,在某些实时性比较高的场合,比如平衡车需要实时读取IMU数据并实时控制车辆转向时,这个延迟相对于IMU的中断间隔就很大了,导致不能实时的控制车辆的转向。该方案存在缺陷。

四、后记

咨询过拓达的工程师后得知CAN控制和RS485速度会快一些,进一步咨询之后知道CAN线的响应为5ms以内,而且看数据手册知道每帧数据之间不需要像数据串口那样延时5ms以上。所以每次发CAN命令之间只需要 间隔5ms 就可以了。这相对于IMU获取姿态的中断来说可以满足需求。
下篇博主将更新CAN控制伺服驱动器进行转向的博文。

2020/5/7
已更新:拓达TSDA-C21B, 通过单片机CAN通信发送命令控制电机转向.

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值