cubemx实现CAN通讯

本文详细介绍了如何使用STM32CubeMX和Keil5进行STM32单片机的CAN通信配置,包括工程创建、系统配置、时钟设置、中断配置、定时器设置及CAN收发功能实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先要安装cubemx跟Keil5两个编程软件

然后打开cubemx软件,新建一个工程项目:

输入CPU型号:

在右下角双击CPU具体型号

稍等片刻会打开如下对话框:

首先要配置系统的调试方式:我们选择SW方式

然后配置晶振源,这里选择的是外部晶振,8M

使能看门狗

使能CAN

使能TIM2时钟源,采用内部时钟

配置完成后可以看到单片机管脚已经做了配置

切换到Clock Configuration选项卡,配置时钟周期,这里配置为8M

切换到Configuration选项卡,进入CAN配置选项配置波特率如下为500Kbps

配置接收中断

配置定时器如下为1ms定时器

配置定时器中断

配置完成后点击保存,然后点击如下按钮,生成代码

填写工程名称,路径,编程软件等等

选择生成代码的方式

等待

点击打开项目。代码生成部分完成。

添加一些特殊配置和逻辑代码

添加CAN的配置信息函数

void Can_Config(void)
{	
  hcan.pTxMsg = &TxMessage;
  hcan.pRxMsg = &RxMessage;

  /*##-1- Configure CAN1 Transmission Massage #####################################*/
  hcan.pTxMsg->StdId = 0x123;
  hcan.pTxMsg->RTR = CAN_RTR_DATA;
  hcan.pTxMsg->IDE = CAN_ID_STD;
  hcan.pTxMsg->DLC = 8;

  /*##-2- Configure the CAN1 Filter ###########################################*/
  sFilterConfig.FilterNumber = 0;
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;
  sFilterConfig.FilterIdHigh = 0;
  sFilterConfig.FilterIdLow = 0;
  sFilterConfig.FilterMaskIdHigh = 0;
  sFilterConfig.FilterMaskIdLow = 0;
  sFilterConfig.FilterFIFOAssignment = CAN_FIFO0;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.BankNumber = 14;
  HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
}

 在Main函数中while(1)之前调用一下即可

添加定时器启动函数: HAL_TIM_Base_Start_IT(&htim2);

CAN接收中断启动函数:HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);

/* USER CODE BEGIN 2 */

	Can_Config();                        //Can配置信息
	HAL_TIM_Base_Start_IT(&htim2);       //定时器启动
	HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//使能Can接收中断

  /* USER CODE END 2 */

 打开stm32f1xx_it.c文件,找到如下函数,

添加接收中断启动函数:HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);

注意:接收中断启动函数使能一次只进一次中断,所以中断退出前要再次使能。

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);
  /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
  HAL_CAN_Receive_IT(&hcan, CAN_FIFO0);//ʹÄÜCAN½ÓÊÕ
  /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
}

添加CAN接收服务函数:HAL_CAN_RxCpltCallback

说明:该函数在stm32f1xx_hal_can.c文件中已经有定义,它的定义方式如下:

__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)

函数前面的__weak关键字意思是如果有同样的定义,先执行没有__weak关键字的函数,所以当我们定义了HAL_CAN_RxCpltCallback函数后,编译器会先编译我们定义的函数,而忽略系统定义的该函数。当我们没有定义该函数时,系统会编译带有__weak关键字的函数。

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
{
    unsigned short int speed;
    switch(hcan->pRxMsg->StdId)
    {//根据ID处理数据
        case 0x123://
        /*在此添加数据处理逻辑*/
        break;
        default:
        break;
     }
}

 添加CAN发送函数:

/* USER CODE BEGIN WHILE */
  while (1)
  {
        HAL_IWDG_Refresh(&hiwdg); //喂狗函数

        if(Can_Trans_Timer == 0)
        {//每100ms发送一次数据
            Can_Trans_Timer = 100;
			
            hcan.pTxMsg->StdId = 0x123;

            hcan.pTxMsg->Data[0] = 'C';
            hcan.pTxMsg->Data[1] = 'A';
            hcan.pTxMsg->Data[2] = 'N';
            hcan.pTxMsg->Data[3] = ' ';
            hcan.pTxMsg->Data[4] = 'T';
            hcan.pTxMsg->Data[5] = 'E';
            hcan.pTxMsg->Data[6] = 'S';
            hcan.pTxMsg->Data[7] = 'T';
					
            HAL_CAN_Transmit(&hcan, 200);//发送一帧数据
        }
    }
  /* USER CODE END WHILE */

在定时器函数中添加定时器代码:

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
  if(Can_Trans_Timer > 0)          Can_Trans_Timer--;
  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */
	
  /* USER CODE END TIM2_IRQn 1 */
}

说明:在往工程中添加代码时要注意,不要任意往里面添加代码,要在注释着USER CODE BEGIN的地方添加代码,这样在重新生成代码时才不至于将已经写好的代码覆盖掉,如下

/* USER CODE BEGIN Includes */

添加用户代码

/* USER CODE END Includes */

/* USER CODE BEGIN PFP */

添加用户代码

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

添加用户代码

/* USER CODE END 0 */

### 使用STM32CubeMX实现通信协议 #### RS485 Modbus从机配置指南 通过STM32CubeMX可以方便地设置RS485 Modbus从机,这涉及到硬件资源的选择以及软件库函数的应用。在初始化项目时,需指定USART外设用于串口通信并启用其功能来支持半双工模式下的数据交换[^1]。 对于具体的参数设定方面,在“Pinout & Configuration”标签页下找到对应的USART模块,调整波特率至9600 bps或其他所需速率;同时勾选RTS控制选项以适应RS485线路的要求。此外还需注意的是,为了确保消息帧结构正确无误,应按照Modbus RTU标准加入CRC16校验机制[^3]。 ```c // 初始化USART实例化句柄 UART_HandleTypeDef huart; void MX_USARTx_UART_Init(void){ huart.Instance = USARTx; huart.Init.BaudRate = 9600; // 设置波特率为9600bps huart.Init.WordLength = UART_WORDLENGTH_8B; huart.Init.StopBits = UART_STOPBITS_1; huart.Init.Parity = UART_PARITY_NONE; huart.Init.Mode = UART_MODE_TX_RX; huart.Init.HwFlowCtl = UART_HWCONTROL_RTS; // 启用RTS流控 HAL_UART_Init(&huart); } ``` 当完成上述基本配置之后,则可通过调用HAL库中的API来进行更高级别的编程工作,比如发送请求命令或是处理接收到的数据包等操作。值得注意的是,由于Modbus是一种主/从架构的网络协议,因此还需要编写额外的状态机逻辑以便于管理不同类型的事务流程。 #### CAN总线配置案例分享 除了RS485之外,CAN也是另一种常见的工业级通信接口。利用STM32CubeMX同样能够快速搭建起基于该技术框架的应用程序原型。这里简要描述一下创建过程的关键环节: - **系统时钟**:确认所使用的微控制器型号及其内部振荡器频率; - **调试烧录接口**:选择SWD作为默认连接方式有利于后续开发阶段中进行在线仿真测试活动; - **CAN节点属性定义**:包括但不限于位定时寄存器(Bit Timing Register)内的各项数值填写,如SJW、BRP等参数均会影响实际传输性能表现; - **事件响应机制构建**:开启接收中断服务例程(Interrupt Service Routine),使得每当有新报文到来时都能及时触发相应的动作执行路径[^4]。 ```c // CAN滤波器配置 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; HAL_CAN_ConfigFilter(&hcan, &sFilterConfig); // 开启CAN接收中断 __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0); // FIFO 0 中断使能 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

史瓦辛彬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值