/* CAN总线数据处理 仅发送模式,创建结构体存储发送数据及调试信息。 */ /* Includes ----------------------------------------------------------------- */ #include "can.h" #include "task\user_task.h" #include "bsp\led.h" /* Private typedef ---------------------------------------------------------- */ typedef struct { uint8_t TxData[8]; // 要发送的数据 uint16_t TxID; // 发送的CAN ID uint8_t TxStatus; // 发送状态,0: 成功,1: 失败 uint32_t DebugCounter; // 调试计数器 } can_t; /* Private define ----------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */ can_t can_debug = { .TxData = {0}, .TxID = 0x023, .TxStatus = 0, .DebugCounter = 0 }; /* Exported functions ------------------------------------------------------- */ void CAN_Init(CAN_HandleTypeDef *hcan_Cur) { // 仅初始化CAN,不配置接收过滤器 HAL_CAN_Start(hcan_Cur); // 开启CAN } /* CAN发送函数 */ uint8_t CAN_SendData(CAN_HandleTypeDef *hcan_Cur, uint8_t *pData, uint16_t ID) { HAL_StatusTypeDef HAL_RetVal = HAL_ERROR; uint8_t FreeTxNum = 0; CAN_TxHeaderTypeDef TxMessage; TxMessage.StdId = ID; TxMessage.DLC = 8; /* 默认一帧传输长度为8 */ TxMessage.IDE = CAN_ID_STD; TxMessage.RTR = CAN_RTR_DATA; FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcan_Cur); while (FreeTxNum == 0) // 等待空邮箱,可能会卡死在这里(小BUG) { FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcan_Cur); } HAL_RetVal = HAL_CAN_AddTxMessage(hcan_Cur, &TxMessage, pData, (uint32_t *)CAN_TX_MAILBOX1); if (HAL_RetVal != HAL_OK) { return 1; // 发送失败 } return 0; // 发送成功 } void Task_Can(void *argument) { (void)argument; // 消除未使用参数的警告 const uint32_t delay_tick = osKernelGetTickFreq() / 100; // 50Hz uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */ CAN_Init(&hcan); // 初始化CAN模块 uint16_t adc_data = 0; // 用于存储从消息队列读取的 ADC 数据 // 初始化调试结构体数据 for (int i = 0; i < 8; i++) { can_debug.TxData[i] = 0; // 填充测试数据 } while (1) { tick += delay_tick; /* 计算下一个唤醒时刻 */ // 周期性发送数据 if (osMessageQueueGet(adcQueueHandle, &adc_data, NULL, osWaitForever) == osOK) { // 将 ADC 数据填充到 CAN 数据帧 can_debug.TxData[0] = (adc_data >> 8) & 0xFF; // 高字节 can_debug.TxData[1] = adc_data & 0xFF; // 低字节 // 发送 CAN 数据 can_debug.TxStatus = CAN_SendData(&hcan, can_debug.TxData, can_debug.TxID); can_debug.DebugCounter++; // 调试计数器递增 } //每发送10条数据切换一次LED状态 if (can_debug.DebugCounter % 10 == 0) { BSP_LED_SET(BSP_LED2, BSP_LED_TAGGLE); // 切换 LED 状态 } osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */ } }