[STM32G4] STM32G431 实现 CAN 通信的完整指南

[复制链接]
 楼主| 童雨竹 发表于 2024-12-1 07:45 | 显示全部楼层 |阅读模式
随着物联网、自动化和智能设备的迅速发展,微控制器(MCU)在其中扮演着重要角色。STM32系列的MCU因其高性能和广泛的应用而广受欢迎。今天,我们将深入探讨如何使用 STM32G431 实现 CAN 通信。STM32G431 是一款基于 ARM Cortex-M4 内核的高性能微控制器,支持丰富的外设和高精度的处理能力,特别适用于需要高速数据传输的场合。
1. STM32G431 概述STM32G431 属于 STMicroelectronics 的 STM32G4 系列,具有高达 170 MHz 的处理器频率,提供了包括 12-bit ADC、多个 SPI、I2C、USART、CAN、USB 和其他接口在内的多种外设。CAN (Controller Area Network) 接口是一种用于汽车和工业设备的通信协议,它支持高速通信和多主机架构,非常适合实时数据交换。
STM32G431 提供了两个 CAN 总线接口(CAN1 和 CAN2),这使得它在需要高速数据传输的场合特别有用。
2. CAN 总线协议简介CAN 是一种多主机、消息优先级的串行通信协议,它通过控制器与其他节点设备(如传感器、执行器等)进行实时、可靠的通信。CAN 采用两线制差分信号传输,这使其在噪声环境中具有优越的抗干扰能力。
CAN 协议定义了以下几个重要的要素:
  • 消息标识符(ID):每个消息都有一个唯一的 ID,用于区分不同的消息。
  • 数据帧:包含数据字段和控制信息。
  • 位定时:CAN 协议通过位定时控制通信速度。
  • 消息过滤器:用于筛选接收到的消息。
3. STM32G431 CAN 总线配置STM32G431 配置 CAN 总线时,我们需要完成以下几步:
  • 启用时钟:首先,必须确保 STM32G431 的 CAN 总线时钟已启用。
  • 配置引脚:STM32G431 的 CAN 接口通常需要通过两个引脚(CAN_TX 和 CAN_RX)与总线连接。
  • 初始化 CAN 控制器:初始化 CAN 控制器并配置其工作模式(如标准模式或扩展模式)。
  • 设置过滤器:配置 CAN 接口的接收过滤器,确保只接收相关的消息。
  • 发送和接收消息:配置和使用 CAN 控制器进行数据传输。
4. 代码实现下面是 STM32G431 配置 CAN 接口并进行通信的代码示例。代码包括 CAN 初始化、发送和接收消息的实现。
4.1 CAN 初始化代码
  1. #include "stm32g4xx_hal.h"

  2. CAN_HandleTypeDef hcan1;
  3. CAN_TxHeaderTypeDef TxHeader;
  4. CAN_RxHeaderTypeDef RxHeader;
  5. uint8_t TxData[8] = {0};
  6. uint8_t RxData[8] = {0};

  7. void SystemClock_Config(void);
  8. static void MX_CAN1_Init(void);
  9. static void MX_GPIO_Init(void);
  10. static void MX_DMA_Init(void);

  11. int main(void) {
  12.     // 初始化 HAL 库
  13.     HAL_Init();
  14.    
  15.     // 配置系统时钟
  16.     SystemClock_Config();

  17.     // 初始化 GPIO
  18.     MX_GPIO_Init();

  19.     // 初始化 CAN1 外设
  20.     MX_CAN1_Init();

  21.     // 配置 CAN 消息头
  22.     TxHeader.DLC = 8;
  23.     TxHeader.IDE = CAN_ID_STD;
  24.     TxHeader.RTR = CAN_RTR_DATA;
  25.     TxHeader.StdId = 0x123;
  26.    
  27.     // 发送数据
  28.     TxData[0] = 0x11;
  29.     TxData[1] = 0x22;
  30.     TxData[2] = 0x33;
  31.     TxData[3] = 0x44;
  32.     TxData[4] = 0x55;
  33.     TxData[5] = 0x66;
  34.     TxData[6] = 0x77;
  35.     TxData[7] = 0x88;

  36.     if (HAL_CAN_AddTxMessage(&hcan1, &TxHeader, TxData, (uint32_t*)CAN_TX_MAILBOX0) != HAL_OK) {
  37.         Error_Handler();
  38.     }

  39.     // 接收数据
  40.     if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) {
  41.         Error_Handler();
  42.     }

  43.     while (1) {
  44.         // 主循环
  45.     }
  46. }

  47. void SystemClock_Config(void) {
  48.     // 这里可以设置系统时钟
  49. }

  50. static void MX_CAN1_Init(void) {
  51.     hcan1.Instance = CAN1;
  52.     hcan1.Init.Prescaler = 16;
  53.     hcan1.Init.Mode = CAN_MODE_NORMAL;
  54.     hcan1.Init.SJW = CAN_SJW_1TQ;
  55.     hcan1.Init.BS1 = CAN_BS1_3TQ;
  56.     hcan1.Init.BS2 = CAN_BS2_2TQ;
  57.     hcan1.Init.TTCM = DISABLE;
  58.     hcan1.Init.ABOM = DISABLE;
  59.     hcan1.Init.AutoRetry = ENABLE;
  60.     hcan1.Init.AutoBusOff = ENABLE;
  61.     hcan1.Init.ReceiveFifoLocked = DISABLE;
  62.     hcan1.Init.TransmitFifoPriority = DISABLE;

  63.     if (HAL_CAN_Init(&hcan1) != HAL_OK) {
  64.         Error_Handler();
  65.     }
  66. }

  67. static void MX_GPIO_Init(void) {
  68.     // 这里可以设置 GPIO 引脚
  69. }

  70. static void MX_DMA_Init(void) {
  71.     // 这里可以初始化 DMA
  72. }

  73. void Error_Handler(void) {
  74.     // 错误处理
  75.     while(1) {
  76.         // 持续等待错误
  77.     }
  78. }
4.2 代码解释
  • HAL_CAN_Init:初始化 CAN 控制器,设置波特率、同步跳跃宽度等参数。
  • HAL_CAN_AddTxMessage:用于发送 CAN 消息。
  • HAL_CAN_GetRxMessage:用于接收 CAN 消息。
  • CAN_TxHeaderTypeDefCAN_RxHeaderTypeDef 结构体用于存储消息头信息,包括消息 ID、数据长度等。
5. 调试与测试在进行代码测试时,我们需要确保以下几点:
  • 硬件连接:确保 CAN_TX 和 CAN_RX 引脚正确连接到 CAN 总线上。
  • 波特率匹配:确保所有参与通信的设备波特率一致。
  • 消息 ID 匹配:确保发送和接收的消息 ID 合法且匹配。
6. 总结STM32G431 是一款功能强大的微控制器,适合用于工业、汽车、物联网等领域的高速数据传输。通过这篇文章,我们学习了如何在 STM32G431 上配置和使用 CAN 总线进行数据传输。希望这个教程能帮助你在实际项目中顺利实现 CAN 通信。

公羊子丹 发表于 2024-12-1 07:46 | 显示全部楼层
哇,这篇文章讲得太详细了!直接上手就能用,太棒了!
周半梅 发表于 2024-12-1 07:46 | 显示全部楼层
很好,STM32G431 真的是一个高性能的芯片,适合这种项目。
帛灿灿 发表于 2024-12-1 07:46 | 显示全部楼层
这段代码特别清晰,能直接跑起来,省了很多时间!
 楼主| 童雨竹 发表于 2024-12-1 07:46 | 显示全部楼层
能否解释一下 CAN 过滤器是如何配置的?我感觉这个非常重要。
万图 发表于 2024-12-1 07:47 | 显示全部楼层
想问一下,这里用的波特率设置是怎么样的?
Wordsworth 发表于 2024-12-1 07:47 | 显示全部楼层
我的 STM32G431 和设备连接不上 CAN 总线,应该检查哪些地方?
Pulitzer 发表于 2024-12-1 07:47 | 显示全部楼层
这篇文章很好,给我的项目提供了很多思路!
Bblythe 发表于 2024-12-1 07:47 | 显示全部楼层
感觉 STM32 还蛮适合做嵌入式开发的,自己动手试了一下,成功了。
Uriah 发表于 2024-12-1 07:48 | 显示全部楼层
看完这篇文章,我决定试试在汽车项目中使用 STM32G431 了!
Clyde011 发表于 2024-12-1 07:48 | 显示全部楼层
这种低延迟的实时通信真的很适合工业应用,学习了!
qintian0303 发表于 2024-12-1 10:02 | 显示全部楼层
CAN通信个人感觉在日常生活中的应用还是不太能感觉到,不过整体应用还是越来越多了
312小七 发表于 2025-2-18 10:52 | 显示全部楼层
学习了,感谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

155

主题

5900

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部