现象:在CAN通信中连续发四帧数据,出现仅仅第一帧数据能发送成功,但是后面几帧数据出现乱码的问题。
首先看我的配置代码部分:
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 6;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_6TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_7TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* 启动CAN外围设备 */
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
这是我利用STM32F4系列板子对CAN通信的配置,因此这个模块只负责发送数据的任务,因此没用过滤器配置。
void CAN_Send(uint8_t *data, uint8_t len, uint8_t id)
{
uint32_t TxMailbox = CAN_TX_MAILBOX0;
uint8_t message[8];
uint8_t count = (len-1)/8 + 1;
// uint16_t t = 0;
for(uint8_t send_count = 0;send_count < count;send_count++)
{
for(int8_t i = 0 + send_count * 8; i < 8 * (send_count+1); i++)
{
message[i%8] = data[i];
}
CAN_HandleTxMsg.StdId = id + send_count;
CAN_HandleTxMsg.IDE = CAN_ID_STD;
CAN_HandleTxMsg.RTR = CAN_RTR_DATA;
CAN_HandleTxMsg.DLC = 8;
if(send_count == count-1)CAN_HandleTxMsg.DLC = len%8;
CAN_HandleTxMsg.TransmitGlobalTime = DISABLE;
printf("send success!!!");
HAL_CAN_AddTxMessage(&hcan1, &CAN_HandleTxMsg, message, &TxMailbox);
// if(HAL_CAN_AddTxMessage(&hcan1, &CAN_HandleTxMsg, message, &TxMailbox) != HAL_OK)
// {
// Error_Handler();
// }
// while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) != 3) /* 等待发送完成,所有邮箱为空 */
// {
// t++;
//
// if (t > 0xFFF)
// {
// HAL_CAN_AbortTxRequest(&hcan1, TxMailbox); /* 超时,直接中止邮箱的发送请求 */
// }
// }
}
}
这是CAN的发送函数,这里有一个小细节可以注意一下,如果我们使用下面这段话
if(HAL_CAN_AddTxMessage(&hcan1, &CAN_HandleTxMsg, message, &TxMailbox) != HAL_OK)
{
Error_Handler();
}
就必须加上后面这段while循环的代码,或者直接用上面这个代码不要if判断。
接下来是问题产生部分:
因为我们不需要打印提示printf("send success!!!");这句话,于是把这句话给去掉了,但是一旦把这句话去掉之后就产生了消息紊乱的问题;
解决办法:
把printf("send success!!!");修改为HAL_Delay(1);
原因:可能是连续两帧数据不能发送得太快,需要有一定得间隔才行,不然不满足CAN通讯协议的要求。