1、使用stm32cube生成CAN代码注意事项:
a、需要手动配置CAN过滤器
{ CAN_FilterConfTypeDef sFilterConfig; uint32_t filterID = (uint32_t)SysAddr<<23; uint32_t filterMaskID = 0x7F800000; sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = (uint16_t)(filterID>>16); sFilterConfig.FilterIdLow = filterID; sFilterConfig.FilterMaskIdHigh = (uint16_t)(filterMaskID>>16); sFilterConfig.FilterMaskIdLow = filterMaskID; sFilterConfig.FilterFIFOAssignment = 0; //收到的报文放在FIFO 0里面 sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14; if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); } filterID = 0x7F800000; sFilterConfig.FilterNumber = 1; sFilterConfig.FilterIdHigh = (uint16_t)(filterID>>16); sFilterConfig.FilterIdLow = filterID; if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { /* Filter configuration Error */ Error_Handler(); } }
b、需要手动使能CAN FIFO接收中断
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0); //使能FIFO0接收中断
c、需要手动初始化数据结构体
typedef struct { CanTxMsgTypeDef TxMsg; CanRxMsgTypeDef RxMsg; CanRxMsgTypeDef Rx1Msg; }CAN_RxTxBufTypeDef; CAN_RxTxBufTypeDef CAN_RxTxBuf; void Can_DataRxTxInit(CAN_HandleTypeDef* hcan) { memset(&CAN_RxTxBuf, 0X00, sizeof(CAN_RxTxBuf)); hcan->pTxMsg = (CanTxMsgTypeDef *)&CAN_RxTxBuf.TxMsg; hcan->pRxMsg = (CanRxMsgTypeDef *)&CAN_RxTxBuf.RxMsg; hcan->pRx1Msg = (CanRxMsgTypeDef *)&CAN_RxTxBuf.Rx1Msg; }
d、每次接收中断完成后需要手动使能下一次接收中断
void USB_LP_CAN1_RX0_IRQHandler(void) { /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */ /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */ HAL_CAN_IRQHandler(&hcan); HAL_CAN_Receive_IT(&hcan,CAN_FIFO0); /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */ }
e、数据接收、发送与错误回调函数
void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan); void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan); void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan);