如何实现4行20字符OLED(NHD0420cw-ab3)的垂直滚动显示
垂直滚动实现方案及问题修正
核心问题分析
你当前代码中menu.line0 + line0_index的写法是字符串指针偏移操作,会让sendString从line0字符串的第line0_index个字符开始显示,导致文本右移,而非切换到下一行的完整文本。要实现垂直滚动,需要切换显示的行对象,而非偏移字符串内部指针。
解决方案
1. 修改结构体为二维数组(支持动态索引)
将独立的line0-line7成员改为二维数组,这样可以通过索引直接访问任意行,替代你想要的menu.(line+variable)动态调用需求:
#include <cstdint> // 引入uint8_t标准类型 struct menus { char lines[8][21] = { "This is a menu 12351", "This is a menu 12352", "This is a menu 12353", "This is a menu 12354", "This is a menu 12355", "This is a menu 12356", "This is a menu 12357", "This is a menu 12358" }; uint8_t top_line = 0; // 当前屏幕第一行对应的菜单索引 } menu;
注:标准C++中应使用uint8_t而非u_int8_t,需引入<cstdint>头文件。
2. 修正显示更新函数
通过top_line索引动态获取要显示的四行文本,利用取模运算实现环形循环:
// 更新显示:sendString([文本指针],[列],[行]) void updateDisplay() { LCD.sendString(menu.lines[menu.top_line], 0, 0); LCD.sendString(menu.lines[(menu.top_line + 1) % 8], 0, 1); LCD.sendString(menu.lines[(menu.top_line + 2) % 8], 0, 2); LCD.sendString(menu.lines[(menu.top_line + 3) % 8], 0, 3); }
3. 简化滚动函数
只需更新top_line并调用显示刷新即可,取模运算自动处理循环边界:
// 触发屏幕上滚一行 void scrollDisplay() { menu.top_line = (menu.top_line + 1) % 8; // 自增后取模,超过7自动回到0 updateDisplay(); // 刷新显示内容 }
效果说明
每次调用scrollDisplay:
top_line加1,代表屏幕第一行切换到下一个菜单文本- 屏幕第1-3行依次上移,第3行的下一个菜单文本(环形循环)补充到屏幕第4行
- 当
top_line到达7后,下一次滚动会回到0,实现环形缓冲区的循环滚动效果
内容的提问来源于stack exchange,提问作者bdrmachine
相关产品推荐
相关产品推荐

