This repository has been archived on 2026-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
2025-12-22 17:06:53 +08:00

558 lines
17 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.c
* @brief This file provides code for the configuration
* of the CAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"
/* USER CODE BEGIN 0 */
#include "CToC.h"
#include "GM6020.h"
#include "M2006.h"
#include "M3508.h"
uint8_t CAN_CAN1DeviceNumber = 4; // CAN1总线上设备数量
uint8_t CAN_CAN2DeviceNumber = 2; // CAN2总线上设备数量
uint8_t CAN_DeviceNumber = 6; // CAN总线上设备数量
uint32_t CAN_CAN1IDList[10][2] = {{CAN_GM6020, GM6020_2}, {CAN_M2006, M2006_7}, {CAN_M3508, M3508_1}, {CAN_M3508, M3508_2}, 0}; // CAN1总线上设备ID列表
uint32_t CAN_CAN2IDList[10][2] = {{CAN_GM6020, GM6020_1}, {CAN_RoboMasterC, CToC_MasterID1}, 0}; // CAN2总线上设备ID列表
int8_t CAN_IDSelect = 0; // CAN总线上ID列表选择位
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 3;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
/* CAN2 init function */
void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN2_Init 0 */
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 3;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_10TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_3TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = ENABLE;
hcan2.Init.AutoWakeUp = ENABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
/* USER CODE END CAN2_Init 2 */
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOD_CLK_ENABLE();
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* CAN2 clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB5 ------> CAN2_RX
PB6 ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0|GPIO_PIN_1);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */
/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN2_CLK_DISABLE();
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN2 GPIO Configuration
PB5 ------> CAN2_RX
PB6 ------> CAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5|GPIO_PIN_6);
/* CAN2 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */
/* USER CODE END CAN2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/*
*函数简介:CAN1总线接收报文
*参数说明:报文存储数组
*返回类型:报文ID
*备注:默认8字节标准数据帧
*备注:没有接收到数据,直接退出,返回0
*/
uint32_t CAN_CAN1Receive(uint8_t *Data)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
return 0; // 没有接收到数据,直接退出
}
// 复制接收到的数据
for (uint8_t i = 0; i < 8; i++)
{
Data[i] = RxData[i];
}
return RxHeader.StdId; // 返回标准ID
}
/*
*函数简介:CAN2总线接收报文
*参数说明:报文存储数组
*返回类型:报文ID
*备注:默认8字节数据
*备注:没有接收到数据,直接退出,返回0
*/
uint32_t CAN_CAN2Receive(uint8_t *Data)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
if (HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO1, &RxHeader, RxData) != HAL_OK)
{
return 0;
}
for (uint8_t i = 0; i < 8; i++)
{
Data[i] = RxData[i];
}
return RxHeader.StdId;
}
/*
*函数简介:CAN1总线更改接收ID
*参数说明:接收ID
*返回类型:无
*备注:无
*/
void CAN_CAN1ChangeID(uint32_t ID)
{
// CAN_FilterTypeDef sFilterConfig;
// // 配置过滤器
// sFilterConfig.FilterBank = 0; // 使用过滤器0
// sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
// sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位过滤器
// // ID配置标准ID左移5位
// sFilterConfig.FilterIdHigh = (ID << 5) >> 16; // ID高16位
// sFilterConfig.FilterIdLow = (ID << 5) & 0xFFFF; // ID低16位
// // 掩码配置0xFFE3直接赋值
// sFilterConfig.FilterMaskIdHigh = 0xFFE3; // 掩码高16位
// sFilterConfig.FilterMaskIdLow = 0xFFE3; // 掩码低16位
// sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 分配到FIFO0
// sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
// sFilterConfig.SlaveStartFilterBank = 14; // 从CAN2开始使用的过滤器编号
CAN_FilterTypeDef sFilterConfig;
// 配置过滤器
sFilterConfig.FilterBank = 0; // 使用过滤器0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位过滤器
// ID配置标准ID左移5位
sFilterConfig.FilterIdHigh = (ID << 5) >> 16; // ID高16位
sFilterConfig.FilterIdLow = (ID << 5) & 0xFFFF; // ID低16位
// 掩码配置0xFFE3直接赋值
sFilterConfig.FilterMaskIdHigh = 0xFFE3; // 掩码高16位-
sFilterConfig.FilterMaskIdLow = 0xFFE3; // 掩码低16位
// 配置过滤器(使用 16-bit scale保持与原寄存器行为一致
sFilterConfig.FilterBank = 0; // 使用过滤器0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; // 16位过滤器与原实现一致
// 16-bit 尺度下,把 (ID << 5) 放入 16 位字段
sFilterConfig.FilterIdHigh = (uint16_t)((ID << 5) & 0xFFFF);
sFilterConfig.FilterIdLow = (uint16_t)((ID << 5) & 0xFFFF);
// 掩码配置16 位尺度下放到相应字段)
sFilterConfig.FilterMaskIdHigh = 0xFFE3;
sFilterConfig.FilterMaskIdLow = 0xFFE3;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; // 分配到FIFO0
sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
sFilterConfig.SlaveStartFilterBank = 14; // 从CAN2开始使用的过滤器编号
// 配置过滤器
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*
*函数简介:CAN2总线更改接收ID
*参数说明:接收ID
*返回类型:无
*备注:无
*/
void CAN_CAN2ChangeID(uint32_t ID)
{
CAN_FilterTypeDef sFilterConfig;
// 配置过滤器(使用 16-bit scale
sFilterConfig.FilterBank = 15; // 使用过滤器15 (CAN2 区域)
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT; // 16位过滤器
sFilterConfig.FilterIdHigh = (uint16_t)((ID << 5) & 0xFFFF);
sFilterConfig.FilterIdLow = (uint16_t)((ID << 5) & 0xFFFF);
sFilterConfig.FilterMaskIdHigh = 0xFFE3;
sFilterConfig.FilterMaskIdLow = 0xFFE3;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1; // 分配到FIFO1
sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
sFilterConfig.SlaveStartFilterBank = 14; // 从CAN2开始使用的过滤器编号
// CAN_FilterTypeDef sFilterConfig;
// // 配置过滤器
// sFilterConfig.FilterBank = 15; // 使用过滤器15
// sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 掩码模式
// sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // 32位过滤器
// // ID配置标准ID左移5位
// sFilterConfig.FilterIdHigh = (ID << 5) >> 16; // ID高16位
// sFilterConfig.FilterIdLow = (ID << 5) & 0xFFFF; // ID低16位
// // 掩码配置0xFFE3直接赋值
// sFilterConfig.FilterMaskIdHigh = 0xFFE3; // 掩码高16位
// sFilterConfig.FilterMaskIdLow = 0xFFE3; // 掩码低16位
// sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1; // 分配到FIFO1
// sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
// sFilterConfig.SlaveStartFilterBank = 14; // 从CAN2开始使用的过滤器编号
// 配置过滤器
if (HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
/*
*函数简介:CAN接收ID列表复位
*参数说明:无
*返回类型:无
*备注:复位CAN_IDSelect,重新从CAN1的1号设备开始接收
*/
void CAN_CANIDReset(void)
{
CAN_IDSelect = 0;
CAN_CAN1ChangeID(CAN_CAN1IDList[0][1]);
CAN_CAN2ChangeID(0x000);
}
/*
*函数简介:CAN接收获取裁判系统状态
*参数说明:无
*返回类型:无
*备注:跳转到接收底盘C板的回传数据,主要用于发射机构掉电时的CAN设备隔离
*/
void CAN_CAN_GetRefereeSystemData(void)
{
CAN_IDSelect = 5;
CAN_CAN1ChangeID(0x000);
CAN_CAN2ChangeID(CAN_CAN2IDList[1][1]);
}
/*
*函数简介:CAN1_FIFO0接收中断函数
*参数说明:无
*返回类型:无
*备注:进入中断时关闭连接检测计时,离开中断时重新打开连接检测计时
*备注:某一设备掉线时,CAN_IDSelect会停留在当前设备在ID列表的索引
*备注:从掉线到重新连接时会重启遥控器
*/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if (hcan->Instance == CAN1)
{
uint8_t Data[8];
uint32_t ID = CAN_CAN1Receive(Data);
// 暂时注释掉连接检测相关功能
/*
LinkCheck_OFF();
if(LinkCheck_ErrorID >= 0 && LinkCheck_ErrorID < CAN_CAN1DeviceNumber)
{
if(ID == CAN_CAN1IDList[LinkCheck_ErrorID][1])
{
LinkCheck_ErrorID = -1;
LinkCheck_Error = 0;
Warming_BuzzerClean();
}
}
*/
// if(CAN_CAN1IDList[CAN_IDSelect][0] == CAN_M3508)
// M3508_CANDataProcess(ID, Data);
// else if(CAN_CAN1IDList[CAN_IDSelect][0] == CAN_M2006)
// M2006_CANDataProcess(ID, Data);
// else
// GM6020_CANDataProcess(ID, Data);
// 保留ID切换逻辑
CAN_IDSelect = (CAN_IDSelect + 1) % CAN_DeviceNumber;
if (CAN_IDSelect >= 0 && CAN_IDSelect < CAN_CAN1DeviceNumber)
{
CAN_CAN1ChangeID(CAN_CAN1IDList[CAN_IDSelect][1]);
CAN_CAN2ChangeID(0x000);
}
else
{
CAN_CAN1ChangeID(0x000);
CAN_CAN2ChangeID(CAN_CAN2IDList[CAN_IDSelect - CAN_CAN1DeviceNumber][1]);
}
// 暂时注释掉发射机构相关功能
/*
if(RefereeSystem_ShooterOpenFlag == 1)
{
RefereeSystem_ShooterOpenCounter++;
if(RefereeSystem_ShooterOpenCounter >= 5000)
{
RefereeSystem_ShooterOpenCounter = 0;
RefereeSystem_ShooterOpenFlag = 0;
CAN_CAN1DeviceNumber = 4;
CAN_DeviceNumber = 6;
}
}
*/
// 暂时注释掉连接检测
// LinkCheck_ON();
}
}
/*
*函数简介:CAN2_FIFO1接收中断函数
*参数说明:无
*返回类型:无
*备注:进入中断时关闭连接检测计时,离开中断时重新打开连接检测计时
*备注:某一设备掉线时,CAN_IDSelect会停留在当前设备在ID列表的索引
*/
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
if (hcan->Instance == CAN2)
{
uint8_t Data[8];
uint32_t ID = CAN_CAN2Receive(Data);
// 暂时注释掉连接检测相关功能
/*
LinkCheck_OFF();
if(LinkCheck_ErrorID >= CAN_CAN1DeviceNumber && LinkCheck_ErrorID < CAN_DeviceNumber)
{
if(ID == CAN_CAN2IDList[LinkCheck_ErrorID-CAN_CAN1DeviceNumber][1])
{
LinkCheck_ErrorID = -1;
LinkCheck_Error = 0;
Warming_BuzzerClean();
}
}
*/
// if(CAN_CAN2IDList[CAN_IDSelect-CAN_CAN1DeviceNumber][0] == CAN_GM6020)
// GM6020_CANDataProcess(ID, Data);
// else
if(CAN_CAN2IDList[CAN_IDSelect-CAN_CAN1DeviceNumber][0] == CAN_RoboMasterC){
CToC_CANDataProcess(ID, Data);
}
// 保留ID切换逻辑
CAN_IDSelect = (CAN_IDSelect + 1) % CAN_DeviceNumber;
if (CAN_IDSelect >= 0 && CAN_IDSelect < CAN_CAN1DeviceNumber)
{
CAN_CAN1ChangeID(CAN_CAN1IDList[CAN_IDSelect][1]);
CAN_CAN2ChangeID(0x000);
}
else
{
CAN_CAN1ChangeID(0x000);
CAN_CAN2ChangeID(CAN_CAN2IDList[CAN_IDSelect - CAN_CAN1DeviceNumber][1]);
}
// 暂时注释掉发射机构相关功能
/*
if(RefereeSystem_ShooterOpenFlag == 1)
{
RefereeSystem_ShooterOpenCounter++;
if(RefereeSystem_ShooterOpenCounter >= 5000)
{
RefereeSystem_ShooterOpenCounter = 0;
RefereeSystem_ShooterOpenFlag = 0;
CAN_CAN1DeviceNumber = 4;
CAN_DeviceNumber = 6;
}
}
*/
// 暂时注释掉连接检测
// LinkCheck_ON();
}
}
/* USER CODE END 1 */