97 lines
3.1 KiB
C
97 lines
3.1 KiB
C
/*
|
||
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); /* 运行结束,等待下一次唤醒 */
|
||
}
|
||
} |