[STM32G4] 深入探索STM32G431:基于CAN接口的多控制器通信设计

[复制链接]
1774|12
 楼主| 童雨竹 发表于 2024-12-16 07:49 | 显示全部楼层 |阅读模式
在嵌入式系统开发中,STM32系列的MCU以其高性能和多功能性广受欢迎。本文将聚焦STM32G431,并结合实际项目经验,探讨如何利用它的CAN接口设计多控制器通信系统。
项目背景目标是设计一个多控制器通信系统,其中STM32G431作为从控制器,通过CAN总线连接到PC,负责接收指令并上报状态。我们将从硬件配置、软件实现和调试技巧三方面展开详细说明。

硬件设计
  • 处理器选型:STM32G431系列适合需要中等计算能力的实时控制任务。
  • CAN收发器:推荐使用MCP2551或TJA1050作为外部收发器,确保与物理层兼容。
  • 终端电阻:在CAN总线的两端添加120欧姆的终端电阻以避免信号反射。
  • 电源管理:STM32G431运行在3.3V,确保电源稳定性。

软件实现1. 初始化CAN外设
我们将采用HAL库来简化开发过程。以下代码展示了如何配置CAN外设,包括波特率和滤波器。
  1. #include "stm32g4xx_hal.h"

  2. CAN_HandleTypeDef hcan;

  3. void CAN_Config(void) {
  4.     // 配置CAN时钟
  5.     __HAL_RCC_CAN1_CLK_ENABLE();
  6.     __HAL_RCC_GPIOA_CLK_ENABLE();
  7.    
  8.     // 配置CAN引脚 (PA11: RX, PA12: TX)
  9.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  10.     GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
  11.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  12.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  13.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  14.     GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
  15.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  16.    
  17.     // 初始化CAN
  18.     hcan.Instance = CAN1;
  19.     hcan.Init.Prescaler = 16; // 配置波特率,500Kbps
  20.     hcan.Init.Mode = CAN_MODE_NORMAL;
  21.     hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  22.     hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  23.     hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  24.     hcan.Init.AutoBusOff = DISABLE;
  25.     hcan.Init.AutoWakeUp = DISABLE;
  26.     hcan.Init.AutoRetransmission = ENABLE;
  27.     hcan.Init.ReceiveFifoLocked = DISABLE;
  28.     hcan.Init.TransmitFifoPriority = ENABLE;
  29.    
  30.     if (HAL_CAN_Init(&hcan) != HAL_OK) {
  31.         // 初始化失败,进入错误处理
  32.         Error_Handler();
  33.     }
  34.    
  35.     // 配置过滤器
  36.     CAN_FilterTypeDef sFilterConfig = {0};
  37.     sFilterConfig.FilterBank = 0;
  38.     sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  39.     sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  40.     sFilterConfig.FilterIdHigh = 0x0000;
  41.     sFilterConfig.FilterIdLow = 0x0000;
  42.     sFilterConfig.FilterMaskIdHigh = 0x0000;
  43.     sFilterConfig.FilterMaskIdLow = 0x0000;
  44.     sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  45.     sFilterConfig.FilterActivation = ENABLE;
  46.     sFilterConfig.SlaveStartFilterBank = 14;
  47.     HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
  48. }
2. 发送和接收数据
以下代码展示了如何实现CAN报文的发送和接收。
  1. void CAN_SendMessage(uint32_t id, uint8_t *data, uint8_t len) {
  2.     CAN_TxHeaderTypeDef TxHeader;
  3.     uint32_t TxMailbox;
  4.     TxHeader.StdId = id;
  5.     TxHeader.ExtId = 0x01;
  6.     TxHeader.IDE = CAN_ID_STD;
  7.     TxHeader.RTR = CAN_RTR_DATA;
  8.     TxHeader.DLC = len;
  9.     TxHeader.TransmitGlobalTime = DISABLE;
  10.    
  11.     if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailbox) != HAL_OK) {
  12.         // 发送失败
  13.         Error_Handler();
  14.     }
  15. }

  16. void CAN_ReceiveMessage(void) {
  17.     CAN_RxHeaderTypeDef RxHeader;
  18.     uint8_t RxData[8];
  19.    
  20.     if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) {
  21.         // 处理接收到的数据
  22.         Process_CAN_Message(RxHeader.StdId, RxData, RxHeader.DLC);
  23.     }
  24. }
3. 主函数
主函数中需启动CAN外设并配置中断:
  1. int main(void) {
  2.     HAL_Init();
  3.     SystemClock_Config();
  4.     CAN_Config();
  5.    
  6.     if (HAL_CAN_Start(&hcan) != HAL_OK) {
  7.         // 启动失败
  8.         Error_Handler();
  9.     }
  10.    
  11.     // 激活中断
  12.     if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
  13.         Error_Handler();
  14.     }
  15.    
  16.     while (1) {
  17.         // 主循环
  18.     }
  19. }
调试与优化
  • 逻辑分析仪调试:借助逻辑分析仪验证CAN总线波形是否正确。
  • 错误处理:关注Error_Handler(),记录CAN错误状态寄存器(ESR)的值以定位问题。
  • 实时调试:使用STM32CubeMonitor监控关键变量,优化性能。

总结STM32G431凭借其丰富的外设和高性能适合实现复杂的CAN总线通信系统。通过本文的代码示例和调试建议,您可以快速上手并完成项目开发。

公羊子丹 发表于 2024-12-16 07:49 | 显示全部楼层
终于找到一篇这么详细的STM32教程,感谢!
周半梅 发表于 2024-12-16 07:50 | 显示全部楼层
代码部分讲得真清楚,新手也能看懂。
帛灿灿 发表于 2024-12-16 07:50 | 显示全部楼层
这篇文章解决了我调CAN总线卡死的问题,大赞!
万图 发表于 2024-12-16 07:50 | 显示全部楼层
波特率的设置讲得很细致,不容易出错。
Wordsworth 发表于 2024-12-16 07:50 | 显示全部楼层
能不能加一段关于CAN错误处理的内容?
Bblythe 发表于 2024-12-16 07:50 | 显示全部楼层
想问一下,STM32G431和F4系列相比,性能差多少?
Pulitzer 发表于 2024-12-16 07:51 | 显示全部楼层
我用TJA1050总是有干扰问题,有什么建议吗?
Uriah 发表于 2024-12-16 07:51 | 显示全部楼层
如果有完整项目代码就更好了!
Clyde011 发表于 2024-12-16 07:51 | 显示全部楼层
HAL库确实方便,但有时候感觉太重了。
是你的乱码 发表于 2024-12-31 00:39 | 显示全部楼层
TM32G431内部内置了CAN控制器,但为了与物理层的电平兼容,需要使用外部CAN收发器。
是你的乱码 发表于 2024-12-31 00:40 | 显示全部楼层
在长距离通信或者噪声较大的环境下,TJA1050相较MCP2551具有更好的抗干扰性能。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

172

主题

6228

帖子

2

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