DEEPSEEK帮写的STM32消息流函数,直接可用.已经测试
#include "main.h"
#include "MessageBuffer.h"static RingBuffer msgQueue = {0};// 初始化队列
void InitQueue(void) {msgQueue.head = 0;msgQueue.tail = 0;msgQueue.count = 0;
}// 检查队列状态
type_usart_queue_status GetQueueStatus(void) {if (msgQueue.count == 0) {return USART_QUEUE_EMPTY;} else if (msgQueue.count >= (QUEUE_SIZE - MAX_MSG_LEN - sizeof(uint16_t))) {return USART_QUEUE_FULL;}return USART_QUEUE_OK;
}// 中断安全的推送消息到队列
type_usart_queue_status PushMsgData(type_Msg *pMsg) {uint32_t primask;type_usart_queue_status result = USART_QUEUE_ERR;if (pMsg == NULL || pMsg->Length == 0 || pMsg->pData == NULL) {return USART_QUEUE_ERR;}// 检查消息长度是否有效if (pMsg->Length > MAX_MSG_LEN) {return USART_QUEUE_ERR;}// 进入临界区(关闭中断)primask = __get_PRIMASK();__disable_irq();// 检查是否有足够空间if ((QUEUE_SIZE - msgQueue.count) >= (pMsg->Length + sizeof(uint16_t))) {// 写入消息长度(小端格式)msgQueue.buffer[msgQueue.head] = (uint8_t)(pMsg->Length & 0xFF);msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;msgQueue.buffer[msgQueue.head] = (uint8_t)((pMsg->Length >> 8) & 0xFF);msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;// 写入消息数据for (uint16_t i = 0; i < pMsg->Length; i++) {msgQueue.buffer[msgQueue.head] = pMsg->pData[i];msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;}msgQueue.count += (pMsg->Length + sizeof(uint16_t));result = USART_QUEUE_OK;} else {result = USART_QUEUE_FULL;}// 退出临界区(恢复中断状态)__set_PRIMASK(primask);return result;
}// 从队列弹出消息(主程序中使用)
type_usart_queue_status PopMsgData(type_Msg *pMsg) {uint32_t primask;type_usart_queue_status result = USART_QUEUE_ERR;if (pMsg == NULL || pMsg->pData == NULL) {return USART_QUEUE_ERR;}// 进入临界区(关闭中断)primask = __get_PRIMASK();__disable_irq();if (msgQueue.count == 0) {result = USART_QUEUE_EMPTY;} else {// 读取消息长度(小端格式)uint16_t msgLength = msgQueue.buffer[msgQueue.tail];msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;msgLength |= (uint16_t)(msgQueue.buffer[msgQueue.tail] << 8);msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;// 检查消息长度是否有效if (msgLength <= MAX_MSG_LEN) {// 读取消息数据for (uint16_t i = 0; i < msgLength; i++) {pMsg->pData[i] = msgQueue.buffer[msgQueue.tail];msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;}pMsg->Length = msgLength;msgQueue.count -= (msgLength + sizeof(uint16_t));result = USART_QUEUE_OK;} else {// 无效长度,重置队列InitQueue();result = USART_QUEUE_ERR;}}// 退出临界区(恢复中断状态)__set_PRIMASK(primask);return result;
}
#ifndef __MESSAGEBUFFER_H__
#define __MESSAGEBUFFER_H__#define QUEUE_SIZE 1024*3 // 环形队列缓冲区大小
#define MAX_MSG_LEN 1024 // 单条消息最大长度typedef struct {uint16_t Length;uint8_t *pData;
} type_Msg;typedef struct {uint8_t buffer[QUEUE_SIZE];volatile uint16_t head; // 使用volatile确保中断和主程序都能正确访问volatile uint16_t tail;volatile uint16_t count;
} RingBuffer;//typedef enum
//{
// USART_QUEUE_EMPTY = 0,
// USART_QUEUE_FULL = 1,
// USART_QUEUE_OK = 2,
// USART_QUEUE_ERR = 3,
//} type_usart_queue_status;void MessageBufferInitFunc(void);
type_usart_queue_status PopMsgData(type_Msg *pMsg);
type_usart_queue_status PushMsgData(type_Msg *pMsg);#endif
中断压入:
type_Msg RevMsg; //接收消息
RevMsg.Length = counter;
RevMsg.pData = RevBuff;
PushMsgData(&RevMsg);
主程序取出:
if (PopMsgData(&RevMsg) == USART_QUEUE_OK)
{
SendFlag = 1;
SendUartDataFunc(USART1, RevMsg.pData, RevMsg.Length);
}