当前位置: 首页 > backend >正文

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);
    }

http://www.xdnf.cn/news/9990.html

相关文章:

  • PostgreSQL主从同步双机集群创建与配置
  • 使用 Arthas 查看接口方法执行时间
  • 时间序列噪声模型分析软件推荐与使用经验
  • SQL(Database Modifications)
  • 【达梦】达梦数据库使用TypeHandler读取数据库时,将字段中的数据读取为数组
  • UIAbility组件基础
  • Cadence Allegro中设置主画面最小显示间距
  • 江科大UART串口通讯hal库实现
  • 【大模型/MCP】MCP简介
  • 哈希之旅:从使用到底层建设
  • CCPC shandong 2025 G
  • 【数据集】中国日尺度1 km全天候地表温度数据集(2000-2022)
  • 尚硅谷redis7 74-85 redis集群分片之集群是什么
  • 【区间dp】-----例题5【田忌赛马】(暂时只会贪心解法)
  • Chuanpai、Nihongo wa Muzukashii Desu、K-skip Permutation
  • 3340. 检查平衡字符串
  • 【2025文博会现场直击】多图预警
  • One Year~
  • WES(三)——变异检测
  • Pix4d航测软件正射影像生产流程(一)项目创建及快速空三
  • Baklib企业知识激活解决方案
  • MySQL 数据库中的主键、超键、候选键、外键是什么?
  • vue3 driverjs
  • 车载摄像头选型相关
  • 初识JAVA:Java异常种类
  • Blaster - Multiplayer P117-PXXX: 匹配状态
  • 项目使用富文本编辑器发送邮件,邮箱无法预览
  • Parasoft C++Test软件单元测试_常见问题及处理
  • MySQL 8.0中的mysql.ibd文件
  • 深度学习目标检测实战——YOLOv8从入门到部署