STM32G431 是 STMicroelectronics 推出的一款高性能微控制器,基于 ARM Cortex-M4 内核,特别适合工业控制和嵌入式应用。本篇文章将以 STM32G431 为例,详细介绍如何利用 CAN 总线实现从设备通信功能。我们将覆盖硬件配置、固件开发及调试的完整流程,最后提供一段完整的代码示例。
STM32G431 的特点与优势STM32G431 提供丰富的外设和功能:
- 性能优越:170 MHz 主频,内置浮点运算单元 (FPU)。
- 集成 CAN 总线控制器:支持 CAN FD,适合高效通信。
- 丰富的外设接口:UART、SPI、I2C 等,可轻松扩展外设。
对于需要多设备间实时通信的项目,STM32G431 的 CAN 模块是一个非常适合的选择。
硬件连接为了实现从设备的 CAN 通信,需要以下硬件配置:
- MCU 核心板:STM32G431 芯片最小系统板。
- CAN 收发器:例如 MCP2551。
- 总线连接:120 Ω 终端电阻,保证信号稳定。
典型硬件连接图如下:
- STM32G431 的 CAN_TX 和 CAN_RX 分别连接到收发器的 TXD 和 RXD。
- 收发器的 CANH 和 CANL 连接到 CAN 总线。
软件开发使用的开发工具- IDE:STM32CubeIDE
- 配置工具:STM32CubeMX
实现步骤- CAN 模块初始化
使用 STM32CubeMX 配置 CAN 接口,选择相应的 GPIO 和波特率(例如 500 kbps)。
- 编写从设备代码
- 配置 CAN 接口接收过滤器。
- 实现 CAN 消息的接收和处理。
- 响应主机指令并发送状态。
- 调试与验证
利用 USB-CAN 调试工具,验证从设备是否正确接收并响应 CAN 消息。
示例代码以下是一个完整的从设备通信实现代码示例:
#include "main.h"
CAN_HandleTypeDef hcan;
CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];
uint8_t txData[8];
CAN_TxHeaderTypeDef txHeader;
uint32_t txMailbox;
// 初始化 CAN
void CAN_Init(void) {
hcan.Instance = CAN1;
hcan.Init.Prescaler = 6;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoRetransmission = ENABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK) {
Error_Handler();
}
}
// 配置过滤器
void CAN_Filter_Config(void) {
CAN_FilterTypeDef filterConfig;
filterConfig.FilterBank = 0;
filterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
filterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
filterConfig.FilterIdHigh = 0x0000;
filterConfig.FilterIdLow = 0x0000;
filterConfig.FilterMaskIdHigh = 0x0000;
filterConfig.FilterMaskIdLow = 0x0000;
filterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filterConfig.FilterActivation = ENABLE;
filterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan, &filterConfig) != HAL_OK) {
Error_Handler();
}
}
// 发送 CAN 消息
void CAN_Send_Message(uint32_t id, uint8_t *data, uint8_t len) {
txHeader.StdId = id;
txHeader.ExtId = 0x01;
txHeader.IDE = CAN_ID_STD;
txHeader.RTR = CAN_RTR_DATA;
txHeader.DLC = len;
if (HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &txMailbox) != HAL_OK) {
Error_Handler();
}
}
// 主循环接收并处理数据
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData);
// 解析收到的消息并发送响应
if (rxHeader.StdId == 0x123) {
txData[0] = 0xAB; // 示例状态
CAN_Send_Message(0x124, txData, 1);
}
}
int main(void) {
HAL_Init();
SystemClock_Config();
CAN_Init();
CAN_Filter_Config();
// 启动 CAN
if (HAL_CAN_Start(&hcan) != HAL_OK) {
Error_Handler();
}
// 激活中断
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
Error_Handler();
}
while (1) {
// 主循环处理逻辑
}
}
总结本文介绍了 STM32G431 的 CAN 总线配置和从设备通信实现。通过配置过滤器和中断回调,实现了主从通信的基本功能。这套方案在实际应用中具有广泛的扩展性,适合需要高效、多设备协作的嵌入式项目。
如果你对 STM32G431 或 CAN 总线有更多的兴趣,可以继续深入研究 CAN FD 的应用或结合 RTOS 实现更复杂的系统功能。
|