MCU_STM32CUBEMX配置生成CAN2的初始化代码的修改
备注一个STM32CUBEMX配置CAN2的遗忘点。
STM32F105/107(405/407)有两个CAN,一般我们两个都会用起来,用STM32CubeMX配置好后,有一个经常容易忘记的地方就是SlaveStartFilterBank这个参数。这里他是最重要的和hcan1不一致的地方,
CAN2_FilerConf.SlaveStartFilterBank = 14;
这一句必须开启,否则CAN2只能发送数据,无法接收到数据。
这个参数其实设置的是CAN_FMR_CAN2SB(参考《RM0008 24.9.4 CAN filter registers》)
摘录其中比较重要的两句如下,
CAN filter master register (CAN_FMR)
Bits 13:8 CAN2SB[5:0]: CAN2 start bank
These bits are set and cleared by software. They define the start bank for the CAN2 interface (Slave) in the range 0 to 27.
Note:
When CAN2SB[5:0] = 28d, all the filters to CAN1 can be used.
When CAN2SB[5:0] is set to 0, no filters are assigned to CAN1.
红色这两句的意思是:
如果CAN2SB=28,就表示28个过滤器全部分配给CAN1,因为CAN2从28开始,而序号从28开始的过滤器不存在,所以全部28个过滤器都分配给了CAN1。
如果CAN2SB=0,就表示28个过滤器全部分配给CAN2,因为最小序号0的过滤器分配给了CAN2,后续也只能连续地分配给CAN2。
STM32CUBEMX生成代码后,修改后如下,
/**
* @brief CAN1 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
HAL_StatusTypeDef HAL_Status;
// NOTE:
//Prescaler = 4; ==> APB1.36M/4 = 9M (original=16)
//Mode = CAN_MODE_LOOPBACK; ==> CAN_MODE_NORMAL; //CAN_MODE_LOOPBACK
//CAN_BS1.2_9TQ/ = CAN_BS1.2_9.8TQ; ==> BaudRate = 9M/(1+9+8) = 500K
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 4;
hcan1.Init.Mode = CAN_MODE_NORMAL; //CAN_MODE_LOOPBACK
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_8TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
// added bymc
// add filter_0 to can_1
CAN_Filter.FilterBank = 0;
CAN_Filter.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_Filter.FilterScale= CAN_FILTERSCALE_32BIT; // 32BIT WIDTH
CAN_Filter.FilterIdHigh = 0x0000; // 32BIT ID
CAN_Filter.FilterIdLow = 0x0000;
CAN_Filter.FilterMaskIdHigh = 0x0000; // 32BIT MASK
CAN_Filter.FilterMaskIdLow = 0x0000;
CAN_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; //filter_0 --> FIFO0
CAN_Filter.FilterActivation = ENABLE; // NOTE: deactivate it if not used!
if( HAL_OK != HAL_CAN_ConfigFilter(&hcan1, &CAN_Filter))
{
Error_Handler();
}
HAL_Status = HAL_CAN_Start(&hcan1);
if(HAL_Status!=HAL_OK){
Error_Handler();
}
// Activate CAN RX notification (HERE WE attach FIFO0 to CAN1) called "CAN0" in manual
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
// Activate CAN TX notification
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
{
Error_Handler();
}
// end added bymc
/* USER CODE END CAN1_Init 2 */
}
/**
* @brief CAN2 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN2_Init 0 */
HAL_StatusTypeDef HAL_Status;
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 4;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_8TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
// added bymc
// add filter_0 to can_1
CAN_Filter.FilterBank = 14; // <=27
CAN_Filter.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_Filter.FilterScale= CAN_FILTERSCALE_32BIT; // 32BIT WIDTH
CAN_Filter.FilterIdHigh = 0x0000; // 32BIT ID
CAN_Filter.FilterIdLow = 0x0000;
CAN_Filter.FilterMaskIdHigh = 0x0000; // 32BIT MASK
CAN_Filter.FilterMaskIdLow = 0x0000;
CAN_Filter.FilterFIFOAssignment = CAN_FILTER_FIFO1; //filter_0 --> FIFO0
CAN_Filter.FilterActivation = ENABLE;
CAN_Filter.SlaveStartFilterBank = 14;
if( HAL_OK != HAL_CAN_ConfigFilter(&hcan2, &CAN_Filter))
{
Error_Handler();
}
HAL_Status = HAL_CAN_Start(&hcan2);
if(HAL_Status!=HAL_OK){
Error_Handler();
}
// Activate CAN RX notification
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
{
Error_Handler();
}
// Activate CAN TX notification
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
{
Error_Handler();
}
// end added bymc
/* USER CODE END CAN2_Init 2 */
}