1. 硬件连接
确保 STM32F103C8T6 的 CAN 接口与 PEAK 设备(如 PCAN-USB)正确连接:
CAN_TX (PA12) → 连接到 PEAK 设备的 CAN_H
CAN_RX (PA11) → 连接到 PEAK 设备的 CAN_L
共地:STM32 和 PEAK 设备必须共地(GND 连接)。
终端电阻:CAN 总线两端需接 120Ω 终端电阻(如果 PEAK 设备已提供,则无需额外添加)。
2. STM32CubeMX 配置
使用 STM32CubeMX 初始化 CAN 接口:
CAN 配置:
Mode: Normal(标准模式)
Prescaler: 6(APB1 = 36MHz → CAN 时钟 = 36MHz / 6 = 6Mbps,但实际建议 500kbps 或 1Mbps)
Time Quanta (BS1 + BS2):
BS1: 8TQ
BS2: 7TQ
Sync Jump Width: 1TQ
Bit Rate: 500kbps(或 1Mbps,需与 BusMaster 配置一致)
Filters:
Bank 0: Mask Mode(接收所有 ID 或过滤特定 ID)
Filter ID: 0x000(默认接收所有)
Mask ID: 0x000(允许所有 ID 通过)
NVIC 配置:
启用 CAN RX0 中断(USBD_CAN_RX0_IRQn)。
生成代码:
使用 STM32CubeIDE 生成项目。
3. 示例代码
(1) 初始化 CAN
在 main.c 中初始化 CAN:
c
#include "stm32f1xx_hal.h"
CAN_HandleTypeDef hcan;
void CAN_Init(void) {
CAN_FilterTypeDef filter;
hcan.Instance = CAN1;
hcan.Init.Prescaler = 6; // 36MHz / 6 = 6Mbps (调整至 500kbps 或 1Mbps)
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_8TQ;
hcan.Init.TimeSeg2 = CAN_BS2_7TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = ENABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK) {
Error_Handler();
}
// 配置 CAN 过滤器(接收所有 ID)
filter.FilterBank = 0;
filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_32BIT;
filter.FilterIdHigh = 0x0000;
filter.FilterIdLow = 0x0000;
filter.FilterMaskIdHigh = 0x0000;
filter.FilterMaskIdLow = 0x0000;
filter.FilterFIFOAssignment = CAN_RX_FIFO0;
filter.FilterActivation = ENABLE;
if (HAL_CAN_ConfigFilter(&hcan, &filter) != HAL_OK) {
Error_Handler();
}
// 启动 CAN
if (HAL_CAN_Start(&hcan) != HAL_OK) {
Error_Handler();
}
// 启用 CAN RX 中断
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
Error_Handler();
}
}
(2) 发送 CAN 数据
c
void CAN_SendMessage(uint32_t id, uint8_t* data, uint8_t len) {
CAN_TxHeaderTypeDef txHeader;
uint32_t mailbox;
txHeader.StdId = id; // 标准 ID (11-bit)
txHeader.ExtId = 0; // 扩展 ID (未使用)
txHeader.RTR = CAN_RTR_DATA; // 数据帧
txHeader.IDE = CAN_ID_STD; // 标准 ID
txHeader.DLC = len; // 数据长度 (0-8)
txHeader.TransmitGlobalTime = DISABLE;
if (HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &mailbox) != HAL_OK) {
Error_Handler();
}
}
(3) 接收 CAN 数据(中断回调)
在 stm32f1xx_it.c 中实现中断回调:
c
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK) {
// 处理接收到的数据
// rxHeader.StdId: 接收到的 CAN ID
// rxData: 接收到的数据 (0-8 字节)
// rxHeader.DLC: 数据长度
}
}
(4) 主函数调用
c
int main(void) {
HAL_Init();
SystemClock_Config();
CAN_Init();
uint8_t testData[] = {0x11, 0x22, 0x33, 0x44};
while (1) {
CAN_SendMessage(0x123, testData, 4); // 发送 CAN 帧 (ID=0x123)
HAL_Delay(1000);
}
}
4. BusMaster 配置
打开 BusMaster,选择 CAN → Database → Channel Configuration。
设置 CAN 通道:
Channel: CAN1
Baud Rate: 500kbps(与 STM32 配置一致)
Controller Mode: Normal
发送测试数据:
使用 BusMaster 的 "Send" 窗口,发送一个标准帧(ID=0x123,数据=0x11 0x22 0x33 0x44)。
监控接收:
在 BusMaster 的 "Log" 窗口 查看是否收到 STM32 的回复。 |
|