Ctrl-Step驱动的使用可以通过CAN或者串口发送指令即可控制电机。其源码interface_can.cpp包含一些相应的操作。
操作大概分三部分,控制设定操作的命令、带有内存操作的命令以及一些一些查询命令。第一篇文章中讲了第一部分是命令,接下来,让我们继续来看interface_can.cpp里剩下的代码内容吧。
第二部分
第二部分代码处理一些控制设定操作的命令,并将其存储到EEPROM中。这些命令的格式为0x1X,表示具有存储功能。例如
1、设置节点ID 并存储到EEPROM
首先,将接受到的数据转为unit类型,如果date[4]里的数据非零,则表示需要提交数据,然后将boardConfig.configstatus设置为提交配置
case 0x11: // Set Node-ID and Store to EEPROM 将节点ID储存到EEPROM储存器中
boardConfig.canNodeId = *(uint32_t*) (RxData); //将接收到的数据转换成uint类型
if (_data[4]) //如果date[4]非零,表示需要提交数据
boardConfig.configStatus = CONFIG_COMMIT;//将boardConfig.configStatus设置为提交配置
break;
2、设置电流限制并存储到EEPROM
先将接受到的数据转换为float类型,然后再通过×1000转换为int类型,并将其作为电流限制值。如果date[4]里面的数据非零,则表示需要提交数据,然后将boardConfig.configstatus设置为提交配置
case 0x12: // Set Current-Limit and Store to EEPROM设置电流限制并存储到EEPROM
motor.config.motionParams.ratedCurrent = (int32_t) (*(float*) RxData * 1000);/*接收到的数据(_data)转换为float类型,并乘以1000
转换为int32_t类型*/
boardConfig.currentLimit = motor.config.motionParams.ratedCurrent; //将电流限制值赋值给boardConfig.currentLimit
if (_data[4])
boardConfig.configStatus = CONFIG_COMMIT;
break;
3、将当前位置应用为零点偏移,并将偏移值存储到EEPROM中
motor.controller表示电机控制器对象,调用ApplyPosAsHomeOffeset()函数将当前位置应用为零点偏移。然后计算编码器的Home Offset值。motor.config.motionParams.encoderHomeOffset表示电机配置结构体中的编码器零点偏移量,将除以电机每圈细分步数的余数,然后把值储存在 boardConfig.encoderHomeOffsset变量中,最后将boardConfig.configstatus设置为提交配置。
case 0x15: // Apply Home-Position and Store to EEPROM 应用Home-Position并存储到EEPROM
motor.controller->ApplyPosAsHomeOffset(); //调用ApplyPosAsHomeOffeset()函数将当前位置应用为零点偏移
boardConfig.encoderHomeOffset = motor.config.motionParams.encoderHomeOffset %
motor.MOTOR_ONE_CIRCLE_SUBDIVIDE_STEPS;/*将电机配置结构体中的编码器零点偏移量,
除以电机每圈细分步数的余数*/
boardConfig.configStatus = CONFIG_COMMIT;
后续代码内容与前两个大同小异,具体功能如下
- 0x13 设置速度限制并存储到EEPROM
- 0x14 设置加速度并存储到EEPROM
- 0x16 设置自动启用电机并存储到EEPROM
- 0x17 设置DCE控制器的Kp值并存储到EEPROM
- 0x18 设置DCE控制器的Kp值并存储到EEPROM
- 0x19 设置DCE控制器的Ki值,并存储到EEPROM
- 0x1A 设置DCE控制器的Kd值,并存储到EEPROM
- 0x1B 设置启用堵转保护并存储到EEPROM
其中,DCE控制器是指Direct Current Electric(直流电)控制器,主要用于调节直流电动机的转速、转矩和运行方向
第三部分
接下来就是第三部分,一些查询命令,这些命令的格式为0x2X,例如
获得电流值
先调用一个函数,获得当前的电流值,然后把该电流值的地址赋值给b,通过一个循环语句,将tmpF
的4个字节复制到_data
数组的前4个元素中,这样就将电流值转换为字节数组。 然后判断电机是否处于完成状态,如果处于完成状态,将_data[4]设置为1,否则设置为0。然后设置确认消息的标准帧ID,最后通过调用Can_Send函数,将确认消息发出去。
case 0x21: // Get Current 获取电流值
{
tmpF = motor.controller->GetFocCurrent(); /*调用motor.controller->GetFocCurrent()函数获取当前的电流值,并将其赋值给tmpF*/
auto* b = (unsigned char*) &tmpF;//定义一个指向tmpF的unsigned char指针b,将tmpF的地址赋值给b
for (int i = 0; i < 4; i++)
_data[i] = *(b + i);//使用循环语句,将tmpF的4个字节复制到_data的前4个元素中
_data[4] = (motor.controller->state == Motor::STATE_FINISH ? 1 : 0);/*根据motor.controller->state的状态判断电机是否处于完成状态。
如果处于完成状态,将_data[4]设置为1,否则设置为0*/
txHeader.StdId = (boardConfig.canNodeId << 7) | 0x21; //设置确认消息的标准帧ID
CAN_Send(&txHeader, _data);//调用CAN_Send(&txHeader, _data)函数将确认消息通过CAN总线发送出去
}
其余命令如下
- 0x22 获取速度值
- 0x23 获取位置值
- 0x24 获取偏移值
最后,还有一些系统命令
case 0x7e: // Erase Configs 擦除配置
boardConfig.configStatus = CONFIG_RESTORE;
break;
case 0x7f: // Reboot重启系统
HAL_NVIC_SystemReset();
break;
default:
break;