在開啟can1時鍾的基礎上,進行如下配置:
1 /** 2 * @brief CAN2 Initialization Function 3 * @param None 4 * @retval None 5 */ 6 void MX_CAN2_Init(void) 7 { 8 9 /* USER CODE BEGIN CAN2_Init 0 */ 10 CAN_FilterTypeDef CAN2_FilerConf; 11 /* USER CODE END CAN2_Init 0 */ 12 13 /* USER CODE BEGIN CAN2_Init 1 */ 14 15 /* USER CODE END CAN2_Init 1 */ 16 hcan2.Instance = CAN2; 17 hcan2.Init.Prescaler = 3; 18 hcan2.Init.Mode = CAN_MODE_NORMAL; 19 hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ; 20 hcan2.Init.TimeSeg1 = CAN_BS1_9TQ; 21 hcan2.Init.TimeSeg2 = CAN_BS2_4TQ; 22 hcan2.Init.TimeTriggeredMode = DISABLE;//這幾個DISABLE暫時還用不上,我試着改了幾個為ENABLE也能正常運行(小弟才疏學淺,要是有錯誤輕噴) 23 hcan2.Init.AutoBusOff = DISABLE; 24 hcan2.Init.AutoWakeUp = DISABLE; 25 hcan2.Init.AutoRetransmission = DISABLE; 26 hcan2.Init.ReceiveFifoLocked = DISABLE; 27 hcan2.Init.TransmitFifoPriority = DISABLE; 28 if (HAL_CAN_Init(&hcan2) != HAL_OK) 29 { 30 Error_Handler(); 31 } 32 33 /* USER CODE BEGIN CAN2_Init 2 */ 34 CAN2_FilerConf.FilterIdHigh = 0X0000; 35 CAN2_FilerConf.FilterIdLow = 0X0000; 36 CAN2_FilerConf.FilterMaskIdHigh = 0X0000; 37 CAN2_FilerConf.FilterMaskIdLow = 0X0000; 38 CAN2_FilerConf.FilterFIFOAssignment = CAN_FILTER_FIFO1;//此處選擇fifo號要與其他地方一致 39 CAN2_FilerConf.FilterBank = 14; 40 CAN2_FilerConf.FilterMode = CAN_FILTERMODE_IDMASK; 41 CAN2_FilerConf.FilterScale = CAN_FILTERSCALE_32BIT; 42 CAN2_FilerConf.FilterActivation = ENABLE; 43 CAN2_FilerConf.SlaveStartFilterBank = 14; 44 if (HAL_CAN_ConfigFilter(&hcan2, &CAN2_FilerConf) != HAL_OK) 45 { 46 /* Filter configuration Error */ 47 Error_Handler(); 48 } 49 50 /* Start the CAN peripheral */ 51 if (HAL_CAN_Start(&hcan2) != HAL_OK)//這個函數和下面的函數是cubemx沒有給出的,需要手動添加 52 { 53 /* Start Error */ 54 Error_Handler(); 55 } 56 57 /* Activate CAN RX notification */ 58 if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)//選擇fifo1中斷 59 { 60 /* Notification Error */ 61 Error_Handler(); 62 } 63 64 /* USER CODE END CAN2_Init 2 */ 65 }
回調函數:
1 /** 2 *@brief CAN2回調函數 3 */ 4 void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) 5 { 6 CAN_RxHeaderTypeDef RxMsg; 7 8 uint8_t Rx_BUF[8]; 9 RxMsg.DLC=8; 10 RxMsg.IDE=CAN_ID_STD; 11 RxMsg.RTR=CAN_RTR_DATA; 12 13 if(hcan->Instance == CAN2) 14 { 15 HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO1, &RxMsg, Rx_BUF);//此處的fifo1也要注意 16 } 17 }
有幾個需要注意的點已在代碼后面注釋。
另外,回調函數的選擇、msp初始化函數中的接收中斷使能名稱,stm32f4xx_it.c中的中斷函數名稱一定要與所選擇的fifo號一致,我就是因為中斷函數名稱選成了RX0而被坑了好幾天。