STM32CubeMX教程:配置STM32F4的CAN1/2/3并开启接收中断

目录

  • 1. CAN配置
  • 1.1引脚(STM32F413VGT6-LQFP100)
  • 1.2 时钟
  • 1.3 RCC配置
  • 1.4 CAN1配置
  • 1.5 CAN2配置
  • 1.6 CAN3配置
  • 1.7 输出设置
  • 2. CAN代码
  • 2.1 CAN初始化
  • 2.2 CAN滤波器设置
  • 2.3 CAN使能
  • 2.4 激活中断
  • 2.5 CAN发送函数
  • 2.6 CAN回调函数
  • 2.7 main之后的代码
  • 1. CAN配置

    1.1引脚(STM32F413VGT6-LQFP100)

    1.2 时钟

    外部使用8MHz晶振
    开启内部16MHz晶振
    使用锁相环
    最大100MHz,3路CAN时钟挂载于APB1时钟上,频率50MHz


    .
    .

    1.3 RCC配置


    .
    .

    1.4 CAN1配置

    波特率计算:
    500K = 50MHz / (5+4+1)*10 ;(10、5、4、1在下图中有介绍)。
    这里我理解的数据段周期是在5和4周期之间进行采样。

    .
    .
    接收中断全部开启:

    1.5 CAN2配置



    .
    .

    1.6 CAN3配置


    1.7 输出设置


    .
    .

    2. CAN代码

    修改内容:

    1. 开启CAN2时钟前,打开CAN1时钟,因为CAN2是CAN的从机,CAN1是主机;STM32F413VGT6中CAN1和CAN2分配(共用)256字节的SRAM,而CAN3分配(使用)512字节;这里我的理解是:由于CAN2是从机,需要调用CAN1去初始化共用的256字节SRAM,所以需要在开启CAN2时钟前,打开CAN1时钟;

    2. 在MAIN()函数里面加上CAN的 滤波器初始化代码、CAN使能代码、CAN的接收(RX)中断使能代码;

    3. 在CAN的滤波器初始化代码中:
      CAN1设置:
      sFilterConfig.FilterBank = 0;
      sFilterConfig.SlaveStartFilterBank = 14;

      CAN2设置:
      sFilterConfig.FilterBank = 14;
      sFilterConfig.SlaveStartFilterBank = 14;
      (这块设置貌似也只能这样,我试了很多其他的方式,只有这种可以使用,这里不是很懂)

    2.1 CAN初始化

    这里只改了void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)的这个部分

    else if(canHandle->Instance==CAN2)
      {
      /* USER CODE BEGIN CAN2_MspInit 0 */
    
      /* USER CODE END CAN2_MspInit 0 */
        /* CAN2 clock enable */
    	__HAL_RCC_CAN1_CLK_ENABLE(); //只增加的部分
        __HAL_RCC_CAN2_CLK_ENABLE();
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**CAN2 GPIO Configuration
        PB12     ------> CAN2_RX
        PB13     ------> CAN2_TX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* CAN2 interrupt Init */
    		HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
    		
        //HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
        HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
      /* USER CODE BEGIN CAN2_MspInit 1 */
    
      /* USER CODE END CAN2_MspInit 1 */
      }
    

    .

    2.2 CAN滤波器设置

    	//
    	CAN1_Filter_Config();
    	CAN2_Filter_Config();
    	CAN3_Filter_Config();
    
    	//CAN1 滤波器设置
    	void CAN1_Filter_Config(){
    	CAN_FilterTypeDef sFilterConfig;
    	
    	sFilterConfig.FilterBank = 0;						//
    	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;	/
    	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;	//
    	sFilterConfig.FilterIdHigh = 0X0000;				//
    	sFilterConfig.FilterIdLow = 0X0000;					//
    	sFilterConfig.FilterMaskIdHigh = 0X0000;			//
    	sFilterConfig.FilterMaskIdLow = 0X0000;				//
    	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;	//
    	sFilterConfig.FilterActivation = ENABLE;			//
    	sFilterConfig.SlaveStartFilterBank = 14;			//
    	
    	if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
    	{
    		Error_Handler();
    	}
    }
    
    //CAN2 滤波器设置
    void CAN2_Filter_Config(){
    	CAN_FilterTypeDef sFilterConfig;
    	
    	sFilterConfig.FilterBank = 14;						//滤波器组初始化
    	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;	//
    	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;	//
    	sFilterConfig.FilterIdHigh = 0X0000;				//
    	sFilterConfig.FilterIdLow = 0X0000;					//
    	sFilterConfig.FilterMaskIdHigh = 0X0000;			//
    	sFilterConfig.FilterMaskIdLow = 0X0000;				//
    	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;	//
    	sFilterConfig.FilterActivation = ENABLE;			//
    	sFilterConfig.SlaveStartFilterBank = 14;			//从属滤波器组,单路CAN无意义
    	
    	if(HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
    	{
    		Error_Handler();
    	}
    }
    
    //CAN3设置
    void CAN3_Filter_Config(){
    	CAN_FilterTypeDef sFilterConfig;
    	
    	sFilterConfig.FilterBank = 0;						//
    	sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;	//
    	sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;	//
    	sFilterConfig.FilterIdHigh = 0X0000;				//
    	sFilterConfig.FilterIdLow = 0X0000;					//
    	sFilterConfig.FilterMaskIdHigh = 0X0000;			//
    	sFilterConfig.FilterMaskIdLow = 0X0000;				//
    	sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;	//
    	sFilterConfig.FilterActivation = ENABLE;			//
    	sFilterConfig.SlaveStartFilterBank = 14;			//
    	
    	if(HAL_CAN_ConfigFilter(&hcan3, &sFilterConfig) != HAL_OK)
    	{
    		Error_Handler();
    	}
    }
    

    .

    2.3 CAN使能

    	HAL_CAN_Start(&hcan1);
    	HAL_CAN_Start(&hcan2);
    	HAL_CAN_Start(&hcan3);
    

    .

    2.4 激活中断

    	HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
    	HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
    	HAL_CAN_ActivateNotification(&hcan3, CAN_IT_RX_FIFO0_MSG_PENDING);
    

    .

    2.5 CAN发送函数

    // 配置
    CAN_TxHeaderTypeDef CAN_TX_T;
    uint32_t tx_mailBox;
    uint8_t tx_data[4] = {0x55, 0x66, 0x23, 0x58};
    CAN_TX_T.StdId = 0x15;
    CAN_TX_T.ExtId = 0;
    CAN_TX_T.DLC = 4;
    
    // 发送
    HAL_CAN_AddTxMessage(&hcan1, &CAN_TX_T, tx_data, &tx_mailBox);
    

    .

    2.6 CAN回调函数

    CAN_RxHeaderTypeDef rxHeader;
    void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    {
    	uint8_t data_ss[8];
    	//HAL_UART_Transmit(&huart1, data_s2, 10, 1000);
    	if(hcan->Instance == CAN1)
    	{
    		HAL_UART_Transmit(&huart1, data_s1, 10, 1000);
    		
    		HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rxHeader, data_ss);
    	}
    	if(hcan->Instance == CAN2)
    	{
    		HAL_UART_Transmit(&huart1, data_s2, 10, 1000);
    		
    		HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &rxHeader, data_ss);
    	}
    	if(hcan->Instance == CAN3)
    	{
    		HAL_UART_Transmit(&huart1, data_s3, 10, 1000);
    		
    		HAL_CAN_GetRxMessage(&hcan3, CAN_RX_FIFO0, &rxHeader, data_ss);
    	}
    	
    }
    

    2.7 main之后的代码

        MX_CAN1_Init();
        MX_CAN2_Init();
        MX_CAN3_Init();
    	
    	CAN1_Filter_Config();
    	CAN2_Filter_Config();
    	CAN3_Filter_Config();
    	
    	HAL_CAN_Start(&hcan1);
    	HAL_CAN_Start(&hcan2);
    	HAL_CAN_Start(&hcan3);
    	
    	HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
    	HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
    	HAL_CAN_ActivateNotification(&hcan3, CAN_IT_RX_FIFO0_MSG_PENDING);
    

    作者:LuDvei

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32CubeMX教程:配置STM32F4的CAN1/2/3并开启接收中断

    发表回复