打印
[开发工具]

8位mcu上写一个环形队列,并给出读写操作示例

[复制链接]
245|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
szt1993|  楼主 | 2025-4-25 08:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
8位MCU的具体硬件细节(如中断控制寄存器)可能有所不同,因此以下代码中的中断控制部分需要根据具体的MCU型号进行调整。

//.环形队列实现

#include <stdint.h>
#include <stdbool.h>

#define QUEUE_SIZE 16 // 环形队列大小

typedef struct {
uint8_t buffer[QUEUE_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
volatile uint8_t count;
} CircularQueue;

// 初始化环形队列
void CircularQueue_Init(CircularQueue* queue) {
queue->head = 0;
queue->tail = 0;
queue->count = 0;
}

// 禁用中断(具体实现依赖于MCU)
void DisableInterrupts(void) {
// 假设有一个全局中断使能寄存器EI,写入0禁用中断
__asm("CLI"); // 示例指令,具体需根据MCU文档
}

// 启用中断(具体实现依赖于MCU)
void EnableInterrupts(void) {
// 假设有一个全局中断使能寄存器EI,写入1启用中断
__asm("SEI"); // 示例指令,具体需根据MCU文档
}

// 写入环形队列
bool CircularQueue_Write(CircularQueue* queue, uint8_t data) {
DisableInterrupts();

if (queue->count == QUEUE_SIZE) {
// 队列满
EnableInterrupts();
return false;
}

queue->buffer[queue->tail] = data;
queue->tail = (queue->tail + 1) % QUEUE_SIZE;
queue->count++;

EnableInterrupts();
return true;
}

// 从环形队列读取
bool CircularQueue_Read(CircularQueue* queue, uint8_t* data) {
DisableInterrupts();

if (queue->count == 0) {
// 队列空
EnableInterrupts();
return false;
}

*data = queue->buffer[queue->head];
queue->head = (queue->head + 1) % QUEUE_SIZE;
queue->count--;

EnableInterrupts();
return true;
}

中断和普通调用示例

#include <stdint.h>
#include <stdbool.h>

#define QUEUE_SIZE 16 // 环形队列大小

typedef struct {
uint8_t buffer[QUEUE_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
volatile uint8_t count;
} CircularQueue;

// 初始化环形队列
void CircularQueue_Init(CircularQueue* queue) {
queue->head = 0;
queue->tail = 0;
queue->count = 0;
}

// 禁用中断(具体实现依赖于MCU)
void DisableInterrupts(void) {
// 假设有一个全局中断使能寄存器EI,写入0禁用中断
__asm("CLI"); // 示例指令,具体需根据MCU文档
}

// 启用中断(具体实现依赖于MCU)
void EnableInterrupts(void) {
// 假设有一个全局中断使能寄存器EI,写入1启用中断
__asm("SEI"); // 示例指令,具体需根据MCU文档
}

// 写入环形队列
bool CircularQueue_Write(CircularQueue* queue, uint8_t data) {
DisableInterrupts();

if (queue->count == QUEUE_SIZE) {
// 队列满
EnableInterrupts();
return false;
}

queue->buffer[queue->tail] = data;
queue->tail = (queue->tail + 1) % QUEUE_SIZE;
queue->count++;

EnableInterrupts();
return true;
}

// 从环形队列读取
bool CircularQueue_Read(CircularQueue* queue, uint8_t* data) {
DisableInterrupts();

if (queue->count == 0) {
// 队列空
EnableInterrupts();
return false;
}

*data = queue->buffer[queue->head];
queue->head = (queue->head + 1) % QUEUE_SIZE;
queue->count--;

EnableInterrupts();

return true;
}


#include <avr/interrupt.h> // 假设使用AVR MCU,具体头文件根据MCU型号调整
CircularQueue queue;
// 中断服务程序示例
ISR(TIMER1_COMPA_vect) {
uint8_t data = 0xAB; // 示例数据
if (CircularQueue_Write(&queue, data)) {
// 写入成功
}
}
int main(void) {
// 初始化队列
CircularQueue_Init(&queue);

// 配置定时器中断(具体配置根据MCU型号和需求调整)
// ...

// 使能全局中断
sei(); // AVR MCU的使能全局中断指令

// 主循环
while (1) {
uint8_t data;
if (CircularQueue_Read(&queue, &data)) {
// 处理读取到的数据
}

// 其他任务...
}

return 0;
}

使用特权

评论回复
沙发
beacherblack| | 2025-5-3 22:03 | 只看该作者
8 位 MCU 的内存资源十分宝贵,要根据实际需求精确计算环形队列所需的内存大小。避免分配过大的内存空间造成浪费,同时也要防止分配过小导致队列频繁溢出。

使用特权

评论回复
板凳
updownq| | 2025-5-3 23:18 | 只看该作者
使用uint8_t表示队列中的数据,以节省内存。
使用uint16_t表示指针和计数器,以避免溢出问题。

使用特权

评论回复
地板
ingramward| | 2025-5-4 00:51 | 只看该作者
8位MCU内存资源有限,队列大小需根据实际需求调整,避免过大占用RAM。

使用特权

评论回复
5
yorkbarney| | 2025-5-4 19:49 | 只看该作者
串口接收中断中仅将数据写入环形队列,而非直接处理

使用特权

评论回复
6
yeates333| | 2025-5-6 10:26 | 只看该作者
读操作前检查队列是否为空,避免读取无效数据。

使用特权

评论回复
7
1988020566| | 2025-5-6 12:20 | 只看该作者
支持一次性读写多个元素,减少函数调用次数。

使用特权

评论回复
8
yorkbarney| | 2025-5-6 14:08 | 只看该作者
优先选择占用内存小的数据类型。在 8 位 MCU 中,char类型(通常为 1 字节)是常用的选择,而尽量避免使用int(可能占用 2 字节或更多)等占用空间较大的数据类型,除非确实需要。

使用特权

评论回复
9
wangdezhi| | 2025-5-6 16:58 | 只看该作者
尽量减少不必要的函数调用和条件判断,提高代码执行效率。

使用特权

评论回复
10
fengm| | 2025-5-6 19:02 | 只看该作者
读写指针需通过模运算实现循环              

使用特权

评论回复
11
uiint| | 2025-5-6 21:30 | 只看该作者
代码应尽量避免依赖特定 8 位 MCU 的硬件特性,如特定的寄存器操作、中断向量表等。如果需要使用硬件相关的功能,应进行封装,使代码具有更好的可移植性。

使用特权

评论回复
12
timfordlare| | 2025-5-11 11:07 | 只看该作者
若需动态调整队列大小,需改用指针实现

使用特权

评论回复
13
tabmone| | 2025-5-11 17:06 | 只看该作者
需综合考虑内存限制、数据类型、溢出处理、中断安全等关键因素。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

321

主题

2514

帖子

6

粉丝