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

[8-2-2] 队列实验_多设备玩游戏(红外改造)_重录

[8-2-2] 队列实验_多设备玩游戏(红外改造)_重录

在这节课程中,我们将通过改造之前的程序,引入队列来优化多设备交互的游戏体验。之前的程序使用的是环形缓冲区,这种方式CPU资源利用率较低。我们将通过引入队列,改进数据传输的效率,并提高音乐播放和游戏控制的流畅度。接下来,我将带你逐步实现这个改进,讲解每个步骤的原理和改动。

1. 初始程序的分析

首先,我们回顾一下之前的程序框架。原程序的结构如下:

  • 球的链路:控制球的运动和与墙壁、挡板的碰撞。
  • 挡球板的链路:通过读取红外遥控器的按键,控制挡球板的左右移动。

1.1 使用环形缓冲区的问题

在原程序中,挡球板的控制链路是通过环形缓冲区来读取红外遥控器的数据。当读取不到数据时,它会一直循环等待,这导致了CPU的资源被浪费,从而影响了系统的响应时间,尤其是导致音乐播放卡顿。

2. 引入队列进行改造

我们决定将环形缓冲区替换为队列,这样可以解决CPU资源浪费的问题,并提高数据传输效率。队列不仅提供了阻塞和唤醒机制,还能够有效地管理任务间的数据传输。

2.1 队列的使用

我们将通过以下步骤改造程序:

  1. 创建队列:在程序中创建队列来替代环形缓冲区。
  2. 中断中写队列:在红外遥控器的中断服务程序中,将数据写入队列。
  3. 任务读取队列:挡球板的链路将从队列中读取数据,来控制挡球板的移动。

2.2 队列创建与操作

使用队列的基本步骤如下:

  • 创建队列:我们首先需要创建一个队列来存放数据。
  • 写入队列:在红外遥控器的中断服务程序中,将数据写入队列。
  • 读取队列:在挡球板的任务链路中读取队列数据,来控制挡球板的移动。
xQueueHandle queue;
queue = xQueueCreate(10, sizeof(int));  // 创建队列,最多存10个数据

// 向队列写入数据
int data = 1;
xQueueSend(queue, &data, portMAX_DELAY);

// 从队列读取数据
int receivedData;
xQueueReceive(queue, &receivedData, portMAX_DELAY);

3. 改造红外遥控器和旋转编码器的输入

3.1 红外遥控器的数据传输

在原程序中,红外遥控器的数据是通过环形缓冲区传递的。我们将其改为通过队列传递数据。在中断服务程序中解析出数据后,直接写入队列。

// 红外中断服务程序
void IR_ISR() {
    int data = read_ir_data();
    xQueueSend(queue, &data, portMAX_DELAY);  // 写入队列
}

3.2 旋转编码器的数据传输

为了进一步优化,我们还引入了旋转编码器。旋转编码器能够提供更高效的输入,减少响应延迟。旋转编码器的数据将通过另一个队列传递,避免与红外遥控器的数据冲突。

// 旋转编码器中断服务程序
void Encoder_ISR() {
    int speed = read_encoder_speed();
    xQueueSend(encoderQueue, &speed, portMAX_DELAY);  // 写入队列
}

3.3 任务读取旋转编码器的数据

为了实现更流畅的挡球板控制,我们将根据旋转编码器的速度来调整挡球板的移动。如果旋转速度快,我们将写入多个数据以增加挡球板的移动速度。

// 任务读取旋转编码器的数据并调整挡球板位置
void adjust_paddle_position() {
    int speed;
    if (xQueueReceive(encoderQueue, &speed, portMAX_DELAY)) {
        if (speed > THRESHOLD) {
            // 快速旋转,增加移动幅度
            move_paddle(speed);
        } else {
            // 慢速旋转,移动幅度小
            move_paddle(speed / 2);
        }
    }
}

4. 队列的改进:阻塞与唤醒机制

通过使用队列,我们能够提高系统的响应效率。队列的阻塞机制保证了当没有数据可读取时,任务会被阻塞,避免了不必要的CPU消耗。队列的唤醒机制确保了当数据可用时,阻塞的任务会被唤醒,继续执行。

4.1 队列阻塞与唤醒

  • 阻塞:当队列为空时,任务会被阻塞,等待数据的到来。
  • 唤醒:当队列有新数据时,任务会被唤醒并继续执行。

5. 最终效果:更流畅的游戏控制

通过改造后,队列的使用不仅提高了系统的效率,还使得游戏体验更加流畅。通过旋转编码器,我们减少了红外遥控器输入的延迟,使得挡球板的控制更加精确和快速。队列的阻塞与唤醒机制也确保了CPU的高效利用。

5.1 流畅的音乐播放与游戏控制

在程序改进后,音乐播放不再受到影响,同时也能顺利控制挡球板。每当我们按下红外遥控器的按钮或旋转编码器时,系统都会快速响应,控制挡球板的移动,而不会卡顿。

6. 总结

通过这次队列实验,我们成功地优化了原有的程序,使用队列替代了环形缓冲区,不仅提升了数据传输的效率,还改进了系统的响应时间。通过引入旋转编码器,我们进一步提高了挡球板控制的精度和流畅度。

希望通过这篇博客,你能够理解队列在多设备协作中的应用,并掌握如何利用队列优化任务间的数据传输。通过这些技巧,你可以为其他实时任务和多设备系统提供更高效的解决方案。


这篇博客详细介绍了队列的改造过程,并展示了如何通过队列优化游戏控制和音乐播放。希望你能够将这些概念应用到实际开发中,提升你在多任务和多设备环境下的编程能力。

相关文章:

  • IWC万国表:源自瑞士的精密制表艺术(中英双语)
  • 第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式
  • skywalking实现原理
  • unity学习39:连续动作之间的切换,用按键控制角色的移动
  • 编程技巧(基于STM32)第一章 定时器实现非阻塞式程序——按键控制LED灯闪烁模式
  • Spring Boot 定时任务:轻松实现任务自动化
  • PyQt6/PySide6 的信号与槽原理
  • YOLOv5-Seg 深度解析:与 YOLOv5 检测模型的区别
  • 四元数如何用于 3D 旋转(代替欧拉角和旋转矩阵)【ESP32指向鼠标】
  • 基于Python的Optimal Interpolation (OI) 方法实现
  • ZZNUOJ(C/C++)基础练习1091——1100(详解版)⭐
  • 差分解方程
  • [矩形绘制]
  • 图的遍历: 广度优先遍历和深度优先遍历
  • FPGA的星辰大海
  • Windows环境下使用Ollama搭建本地AI大模型教程
  • MAC 系统关闭屏幕/睡眠 后被唤醒 Wake Requests
  • spring针对抽象类注入属性
  • 6.2.1 数据模型的基本概念、数据模型三要素
  • Linux alias使用
  • 前四个月社会融资规模增量累计为16.34万亿元,比上年同期多3.61万亿元
  • 上海北外滩,未来五年将如何“长个子”“壮筋骨”?
  • 王毅谈中拉论坛十年成果
  • 印称印巴军事行动总指挥同意将局势降级
  • 男子退机票被收票价90%的手续费,律师:虽然合规,但显失公平
  • 新华时评:中美经贸会谈为全球经济纾压增信