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

(三)随处可见的LED广告屏是怎么工作的呢?接入GUI

续上文,本篇我们将尝试接入一个GUI来控制点阵屏。

在前两篇中,我们相继介绍了点阵屏的控制原理,以及如何让点阵屏按照我们所想的进行显示。本篇将在此基础上接入一个GUI,使点阵屏的控制更加优雅。

限于阅读体验和展示效果,软件部分将以伪代码、图片的形式进行展示。工程代码大家可以留言或者在订阅号上回复1001进行获取。

【选择合适的GUI】

目前嵌入式上开源的GUI有很多,u8g2、GuiLite、lvgl、miniGUI等等。这些GUI完整度很高,对RTOS的支持也很不错,而我们这次要移植的是SimpleGUI。

SimpleGUI在设计上尽可能减小了资源消耗,同时提供了点、线、基本几何图形以及单色位图、文字的绘制功能,以及列表、进度条、滚动条、提示框、曲线图等复杂部件的显示功能。

【预备工作】

点阵屏和我们常见的OLED最大的区别在于:点阵屏需要我们不断的控制MCU来对屏幕进行刷新,从而维持屏幕的正常显示。用显卡来举例,点阵屏是集成显卡,屏幕的控制集成在CPU中,和CPU共享内存。OLED是独立显卡,有独立芯片或者独立板卡来驱动,同时拥有独立的内存空间。

我们来看下SimpleGUI参考例程中初始化时需要填充哪些数据:

参数上我们需要填充屏幕的宽度、高度,函数上我们需要提供:获取屏幕像素点、设置像素点、清屏和刷新。

【如何实现这些函数】

上边我们提到了点阵屏和OLED屏幕在驱动上的一些区别,同时也清楚了移植GUI需要添加的功能函数。其中,屏幕像素点信息的获取和设置是点阵屏本身所不具备的。通常,我们在使用OLED时,厂家提供的驱动中会涵盖像素点的操作函数,我们先看看他们是如何实现的。

我们参考类比一下:在程序内部创建一个二维数组作为屏幕输出的数据缓存,通过计算X、Y坐标,将LED是否被点亮的数据写入到缓冲数组中某个字节的某个bit上。这里的数据缓存相当于我们第二篇中提到用来存储字模的数组。

【屏幕缓冲区】

回忆一下第二篇中我们取模的方式,取模成功后我们将字模数据存储到了一个32行、16列的二维数组中。这个数组中每个字节代表的bit和屏幕的像素点是一一对应的。

取模方式:阴码、逐行式、逆向(低位在前)
disp_table[32][16];

参照OLED的设置屏幕像素点的功能函数,我们把这个数组的行列对调下,以便符合这个X、Y的书写习惯。

LED_GRAM[16][32];//LED数据缓存区

【设置像素点】

设置像素点,本质上是找到LED_GRAM数组中对应像素点的bit值并改写。用伪代码来做一下描述

eg:将坐标(27,18)设置为1
先找到对应的字节byte
27/8=3找到列对应的下坐标
27%8=3找到对应的位

我们通过下边这个图表来直观的看一下。

上代码:

【读取像素点】

读取像素点与设置相类似,不同点在于,我们找到对应的字节后通过与操作,来判断当前像素点是0 or 1。

留意“设置像素点”和“读取像素点”这两段代码,2~11行,代码内容是完全一样的,在13~16行发生了变化。

设置代码是通过与、或操作将数值写入到当前字节。

读取代码则是通过与操作判断当前字节是0或者1,从而得出当前点是点亮还是熄灭。

【清屏】

清屏即将屏幕显示恢复至默认的背景色,对点阵屏来讲就是全灭。

在不使用GUI的情况,我们可以通过持续向HC595写入0x00来实现。在使用GUI后,我们清屏的操作不再是直接操作屏幕了,而是操作屏幕缓冲区,将屏幕缓冲区的二维数组全部置为0。

【屏幕刷新】

屏幕刷新,我们仍使用第二章整屏显示输出中的程序。因为我们将字模数组的xy做了对调,同样在输出函数中我们也对调一下xy。

【GUI与实际屏幕的显示关系】

在接入GUI后,我们对屏的操作,其实是隔了“显存”来进行的。无论是直线、圆、字符,本质是对“显存”的每个像素点进行读、写操作,之后统一通过HC595和译码器更新到屏幕上。

【测试】

至此,整个GUI移植所需的函数,我们都已经准备完毕。按照SimpleGUI参考例程中初始化的要求,我们填入这些数据。

使用GUI自带的字符串接口,显示一个“Hello Rabbit!”,实际效果如图。

【结束】

接入GUI后,我们可以更加便利的控制屏,让屏幕显示不在单调,更多好玩的显示效果期待大家得挖掘。

注:文章中部分图片来源于网络,如侵权请联系删除。

<第三篇END 文:雷打不动的晴天>


道阻且长,行则将至。

欢迎大家关注“兔子聊电路”,会不定期的分享一些遇到的电路问题和一些有趣的电路设计,更欢迎大家一起交流电路设计上的心得。同时,也会分享一些有意义的非技术类书籍。

相关文章:

(三)随处可见的LED广告屏是怎么工作的呢?接入GUI

续上文&#xff0c;本篇我们将尝试接入一个GUI来控制点阵屏。在前两篇中&#xff0c;我们相继介绍了点阵屏的控制原理&#xff0c;以及如何让点阵屏按照我们所想的进行显示。本篇将在此基础上接入一个GUI&#xff0c;使点阵屏的控制更加优雅。限于阅读体验和展示效果&#xff0…...

线程池简介

线程池 线程池&#xff08;英语&#xff1a;thread pool&#xff09;&#xff1a;一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时…...

大数据面试题集锦-Hadoop面试题(四)-YARN

你准备好面试了吗?这里有一些面试中可能会问到的问题以及相对应的答案。如果你需要更多的面试经验和面试题&#xff0c;关注一下"张飞的猪大数据分享"吧&#xff0c;公众号会不定时的分享相关的知识和资料。 文章目录1、为什么会产生 yarn,它解决了什么问题&#xf…...

Python---time模块

专栏&#xff1a;python 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;Python在学&#xff0c;希望能够得到各位的支持&#xff01;&#xff01;&#xff01; time模块前言时间戳time.time()将时间戳转换成字符串time.ctime()将时间戳转换为元组time.localtime(时间戳)将元…...

坚鹏:学习贯彻二十大精神 解码共同富裕之道(面向银行)

学习贯彻二十大精神 解码共同富裕之道课程背景&#xff1a; 很多银行从业人员存在以下问题&#xff1a;不知道如何准确解读二十大精神&#xff1f;不清楚共同富裕相关政策要求&#xff1f;不知道如何有效推动共同富裕&#xff1f; 课程特色&#xff1a;有实战案例有…...

python查看程序的cpu和内存资源占用情况

1.获取线程消耗的内存 :线程内存使用的概念没有明确定义。线程共享它们的内存。唯一真正的线程本地内存是它的调用堆栈&#xff0c;除非您认真地递归地做一些事情&#xff0c;否则这不是有趣的部分。 2.获取进程消耗的内存 3.获取程序消耗的内存 mprof run endpoint.py 4.查看…...

番外10:使用ADS对射频功率放大器进行非线性测试2(使用带宽20MHz的64QAM信号进行ACLR、EVM、CCDF测试)

番外10&#xff1a;使用ADS对射频功率放大器进行非线性测试2&#xff08;使用带宽20MHz的64QAM信号进行ACLR、EVM、CCDF测试&#xff09; 1、基本理论 功率放大器的非线性性能十分重要&#xff0c;特别是对于当前广泛使用的移动设备。由于其各种复杂的信号调制&#xff0c;功…...

Ubuntu搭建maven私服

1.安装JDK8 已经是JDK8的需要配置环境变量&#xff0c;如果是更高版本的JDK则需要修改nexus配置文件 2.下载nexus安装包 百度网盘下载&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1DfKqql8tZNQXEBxAEH7UyA 提取码&#xff1a;hx4p安装到有磁盘的目录如下所示&…...

【JavaWeb】Servlet基础

文章目录1.Tomcat服务器安装注意事项2.编写WebApp3.BS系统角色和协议4.模拟Servlet4.1模拟sun公司4.2模拟Tomcat服务器4.3模拟WebApp开发者5.开发一个带有Servlet的WebApp5.1创建一个名为crm的项目5.2 在项目中创建一个名为WEB-INF的文件&#xff08;必须&#xff09;5.3在WEB-…...

pinia + pinia-plugin-persistedstate + 组合式API 写法,持久化失效问题

持久化失效卡了一天的问题安装使用就不多说了&#xff0c;主要是针对持久化失效的几个问题说明和解决方法首先是组合式写法&#xff0c;配置持久化export const useUserStore defineStore(user, () > {},{persist: true} )defineStore 第三个参数&#xff0c;具体可以看 p…...

ptrace 调式详解

在程序出现bug的时候&#xff0c;最好的解决办法就是通过 GDB 调试程序&#xff0c;然后找到程序出现问题的地方。比如程序出现 段错误&#xff08;内存地址不合法&#xff09;时&#xff0c;就可以通过 GDB 找到程序哪里访问了不合法的内存地址而导致的。本文不是介绍GDB不是使…...

【AI绘画】绝美春天插画,人人都是插画师

春天&#xff0c;自然界重新苏醒&#xff0c;生机勃勃&#xff0c;百花争艳&#xff0c;万籁俱寂。一切都被新的生命活力所染上。春风拂面&#xff0c;一股清新的空气流过&#xff0c;仿佛带着一种神秘的力量&#xff0c;让人心旷神怡&#xff0c;心情舒畅、轻松愉悦。 突然&a…...

蓝桥杯入门即劝退(二十四)重复的子字符串(被秒杀)

欢迎关注点赞评论&#xff0c;共同学习&#xff0c;共同进步&#xff01; ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法&#xff0c;欢迎订阅专栏共同学习交流&#xff01; 你的点赞、关注、评论、是我创作的动力&#xff01; -------希望我的文章…...

针对序列级和词元级应用微调BERT(需修改)

对于序列级和词元级自然语言处理应用&#xff0c;BERT只需要最小的架构改变&#xff08;额外的全连接层&#xff09;&#xff0c;如单个文本分类&#xff08;例如&#xff0c;情感分析和测试语言可接受性&#xff09;、文本对分类或回归&#xff08;例如&#xff0c;自然语言推…...

(四十七)大白话表锁和行锁互相之间的关系以及互斥规则是什么呢?

今天我们接着讲&#xff0c;MySQL里是如何加表锁的。这个MySQL的表锁&#xff0c;其实是极为鸡肋的一个东西&#xff0c;几乎一般很少会用到&#xff0c;表锁分为两种&#xff0c;一种就是表锁&#xff0c;一种是表级的意向锁&#xff0c;我们分别来看看。 首先说表锁&#xf…...

织梦TXT批量导入TAG标签并自动匹配相关文章插件

织梦TXT批量导入TAG标签并自动匹配相关文章插件是一种非常有用的插件&#xff0c;它可以帮助网站管理员快速地将TAG标签添加到文章中&#xff0c;并自动匹配相关文章。 以下是该织梦TXT批量导入TAG标签插件的几个优点&#xff1a; 1、提高网站的SEO效果&#xff1a;TAG标签是搜…...

Sentinel架构篇 - 10分钟带你看滑动窗口算法的应用

限流算法 以固定时间窗口算法和滑动时间窗口算法为例&#xff0c;展开两种限流算法的分析。 固定时间窗口算法 在固定的时间窗口内&#xff0c;设置允许固定数量的请求进入。如果超过设定的阈值就拒绝请求或者排队。 具体的&#xff0c;按照时间划分为若干个时间窗口&#…...

redis主从复制

<1> redis主从复制介绍&#xff1a; 首先来介绍一下什么是redis主从复制 Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中&#xff0c;当读写体量比较大的时候&#xff0c;服务端就很难承受…...

近期常见组件漏洞更新:

&#xff08;1&#xff09;mysql 5.7 在2023年1月17日&#xff0c;发布了到5.7.41版本 mysql 8.0 在2023年1月17日&#xff0c;发布了到8.0.32版本 MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/mysql/ &#xff08;2&#xff09;Tomcat8在202…...

深度学习常用的激活函数总结

各种激活函数总结 目录一、sigmoid二、tanh![在这里插入图片描述](https://img-blog.csdnimg.cn/a0d92552edf8464db793fdd2f2b75cb5.png)三、ReLU系列1.原始ReLU2.ReLU改进&#xff1a;Leaky ReLU四、swish五、GeLU一、sigmoid 优点&#xff1a; 1.可以将任意范围的输出映射到 …...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...