文章目录
帧结构
- CAN的报文结构:
测试模式(静默/换回/环回静默):
- 静默模式:
- 环回模式:
- 环回静默模式:
环回测试配置
- 选好对应GPIO即可,APB1 36 Mhz, 500kbps:
过滤器的使用
- 不配置过滤器亦可使用
- 根据不同位长模式,每个过滤器组,32位模式可以配置一个屏蔽掩码或两个白名单列表,16位模式翻倍
- 标准帧和扩展帧的ID长度分别为11比特和29比特,通过移位操作对齐其对应的高低位
测试参考用例
过滤器的初始化
- cube不能配置过滤器,需要手动配置,直接添加到生成代码的自定义区即可
- 初始化后需要手动打开CAN外设
- 单机测试使用了环回模式
c
static void MX_CAN_Init(void)
{
/* USER CODE BEGIN CAN_Init 0 */
/* USER CODE END CAN_Init 0 */
/* USER CODE BEGIN CAN_Init 1 */
/* USER CODE END CAN_Init 1 */
hcan.Instance = CAN1;
hcan.Init.Prescaler = 4;
hcan.Init.Mode = CAN_MODE_LOOPBACK;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan.Init.TimeSeg2 = CAN_BS2_8TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN_Init 2 */
//接收所有
CAN_FilterTypeDef can_filterconfig;
can_filterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
can_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
can_filterconfig.FilterIdHigh = 0;
can_filterconfig.FilterIdLow = 0;
can_filterconfig.FilterMaskIdHigh = 0;
can_filterconfig.FilterMaskIdLow = 0;
can_filterconfig.FilterBank = 0;
can_filterconfig.FilterFIFOAssignment = CAN_FilterFIFO0;
can_filterconfig.FilterActivation = CAN_FILTER_ENABLE;
can_filterconfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan, &can_filterconfig);
HAL_CAN_Start(&hcan);
/* USER CODE END CAN_Init 2 */
}
发送和接收
c
uint8_t can_send_message(CAN_TxHeaderTypeDef TxHeader,uint32_t std_id, uint8_t aData[],uint16_t lengh)
{
uint32_t TxMailBox = CAN_TX_MAILBOX0;
uint8_t FreeTxMailBoxNum = 0;
TxHeader.StdId = std_id; //id由IDE决定类型
TxHeader.ExtId = 0;
TxHeader.DLC = lengh; //数据长度
TxHeader.IDE = CAN_ID_STD; //标准帧/扩展帧
TxHeader.RTR = CAN_RTR_DATA; //数据帧
TxHeader.TransmitGlobalTime = DISABLE;
while(0 == FreeTxMailBoxNum)
{
FreeTxMailBoxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
}
if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, aData, &TxMailBox) != HAL_OK)
{
/* Transmission request Error */
Error_Handler();
}
return 1;
}
uint8_t can_receive_message(uint8_t *buf)
{
if(HAL_CAN_GetRxFifoFillLevel(&hcan,CAN_RX_FIFO0) == 0)
return 0;
HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &canRxType, buf);
return canRxType.DLC;
}
中断
四个中断源分别对应cube的四个选项:
手动中断开启函数:
c
HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING);
中断回调函数:
c
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if(hcan->Instance == CAN1)
{
HAL_CAN_GetRxMessage(&hcan, CAN_FILTER_FIFO0,&canRxType,canRxbuf);
}
}