完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
前言
拓达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数字输入。 (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 } 我们的编码器是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获取姿态的中断来说可以满足需求。 |
|
|
|
只有小组成员才能发言,加入小组>>
2397 浏览 0 评论
8956 浏览 4 评论
36569 浏览 19 评论
4995 浏览 0 评论
24414 浏览 34 评论
1404浏览 2评论
1657浏览 1评论
2066浏览 1评论
1467浏览 0评论
424浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 15:58 , Processed in 1.245954 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号