[STM32G4] 探索STM32G431:CAN通信和GPIO控制的实现

[复制链接]
1774|10
 楼主| Uriah 发表于 2024-11-24 07:42 | 显示全部楼层 |阅读模式
STM32G431是ST公司推出的一款高性能微控制器,凭借其强大的性能、丰富的外设和较低的功耗,在工业控制、通信和电机控制领域备受欢迎。本篇文章将基于STM32G431,带大家实现以下两个功能:
  • 配置CAN接口,用于主从通信;
  • 配置GPIO,实现基本的LED控制功能。
硬件与软件准备
  • 硬件

    • STM32G431开发板
    • CAN收发器模块(如MCP2551或TJA1050)
    • LED和适配电阻
    • PC,用于通过CAN调试工具与MCU通信
  • 软件

    • STM32CubeMX:用于生成初始代码
    • Keil或STM32CubeIDE:用于编写和调试程序

CAN通信配置与实现配置步骤
  • 打开STM3总结本文基于STM32G431的CAN通信和GPIO控制功能进行了演示。从基础配置到代码实现,我们一步步探索了如何让STM32G431成为高效的嵌入式开发工具。希望本文对你的开发有所帮助!2CubeMX,选择STM32G431的芯片型号。
  • 在引脚图中,将CAN接口(FDCAN1)启用。
  • 配置CAN的波特率,比如500 kbps,同时开启接收和发送功能。
  • 生成代码,并使用CubeIDE导入。
代码实现以下代码实现了一个简单的CAN接收和发送功能:
  1. #include "main.h"

  2. // CAN消息接收/发送定义
  3. FDCAN_HandleTypeDef hfdcan1;
  4. FDCAN_RxHeaderTypeDef RxHeader;
  5. FDCAN_TxHeaderTypeDef TxHeader;
  6. uint8_t RxData[8];
  7. uint8_t TxData[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};

  8. void SystemClock_Config(void);
  9. static void MX_GPIO_Init(void);
  10. static void MX_FDCAN1_Init(void);

  11. int main(void) {
  12.     HAL_Init();
  13.     SystemClock_Config();
  14.     MX_GPIO_Init();
  15.     MX_FDCAN1_Init();

  16.     // 配置CAN
  17.     if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK) {
  18.         Error_Handler();
  19.     }

  20.     if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) {
  21.         Error_Handler();
  22.     }

  23.     // 配置发送消息的头部
  24.     TxHeader.Identifier = 0x123;
  25.     TxHeader.IdType = FDCAN_STANDARD_ID;
  26.     TxHeader.TxFrameType = FDCAN_DATA_FRAME;
  27.     TxHeader.DataLength = FDCAN_DLC_BYTES_8;
  28.     TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
  29.     TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
  30.     TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
  31.     TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;

  32.     while (1) {
  33.         // 发送CAN消息
  34.         if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK) {
  35.             Error_Handler();
  36.         }
  37.         HAL_Delay(1000);
  38.     }
  39. }

  40. // CAN中断回调函数
  41. void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
  42.     if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0) {
  43.         HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData);
  44.         // 简单打印接收到的数据
  45.         printf("Received Data: ");
  46.         for (int i = 0; i < 8; i++) {
  47.             printf("%02X ", RxData[i]);
  48.         }
  49.         printf("\n");
  50.     }
  51. }

  52. static void MX_FDCAN1_Init(void) {
  53.     hfdcan1.Instance = FDCAN1;
  54.     hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
  55.     hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
  56.     hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
  57.     hfdcan1.Init.AutoRetransmission = ENABLE;
  58.     hfdcan1.Init.TransmitPause = DISABLE;
  59.     hfdcan1.Init.ProtocolException = DISABLE;
  60.     hfdcan1.Init.NominalPrescaler = 5;
  61.     hfdcan1.Init.NominalSyncJumpWidth = 1;
  62.     hfdcan1.Init.NominalTimeSeg1 = 13;
  63.     hfdcan1.Init.NominalTimeSeg2 = 2;
  64.     if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) {
  65.         Error_Handler();
  66.     }
  67. }
GPIO控制LED实现配置步骤
  • 在STM32CubeMX中将对应引脚配置为GPIO_Output模式,用于控制LED。
  • 生成代码,初始化GPIO。
代码实现
  1. static void MX_GPIO_Init(void) {
  2.     GPIO_InitTypeDef GPIO_InitStruct = {0};

  3.     // GPIO时钟使能
  4.     __HAL_RCC_GPIOA_CLK_ENABLE();

  5.     // 配置引脚PA5为输出模式
  6.     GPIO_InitStruct.Pin = GPIO_PIN_5;
  7.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  8.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  9.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  10.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  11. }

  12. int main(void) {
  13.     HAL_Init();
  14.     SystemClock_Config();
  15.     MX_GPIO_Init();

  16.     while (1) {
  17.         // 点亮LED
  18.         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
  19.         HAL_Delay(500);

  20.         // 熄灭LED
  21.         HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
  22.         HAL_Delay(500);
  23.     }
  24. }


公羊子丹 发表于 2024-11-24 07:43 来自手机 | 显示全部楼层
哇,这个代码好清晰,刚好我最近也在研究CAN通信,太及时了!
周半梅 发表于 2024-11-24 07:44 来自手机 | 显示全部楼层
感谢分享,我用的是STM32F407,改改应该也能用!
帛灿灿 发表于 2024-11-24 07:44 来自手机 | 显示全部楼层
写得很详细,尤其是初始化部分,受教了!
童雨竹 发表于 2024-11-24 07:44 来自手机 | 显示全部楼层
之前一直觉得STM32的CAN挺难的,看了你的文章好像也不复杂嘛。
万图 发表于 2024-11-24 07:44 来自手机 | 显示全部楼层
GPIO那部分太基础了,不过对新手还是很友好的!
Wordsworth 发表于 2024-11-24 07:44 来自手机 | 显示全部楼层
有没有多控制器协同的代码示例?想看看更复杂点的应用。
Pulitzer 发表于 2024-11-24 07:45 来自手机 | 显示全部楼层
用STM32CubeIDE的话调试方便多了,强推!
Bblythe 发表于 2024-11-24 07:45 来自手机 | 显示全部楼层
期待你下一篇文章,能不能讲讲UART和CAN混合使用?
Clyde011 发表于 2024-11-24 07:45 来自手机 | 显示全部楼层
这个LED闪烁可以加点花样,比如调光或者多LED控制。
无名无 发表于 2024-11-26 14:55 | 显示全部楼层
CAN不需要配置过滤器吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

158

主题

6208

帖子

1

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