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

单片机实现分页显示环形更新的历史数据

就是在EEPROM 或者FLASH 里采用类似环形缓冲区的结构来存储历史数据,如果数据总数超过了总容量,就用最新数据覆盖最旧的数据。然后把历史数据按从新到旧的顺序分页显示在屏幕上。

环形缓冲

需要记录当前写入的数据总数和写入位置:

  • 如果写入量超过了总的存储容量,则数据总数不再增加,所以数据总数最大等于存储容量;
  • 新的数据总是写入到当前写入位置,然后让写入位置自增;
  • 当写入量超过总容量时,写入位置归零,重新从开头写,从而覆盖旧数据,形成回环;
  • 最新的数据位于当前写入位置前一个;

下面不讨论用环形缓冲记录历史数据具体怎么实现,只考虑显示数据。

分页显示

第一页的第一个数据是当前写入位置的前一个,后面的数据读取位置依次递减,和写入位置的递增刚好相反,如果减到了0,就回到缓冲区末尾。

比方说,如果缓冲区总量是10,里面的当前数据是:

u16 data_buffer[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

写入位置是2,那么就从1 开始向前读。如果一页显示4 个数据,那么第一页输出的内容就是[ 1, 0, 9, 8 ],后面的页依此类推。如果缓冲区总容量是10,但是当前只记录了2 个数据,那么读取时就不能自动回环,第一页内容是[ 1, 0 ],没有后续。

验证实现

下面是用来验证分页显示算法的实现,可以直接运行:

#include <iostream>
#include <stdint.h>using namespace std;using u16 = uint16_t;// 环形缓冲区 - 存储历史数据
u16 data_buf[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};// 分页配置
u16 ITEMS_PER_PAGE = 4;    // 每页显示4条数据
u16 BUFFER_SIZE = 10;      // 缓冲区总容量// 这些用来跟踪数据记录状态的变量要和数据一样存储在Flash 或EEPROM 里,
// 每次写入新数据时更新
u16 current_index = 9;     // 当前读取位置,根据当前写入位置计算,这里省略
u16 total_items = 10;      // 当前记录的数据量// 分页显示函数
// 从第一页开始,page_num 最小等于1
void show_page(u16 page_num) {// 页码检查 (从1开始)if(page_num < 1) {return;}// 计算当前页之前有多少条数据u16 items_before = ITEMS_PER_PAGE * (page_num - 1);// 检查请求的页码是否超出范围if(items_before >= total_items) {return;}// 计算要显示的页的起始位置u16 start_index;if(items_before > current_index) {// 处理环形缓冲区回绕u16 wrap_around = items_before - current_index;start_index = BUFFER_SIZE - wrap_around;} else {start_index = current_index - items_before;}// 计算当前页实际显示的数据量,如果是最后一页,可能剩余数据不足一整页u16 total_requested = items_before + ITEMS_PER_PAGE;u16 items_to_show = ITEMS_PER_PAGE;if(total_requested > total_items) {items_to_show = total_items - items_before;}// 显示数据for(; items_to_show > 0; --items_to_show) {// 从后往前遍历一页数据cout << data_buf[start_index] << endl;if(start_index < 1) {start_index = BUFFER_SIZE - 1;}else {--start_index;}}
}// 主函数 - 测试代码
int main() {show_page(1);cout << "=============" << endl;show_page(2);cout << "=============" << endl;show_page(3);return 0;
}
http://www.xdnf.cn/news/20209.html

相关文章:

  • 算法随笔(一)
  • S32K328上芯片内部RTC的使用和唤醒配置
  • 深度学习篇---MNIST:手写数字数据集
  • 基础排序--冒泡--选择--插入
  • 【算法--链表】25.K个一组翻转链表--通俗讲解
  • Linux初始化配置——RHEL7.9、9.3环境部署
  • 【C语言】 第三课 函数与栈帧机制详解
  • RTP打包与解包全解析:从RFC规范到跨平台轻量级RTSP服务和低延迟RTSP播放器实现
  • Deeplizard深度学习课程(七)—— 神经网络实验
  • 飞算JavaAI全面解析:重塑Java开发流程的智能引擎
  • 商城源码后端性能优化:JVM 参数调优与内存泄漏排查实战
  • List<?>和List<Object>区别
  • 第二阶段WinForm-12:UI控件库
  • 力扣516 代码随想录Day16 第一题
  • 【涂鸦T5】6. lvgl显示光感数值
  • 鸿蒙:AppStorageV2状态管理和数据共享
  • Gmail 数据泄露安全警报以及启示
  • 【Linux】线程概念与控制
  • 代码随想录刷题Day49
  • house (ai)
  • 对话Michael Truell:23岁创立Cursor,与Github Copilot竞争
  • 【C++上岸】C++常见面试题目--算法篇(第十九期)
  • 2025年8月文章一览
  • 深度学习:自定义数据集处理、数据增强与最优模型管理
  • 数据旁路(Data Bypassing)是什么?
  • 安装3DS MAX 2026后,无法运行,提示缺少.net core的解决方案
  • 2025年数学建模国赛C题第二版本超详细解题思路
  • Qwen-agent 核心功能分析学习
  • 从零开始学无监督学习:图像混合与标签平滑技术详解,收藏不走丢
  • C++开发中的常用设计模式:深入解析与应用场景