0 工具准备
1.STM32CubeMX
1 前言
本文介绍基于STM32CubeMX,使用stm32h743xi的对FDCAN2进行配置的方法。
2 初始化代码生成
2.1 选择FDCAN引脚
本例选择PB5、PB6作为FDCAN2的RX、TX引脚。
2.2 选择FDCAN时钟源
本例选择PLL2Q作为FDCAN时钟源,频率设置为100MHz。配置如下:
2.3 FDCAN参数设置
这一部分可以在代码里修改,一般设置标准帧过滤器个数、扩展帧过滤器个数、RX FIFO个数、TX FIFO个数、RX FIFIO元素大小、TX FIFO元素大小即可,其余参数在代码里修改。
本例使用中断接收CAN报文,使能所有FDCAN2相关中断:
可以在NVIC选项里修改FDCAN2抢占优先级和子优先级为(3,0):
2.4 初始化代码生成
配置好后,直接点击“生成”按钮生成我们需要的初始化代码:
生成的初始化相关代码如下:
/**
* @brief FDCAN2 Initialization Function
* @param None
* @retval None
*/
static void MX_FDCAN2_Init(void)
{
/* USER CODE BEGIN FDCAN2_Init 0 */
/* USER CODE END FDCAN2_Init 0 */
/* USER CODE BEGIN FDCAN2_Init 1 */
/* USER CODE END FDCAN2_Init 1 */
hfdcan2.Instance = FDCAN2;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = DISABLE;
hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = DISABLE;
hfdcan2.Init.NominalPrescaler = 10;
hfdcan2.Init.NominalSyncJumpWidth = 1;
hfdcan2.Init.NominalTimeSeg1 = 17;
hfdcan2.Init.NominalTimeSeg2 = 2;
hfdcan2.Init.DataPrescaler = 1;
hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 1;
hfdcan2.Init.DataTimeSeg2 = 1;
hfdcan2.Init.MessageRAMOffset = 0;
hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 1;
hfdcan2.Init.RxFifo0ElmtsNbr = 64;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.RxFifo1ElmtsNbr = 0;
hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.RxBuffersNbr = 0;
hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_64;
hfdcan2.Init.TxEventsNbr = 0;
hfdcan2.Init.TxBuffersNbr = 0;
hfdcan2.Init.TxFifoQueueElmtsNbr = 32;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_64;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN2_Init 2 */
/* USER CODE END FDCAN2_Init 2 */
}
/**
* @brief FDCAN MSP Initialization
* This function configures the hardware resources used in this example
* @param hfdcan: FDCAN handle pointer
* @retval None
*/
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hfdcan->Instance==FDCAN2)
{
/* USER CODE BEGIN FDCAN2_MspInit 0 */
/* USER CODE END FDCAN2_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInitStruct.PLL2.PLL2M = 5;
PeriphClkInitStruct.PLL2.PLL2N = 80;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 4;
PeriphClkInitStruct.PLL2.PLL2R = 1;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_FDCAN_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**FDCAN2 GPIO Configuration
PB5 ------> FDCAN2_RX
PB6 ------> FDCAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* FDCAN2 interrupt Init */
HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn);
HAL_NVIC_SetPriority(FDCAN2_IT1_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(FDCAN2_IT1_IRQn);
HAL_NVIC_SetPriority(FDCAN_CAL_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(FDCAN_CAL_IRQn);
/* USER CODE BEGIN FDCAN2_MspInit 1 */
/* USER CODE END FDCAN2_MspInit 1 */
}
}
/**
* @brief FDCAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hfdcan: FDCAN handle pointer
* @retval None
*/
void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* hfdcan)
{
if(hfdcan->Instance==FDCAN2)
{
/* USER CODE BEGIN FDCAN2_MspDeInit 0 */
/* USER CODE END FDCAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_FDCAN_CLK_DISABLE();
/**FDCAN2 GPIO Configuration
PB5 ------> FDCAN2_RX
PB6 ------> FDCAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5|GPIO_PIN_6);
/* FDCAN2 interrupt DeInit */
HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn);
HAL_NVIC_DisableIRQ(FDCAN2_IT1_IRQn);
HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn);
/* USER CODE BEGIN FDCAN2_MspDeInit 1 */
/* USER CODE END FDCAN2_MspDeInit 1 */
}
}
/**
* @brief This function handles FDCAN2 interrupt 0.
*/
void FDCAN2_IT0_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */
/* USER CODE END FDCAN2_IT0_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */
/* USER CODE END FDCAN2_IT0_IRQn 1 */
}
/**
* @brief This function handles FDCAN2 interrupt 1.
*/
void FDCAN2_IT1_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN2_IT1_IRQn 0 */
/* USER CODE END FDCAN2_IT1_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN FDCAN2_IT1_IRQn 1 */
/* USER CODE END FDCAN2_IT1_IRQn 1 */
}
/**
* @brief This function handles FDCAN calibration unit interrupt.
*/
void FDCAN_CAL_IRQHandler(void)
{
/* USER CODE BEGIN FDCAN_CAL_IRQn 0 */
/* USER CODE END FDCAN_CAL_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN FDCAN_CAL_IRQn 1 */
/* USER CODE END FDCAN_CAL_IRQn 1 */
}