STM32 HAL库CAN使用队列发送
前言
为了解决STM32CAN同时发送多条数据可能出现丢包的现象,故采取队列形式发送CAN数据;
一、STM32CubeMX配置
1.FreeRTOS新建发送队列
2.创建一个专门CAN出队的任务
二、Keil5
1.定义发送消息结构体
// 定义CAN消息结构体
typedef struct
{
uint32_t id;
uint8_t data[8];
uint8_t len;
uint8_t isExtended; // 标记是否为扩展帧
} CanMessage_t;
2.CAN消息入队
extern osMessageQueueId_t CanTxQueueHandle;
/**
* @brief CAN数据入队
* @param can CAN句柄
* @param id 发送ID
* @param *data 发送数据
* @param len 数据长度
* @param isExtended 数据类型:CAN_ID_EXT CAN_ID_STD
* @retval void
*/
void SendCanMessage(uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtended)
{
CanMessage_t txMessage;
txMessage.id = id;
txMessage.len = len;
txMessage.isExtended = isExtended;
memcpy(txMessage.data, data, len);
osMessageQueuePut(CanTxQueueHandle, &txMessage, NULL, 0);
}
3.CAN消息出队
/**
* @brief CAN2数据出队
* @retval void
*/
CanMessage_t txMessage;
void DeQueueCanMessage(void)
{
if (osMessageQueueGet(CanTxQueueHandle, &txMessage, NULL, 0) == osOK)
{
// 从队列中接收消息
CAN_TxHeaderTypeDef txHeader;
txHeader.ExtId = txMessage.isExtended ? txMessage.id : 0; // 如果是标准帧,则扩展帧ID为0
txHeader.RTR = CAN_RTR_DATA;
txHeader.IDE = txMessage.isExtended ? CAN_ID_EXT : CAN_ID_STD; // 根据isExtended标志设置帧格式
txHeader.DLC = txMessage.len;
txHeader.TransmitGlobalTime = DISABLE;
uint32_t TxMailbox;
while (HAL_CAN_AddTxMessage(&hcan2, &txHeader, txMessage.data, &TxMailbox) != HAL_OK);
// 等待发送成功
while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan2) != 3);
}
}
4.函数声明
// CAN2数据入队
void SendCanMessage(uint32_t id, uint8_t *data, uint8_t len, uint8_t isExtended);
// CAN2数据出队
void DeQueueCanMessage(void);
5.Freertos调用
/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the myTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
/* Infinite loop */
for (;;)
{
/* CAN2发送消息出队 */
DeQueueCanMessage();
osDelay(3);
}
/* USER CODE END StartTask02 */
}
3.CAN发送入队示例
//扩展帧发送
uint8_t CANSendData[8];
SendCanMessage(0x1122220A, CANSendData, 8, CAN_ID_EXT);
//标准帧发送修改最后一个标志位即可