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

单片机学习笔记---LED点阵屏显示图形动画

目录

LED点阵屏显示图形

LED点阵屏显示动画

最后补充


上一节我们讲了点阵屏的工作原理,这节开始代码演示!

前面我们已经说了74HC595模块也提供了8个LED,当我们不使用点阵屏的时候也可以单独使用74HC595,这8个LED可以用来测试74HC595。

那接下来我们可以先不使用点阵屏,先用这8个LED来测试一下74HC595。

LED点阵屏显示图形

新创建一个工程:LED点阵屏显示图形。

写上框架

接下来先补充几个关键词的介绍:

sfr(special function register):特殊功能寄存器声明

例:sfr P0 = 0x80;

声明P0口寄存器,物理地址为0x80

sbit(special bit):特殊位声明

例:sbit P0_1 = 0x81;    或    sbit P0_1 = P0^1;

声明P0寄存器的第1位

可位寻址/不可位寻址:在单片机系统中,操作任意寄存器或者某一位的数据时,必须给出其物理地址,又因为一个寄存器里有8位,所以位的数量是寄存器数量的8倍,单片机无法对所有位进行编码,故每8个寄存器中,只有一个是可以位寻址的。对不可位寻址的寄存器,若要只操作其中一位而不影响其它位时,可用“&=”、“|=”、“^=”的方法进行位操作。

“&=”一般用于对某一位清零

“|=”一般用于对某一位置1

“^=”异或等于,一般用于对某一位取反,不一样就置1,一样就置0。异或这个用的比较少。

为什么要补充这几个关键词的介绍呢?是因为我们接下来要操作P35等三个引脚,但是为了方便操作,我们想要对这三个引脚重新命名,所以我们就要使用重命名的方法。

比如我们要重新命名P3的第五位,可以这样写

这样我们之后操作RCLK就等于操作P3的第5位

但是由于RLCK已经被头文件定义过了,所以我们不能重复定义,所以把这三个引脚都重新命名为:

不同的人对同一个引脚的命名也不一样,所以今后在芯片手册上要注意对应。

接下来我们写一个子函数,它的作用是将参数传过来的数据给写入那8个引脚,相当于给那8个引脚赋值。

由于推进来的第一位是要赋值给QH的,所以我们要先将参数的字节的最高位取出来

PS:SER是一位数据,如果将8位数据赋给它的话,非0即1

按照上一篇博客讲的工作原理,接下来要先给SERCLK初始化,

然后再给它一个高电平(上升沿),

SER过来的数据在移位寄存器中下降一位之后再将SERCLK清零,为下一次移位做准备。

到这里Byte的最高位已经操作完毕,接下来是移动次高位

同理,其他位也是这样操作,如此循环,我们可以用一个for循环语句

移完8位数据后,要输出就得先初始化RCLK锁存数据,

然后给它一个上升沿,

最后同时输出8位数据后,给它清零

这样操作完后,就能把8位数据送到IO口上了。

最后我们调用这个子函数测试一下

最后整个代码是这样的

编译无错误后看一下效果

的确这八个LED一半亮一半灭

测试74HC595完毕,接下来我们就开始实际操作点阵屏

我们会用到Delay函数的代码,所以要添加进本节的工程文件中。

由于点阵屏的操作和数码管的操作类似,所以我可以参照数码管的那一节代码。

这是我们之前写一个数码管的子函数,location表示它显示的位置,Number表示显示的段码

同理,我们把点阵屏的每一列看成location,每一行看成是段码

那么我们要添加一个子函数,column表示列,data表示行的数据

然后我们在这里先调用一下行的数据

然后要选择列的数据

这样写表示如果用户选的是第0列,也就是P07列,

那么就让P07=0,其他位等于1,所以就取反0x80=0111 1111

如果选P06=0,要如此循环写if语句,我们可以用另一种写法避免重复写if语句

然后调用一下这个函数

完整代码:

编译无错误测试一下

的确是第0列,行显示亮灭亮灭。

如果想要进行扫描的话,也需要进行消影,和数码管的操作类似(之前我们说数码管进行段选-位选-段选-位选-段选-位选的过程中,刚把下一位段选送入的时候,它会把这个段选送到上一位选,因为上一位的位选还没来得及改变,产生串位的现象,也就是残影的问题)

那么我们需要加一个过程,就是位选后,位选清零。

于是就变成段选-位选-位清零-段选-位选--位清零-段选-位选

顺便加一段延时过程

段选-位选-延时-位清零-段选-位选-延时-位清零-段选-位选

这样即使它发生串位也是串到了位清零的时刻,但是位清零什么都没有显示,这样就能达到消影的效果。

但是这样的结果是它执行一次就会马上灭掉,所以我们把调用放在while循环里面让它循环执行。

这样我们还可以显示多位了,比如让它显示一条对角的斜线

如果我们想要想让显示一个笑脸的话,可以先把效果脸的图画在一个表格中

上图画1的位置点亮,其他不亮

我们要一列一列的进行扫描,把每一列的数据转换成16进制

每一列的数据转换好之后写进去

效果

成功显示了一个笑脸

然后我们对这个代码进行一下优化

重定义一下P0

然后把我们程序中的所有P0口改成MATRIX_LED_PORT

增加这行代码的意义在于当我们用不同开发板(有可能不同引脚)运行程序时,我们只需要修改#define MATRIX_LED_PORT P0后面的P0就行,而无需逐个修改整个程序中的P0。

优化后的代码加上注释:

PS: void MatrixLED_ShowColumn(unsigned char Column,Data)这个子函数这里给1为亮,0为灭是因为:

根据点阵屏的原理图,列是把每列LED的阴极连在一起,行是把每行LED的阳极两在一起,当阴极(列)给0,阳极(行)给1的时候,对应的LED才会亮)

因此段选==选择行给了低电平之后,位选==选择列就要给高电平1才能让对应的LED亮。

第一个代码演示完毕,源码放在评论区了,自取!

LED点阵屏显示动画

接下来我们演示第二个示例代码:显示动画

把第一个代码演示的工程文件复制一份,打开后改造并把程序模块化一下

main.c

MatrixLED.c

MatrixLED.h

然后接下来我们来写显示动画

比如我们想要显示一串字符“Hello!”然后让它向左流动。

那么我们先要存一个数组,这个数组存的是一长条的整幅动画,就是8*32或者更多。

接下来我们介绍一个辅助工具:文字取模软件

这个软件可以自动帮我们数据给提出来

首先要新建图像

填上宽度和高度32*8,点击确定后创建好一个区域

放大格点

参数设置,其他选项

纵向取模,确定

然后在这里我们可以手动地画一下我们要显示的东西

字幕画好了之后

然后我们先控制前八个显示,依次往后移动,然后字幕就能在屏幕上流动

取模方式,C51格式,下面就显示出来了我们的数据

直接把这个数据复制过来,放进我们定义好的数组里面

这个数组内每一个元素分别表示每一列的数据

然后我们需要定义数组元素的下标

然后用一个for循环让它循环流动显示每一列的数据

然后我们需要定义一个变量offset表示偏移量。

我们一开始一个for循环显示完8个元素(0~7号元素),也就是动画第一帧结束。

i+offset就让它从第二个元素开始显示起(1~8号元素),也就是动画的第二帧。每次+offset就从下一位循环起,如此反复每一次都把起始位置移一下,就形成了动画的很多帧。

然后我们还需要定义一个Count,每扫描一次后就+1,扫描10次的话相当于延时了(因为每一帧让它循环显示10遍,这样做的目的是让前一帧动画显示的时间长一点,为了避免下一帧动画显示时把前一帧动画给覆盖掉,显示10遍的话即使下一帧动画来覆盖也不可能完全覆盖掉前一帧动画)

Offset一直在加,当它加到头的时候溢出数组了,所以后面就产生乱码

为了防止数组溢出,再加一个if语句

但是这样写的话当它执行完所有帧的时候它会直接跳回到第一帧,这样显得比较突兀,我们可以在数组第一个元素前再加8个元素0x00(刚好等于一帧动画),然后最后一个元素后面也加8个元素0x00,这样就相当于第一帧动画前加一帧空白帧,最后一帧动画后面也加一帧空白帧,让最后一帧动画和第一帧动画能对接上,这样字幕播放就是流畅的,不会出现最后一帧动画播放完后立马又闪现出第一帧的动画的现象!

然后这里改成32

但是这样写还有一个问题就是播放最后一帧动画显示感叹号的时候,感觉突然消失了

我们可以再改成40,也就是让屏幕显示完40个数据(前五帧)后再对offset清零,这样就能让最后一个感叹号显示完之后显示一个空白帧然后再对offset清零,进入第二轮字幕播放。

最后主程序的代码如下:

效果请看视频:

用点阵屏做的流动字幕

最后补充

如果想要用点阵屏做一个逐帧动画也是可以的,可以自己琢磨在这个程序的基础上改。

还要说明一点:如果想要设置更长的动画的话,就在数组里面去更多的数据,就可以显示不同的动画。但是这个数组元素是否能无限加呢?不能!如果数据过多的时候,单片机的RAM就不够,因为我们这个数组的数据其实是存放在RAM里面的。

单片机有两种存储,一种是程序运行时的暂存器叫RAM,另一种是放在Flash里面的程序存储器(持续空间会大一些)。

而且这个数组里面的数据一般不需要改变其中的值,所以放在RAM里面会很浪费内存,所以我们一般把它放在flash里面。

怎么放在flash里面呢?需要在这里加一个关键字code,加上这个关键字后,数组里面的数据就会放在flash里面。

但是如果将这个数组放在code里面有个不好的地方就是这个数组不能更改了。如果尝试将数组中的某个元素重新赋值,程序就会报错。

以上就是本节的全部内容,源码已经放在评论区,如有问题可在评论区留言。

相关文章:

单片机学习笔记---LED点阵屏显示图形动画

目录 LED点阵屏显示图形 LED点阵屏显示动画 最后补充 上一节我们讲了点阵屏的工作原理,这节开始代码演示! 前面我们已经说了74HC595模块也提供了8个LED,当我们不使用点阵屏的时候也可以单独使用74HC595,这8个LED可以用来测试7…...

Git分支常用指令

目录 1 git branch 2 git branch xx 3 git checkout xx 4 git checkout -b xx 5 git branch -d xx 6 git branch -D xx 7 git merge xx(含快进模式和冲突解决的讲解) 注意git-log: 1 git branch 作用:查看分支 示例: 2 git branch xx 作用&a…...

3.3 Binance_interface APP U本位合约行情-实时行情

Binance_interface APP U本位合约行情-实时行情 Github地址PyTed量化交易研究院 量化交易研究群(VX) py_ted目录 Binance_interface APP U本位合约行情-实时行情1. APP U本位合约行情-实时行情函数总览2. 模型实例化3. 获取一个产品的最优挂单 get_bookTicker4. 获取全部产品…...

机器学习——流形学习

流形学习是一种在机器学习领域中用于理解和分析数据的技术。它的核心思想是,尽管我们通常将数据表示为高维空间中的向量,但实际上数据可能具有较低维度的内在结构,这种结构被称为流形。流形学习的目标是发现并利用数据的这种潜在结构&#xf…...

离线数仓(一)【数仓概念、需求架构】

前言 今天开始学习数仓的内容,之前花费一年半的时间已经学完了 Hadoop、Hive、Zookeeper、Spark、HBase、Flume、Sqoop、Kafka、Flink 等基础组件。把学过的内容用到实践这是最重要的,相信会有很大的收获。 1、数据仓库概念 1.1、概念 数据仓库&#x…...

物联网测试:2024 年的最佳实践和挑战

据 Transforma Insights 称,到 2030 年,全球广泛使用的物联网 (IoT) 设备预计将增加近一倍,从 151 亿台增至 290 亿台。这些设备以及智能汽车、智能手机等广泛应用于各种官僚机构。 健康视频监视器、闹钟以及咖啡机和冰箱等最受欢迎的家用电器…...

蓝桥杯Web应用开发-CSS3 新特性

CSS3 新特性 专栏持续更新中 在前面我们已经学习了元素选择器、id 选择器和类选择器,我们可以通过标签名、id 名、类名给指定元素设置样式。 现在我们继续选择器之旅,学习 CSS3 中新增的三类选择器,分别是: • 属性选择器 • 子…...

MongoDB聚合:$unionWith

$unionWith聚合阶段执行两个集合的合并&#xff0c;将两个集合的管道结果合并到一个结果集传送到下一个阶段。合并后的结果文档的顺序是不确定的。 语法 { $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } }要包含集合的所有文档不…...

人工智能三子棋-人机对弈-人人对弈,谁会是最终赢家?

✅作者简介&#xff1a;大家好我是原始豌豆&#xff0c;感谢支持。 &#x1f194;本文由 原始豌豆 原创 CSDN首发&#x1f412; 如需转载还请通知⚠ &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​ &#x1f4e3;系列专栏&#xff1a;C语言项目实践…...

【leetcode热题100】反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1a;[1,4,3,2…...

谷歌 DeepMind 联合斯坦福推出了主从式遥操作双臂机器人系统增强版ALOHA 2

谷歌 DeepMind 联合斯坦福推出了 ALOHA 的增强版本 ——ALOHA 2。与一代相比&#xff0c;ALOHA 2 具有更强的性能、人体工程学设计和稳健性&#xff0c;且成本还不到 20 万元人民币。并且&#xff0c;为了加速大规模双手操作的研究&#xff0c;ALOHA 2 相关的所有硬件设计全部开…...

金融行业专题|证券超融合架构转型与场景探索合集(2023版)

更新内容 更新 SmartX 超融合在证券行业的覆盖范围、部署规模与应用场景。新增操作系统信创转型、Nutanix 国产化替代、网络与安全等场景实践。更多超融合金融核心生产业务场景实践&#xff0c;欢迎阅读文末电子书。 在金融行业如火如荼的数字化转型大潮中&#xff0c;传统架…...

【C语言】C的整理记录

前言 该笔记是建立在已经系统学习过C语言的基础上&#xff0c;笔者对C语言的知识和注意事项进行整理记录&#xff0c;便于后期查阅&#xff0c;反复琢磨。C语言是一种面向过程的编程语言。 原想在此阐述一下C语言的作用&#xff0c;然而发觉这些是编程语言所共通的作用&#…...

使用STM32Cubemx创建一个工程并且给出每一步的含义

...

C/C++模板初阶

目录 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.1 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3. 类模板 3.1 类模板的定义格式 3.2 类模板的实例化 1. 泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int&…...

linux系统下vscode portable版本的c++/Cmake环境搭建001

linux系统下vscode portable版本的Cmake环境搭建 vscode portable 安装安装基本工具安装 build-essential安装 CMake final script code安装插件CMake Tools & cmakeC/C Extension Pack Testsettings,jsonCMakeLists.txt调试和运行工具 CG 目的&#xff1a;希望在获得一个新…...

【QT+QGIS跨平台编译】之三十一:【FreeXL+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、FreeXL介绍二、文件下载三、文件分析四、pro文件五、编译实践一、FreeXL介绍 【FreeXL跨平台编译】:Windows环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台编译】:Linux环境下编译成果(支撑QGIS跨平台编译,以及二次研发) 【FreeXL跨平台…...

2024年 前端JavaScript入门到精通 第一天

主要讲解JavaScript核心知识&#xff0c;包含最新ES6语法&#xff0c;从基础到API再到高级。让你一边学习一边练习&#xff0c;重点知识及时实践&#xff0c;同时每天安排大量作业&#xff0c;加深记忆&#xff0c;巩固学习成果。 1.1 基本软件与准备工作 1.2 JavaScript 案例 …...

155基于matlab 的形态学权重自适应图像去噪

基于matlab 的形态学权重自适应图像去噪&#xff1b;通过串并联的滤波降噪对比图&#xff0c;说明并联降噪的优越性。输出降噪前后图像和不同方法的降噪情况的信噪比。程序已调通&#xff0c;可直接运行。 155matlab 自适应图像降噪 串并联降噪 (xiaohongshu.com)...

操作系统——内存管理(附带Leetcode算法题LRU)

目录 1.内存管理主要用来干什么&#xff1f; 2.什么是内存碎片&#xff1f; 3.虚拟内存 3.1传统存储管理方式的缺点&#xff1f; 3.2局部性原理 3.3什么是虚拟内存&#xff1f;有什么用&#xff1f; 3.3.1段式分配 3.3.2页式分配 3.3.2.1换页机制 3.3.2.2页面置换算法…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...

Java数组Arrays操作全攻略

Arrays类的概述 Java中的Arrays类位于java.util包中&#xff0c;提供了一系列静态方法用于操作数组&#xff08;如排序、搜索、填充、比较等&#xff09;。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序&#xff08;sort&#xff09; 对数组进行升序…...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器

从本章节开始&#xff0c;进入到函数有多个参数的情况&#xff0c;前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参&#xff0c;ECX是整型的第一个参数的寄存器&#xff0c;那么多个参数的情况下函数如何传参&#xff0c;下面展开介绍参数为整型时候的几种情…...