当电机不处于速度闭环且使用私有协议的速度闭环函数RobStride_Motor_Speed_control时,单片机会一口气发送6帧数据,但用逻辑分析仪只采到了4帧。
按时间顺序采集到的这四帧数据分别对应这4个函数:
Set_RobStride_Motor_parameter(0X7005, Speed_control_mode, Set_mode);
Enable_Motor();
Get_RobStride_Motor_parameter(0x7005);
Set_RobStride_Motor_parameter(0X700A, Motor_Set_All.set_speed, Set_parameter);
但代码中却是先Get_RobStride_Motor_parameter(0x7005);再Enable_Motor();,第二三行代码发生了竞争,此外还有两帧数据发送失败。
解决办法:在这6个函数中间加延时,或者在发送数据前先判断邮箱是否为空,例如将HAL_CAN_AddTxMessage换成CAN_Send_With_Timeout。
uint32_t timeout=100;
HAL_StatusTypeDef CAN_Send_With_Timeout(uint32_t timeout, CAN_TxHeaderTypeDef TxMessage, const uint8_t txdata[])
{
uint32_t tickstart = HAL_GetTick();
while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0)
{
if ((HAL_GetTick() - tickstart) > timeout)
return HAL_TIMEOUT;
}
// 确保有空闲邮箱后,再调用 HAL_CAN_AddTxMessage
return HAL_CAN_AddTxMessage(&hcan1, &TxMessage, txdata, &Mailbox);
}
推测原因:官方工程的HCLK是72MHZ,我使用的是168MHZ,在处理数据时更快却未检查can的状态,从而导致掉帧和竞争的发生。
当电机不处于速度闭环且使用私有协议的速度闭环函数RobStride_Motor_Speed_control时,单片机会一口气发送6帧数据,但用逻辑分析仪只采到了4帧。
按时间顺序采集到的这四帧数据分别对应这4个函数:
Set_RobStride_Motor_parameter(0X7005, Speed_control_mode, Set_mode);
Enable_Motor();
Get_RobStride_Motor_parameter(0x7005);
Set_RobStride_Motor_parameter(0X700A, Motor_Set_All.set_speed, Set_parameter);
但代码中却是先Get_RobStride_Motor_parameter(0x7005);再Enable_Motor();,第二三行代码发生了竞争,此外还有两帧数据发送失败。
解决办法:在这6个函数中间加延时,或者在发送数据前先判断邮箱是否为空,例如将HAL_CAN_AddTxMessage换成CAN_Send_With_Timeout。
uint32_t timeout=100;
HAL_StatusTypeDef CAN_Send_With_Timeout(uint32_t timeout, CAN_TxHeaderTypeDef TxMessage, const uint8_t txdata[])
{
uint32_t tickstart = HAL_GetTick();
while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0)
{
if ((HAL_GetTick() - tickstart) > timeout)
return HAL_TIMEOUT;
}
// 确保有空闲邮箱后,再调用 HAL_CAN_AddTxMessage
return HAL_CAN_AddTxMessage(&hcan1, &TxMessage, txdata, &Mailbox);
}
推测原因:官方工程的HCLK是72MHZ,我使用的是168MHZ,在处理数据时更快却未检查can的状态,从而导致掉帧和竞争的发生。