基于 51 的点阵屏显示·16*16 点阵仿真实验(静态显示,左移显示)

news2024/11/18 5:52:18

若想更详细了解可以先跳转到:

基于 51 的点阵屏显示 8*8 点阵仿真实验:

基于 51 的点阵屏显示 8*8 点阵仿真实验-CSDN博客

对一个模块进行了解

16*16 点阵的显示原理

        虽然完成了上面 8*8 点阵的显示,但是由于点的数量太少以至于它的显示效果并不是很理想,事实上现在大部分点阵的汉字都是16*16显示的,下面让我们来学习16*16点阵的显示。和上面一样我们先选择元件 :AT89C52 ,74LS138, ,MATRIX-8*8-GREEN ,因为要显示16*16的汉字,我们就不能再使用一个38译码器进行行选了,这里我们用两个38译码器组合成一个4 选 16的译码器(当然也可以使用 74159)。而MATRIX-8*8-GREEN 点阵需要4个。完成后如下图:

        先来看看 4 选 16 的译码器是如何工作的,这里有 4 个输入端a、b、c、d,16 个输出端 HO~H15,如上图连线后即可完成类似于38译码器一样的工作。只不过扩展到了16 行选。关于连线的原理这里不再赘述,只要明白38译码器的原理这个可以轻松理解。接着完成全部布线。如下图所示:

        连好线后,P1作为行选,P2、P3一起作为列选。现在16*16的点阵被分成两块并不完整的部分,我们可以整体移动(包括点阵屏、连线以及连接点,)来方便我们观察显示的效果(最好同时去掉仿真中电平的指示灯)。接着我们来看一个程序,还是让此点阵屏显示一个汉字:“明。”先看效果图:

源代码如下:

#include<reg52.h> 
char code table[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21, 
 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 
 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 
 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10}; // 明
void delay(int z) 
{ 
 int x,y; 
 for(x=0;x<z;x++) 
 for(y=0;y<110;y++); 
} 
void main() 
{ 
 int num; 
 while(1) 
 { 
 for(num=0;num<16;num++) 
 { 
 P1=num; //行选
 P2=table[2*num]; //列选
 
 P3=table[2*num+1]; //列选
 delay(2); 
 } 
 } 
}

        先来看这次使用的table数组,因为是16*16的点阵,所以总共有32个数据,其中第1、2个数据用于第一行的显示,第2、3个数据用于第二行的显示,以此类推,总共16行。然后还是来看while循环内,同样for循环依次扫描16行,以第一行为例,即num=0时,首先 P1=0,选中第一行,P2=table[0]、P3=table[1]送出列选数据,即第一行要显示的两个字节的数据。其他行同理。这样很轻松的我们就完成了16*16 点阵的显示。程序虽然完成了,但是回过头来看一看就会发现,我们在这里使用了 P2 与 P3 口一起来做列选,浪费了大量的1/0/资源,而且现在点阵屏的大小还只有16*16 ,如果想要扩展的更大,已经没有足够的1/0口可用了。所以一定要想出更好的办法进行列选。

        为了解决上面提到的问题,我们来学习一个新的元件: 74HC595。它实质上是一个串行移位寄存器,能够实现“串入并出”的功能,关于它的使用我们还是用上一个列子来讲解,先来看看它的实现,如图:

        可以看到这里我们仅使用了三个 1O口就完成了列选数据的发送。主要来看74HC595是如何实现“串入并出”的,这里我们使用了两个595 进行了级联,即第二个595 的数据输入端连接了第一个595的级联输出口Q7'。也就是说,我们只需要从第一个595的输入端串行输入数据,便可以实现把数据送入第二个595的功能。而且595的数量可以进行无限的级联,而不管有多少个595,我们只需要一个数据输入端就可以,这样就大大节省了10资源。对于595的具体使用还是来看程序。

源代码如下:

#include<reg52.h> 
sbit R=P2^0; //数据输入端口
sbit CLK=P2^1; //时钟信号
sbit STB=P2^2; // 锁存段
char code table[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21, 
 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 
 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 
 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10}; // 明
 
void delay(int z) 
{ 
 int x,y; 
 for(x=0;x<z;x++) 
 for(y=0;y<110;y++); 
} 
void WriteByte(char dat) //写一个字节数据
 
{ 
 char i; 
 for(i=0;i<8;i++) //循环八次
 { 
 dat=dat>>1; //右移一位
 
 R=CY; //最低字节给R
 CLK=0; //上升沿
 
 CLK=1; 
 } 
} 
void main() 
{ 
 int num; 
 while(1) 
 { 
 for(num=0;num<16;num++) 
 { 
 WriteByte(table[2*num]); //送出一个字节
 
 WriteByte(table[2*num+1]); 
 P1=num; //行选
 
 STB=1; //下降沿
 
 STB=0;
 delay(2); 
  } 
 } 
}

        先来看不同之处这里我们首先位定义了R、CLK、STB分别对应于74HC595的DS、SH_CP、ST-CP用以实现串行数据输入、数据移位以及并行数据输出。然后来看WriteByte(char dat )函数,该函数实现了串行向595中输入一个字节数据的功能。来看for循环,首先dat-dat>>1,把要输入的数据右移一位,这样最低位便进入移位寄存器CY中,紧接着我们让R=CY,把该位传给 595 的输入端,CLK一个上升沿的跳变就实现了把该位数据移入 595的功能。8次循环便可以将一个字节的数据送出。重点还是看 while 循环内,同样也是 16 行的扫描 ,然后就是WriteByte( table[2*num]筹同于上面的P2=table[2*num] ,WriteByte(table[2*num+1])等同于P3=table[2*num+1] ,完成列选,接着行选,然后有一个STB的下降沿的跳变,这个变化能够实现并行输出移位寄存器中的数据。这样就完成了整个过程。

项目源码:

LED点阵屏16x16静态显示.rar资源-CSDN文库

16*16点阵的移位控制

点阵的移位一般有上、下、左、右的移动,这里我们重点讲上移和左移,其它同理。

点阵的上移:

点阵的上移相对来说很简单,看效果图如下:

程序源码:

#include<reg52.h> 
sbit R=P2^0; //数据输入端口
sbit CLK=P2^1; // 时钟信号 
sbit STB=P2^2; //锁存端
 
char code table[]={ 

 0x00,0x00,0xFE,0x3E,0x48,0x22,0x48,0x22, 
 0x48,0x12,0x48,0x12,0x48,0x0A,0xFF,0x13, 
 0x48,0x22,0x48,0x42,0x48,0x42,0x48,0x46, 
 0x44,0x2A,0x44,0x12,0x42,0x02,0x40,0x02,//邢
 
 0x40,0x00,0x40,0x00,0x20,0x00,0x10,0x04, 
 0x08,0x08,0x04,0x10,0xFE,0x3F,0x00,0x20, 
 0x00,0x08,0xF8,0x1F,0x08,0x08,0x08,0x08, 
 0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08, //台
};
 
void delay(int z) 
{ 
 int x,y; 
 for(x=0;x<z;x++) 
 for(y=0;y<110;y++); 
} 
void WriteByte(char dat) //写一个字节数据 
{ 
 char i; 
 for(i=0;i<8;i++) //循环八次
 { 
 dat=dat>>1; //右移一位
 
 R=CY; 
 CLK=0; //将数据送出,上升沿
 
 CLK=1; 
 } 
} 
void main() 
{ 
 int num,move,speed; 
 while(1) 
 { 
 if(++speed>8) //移速控制
 { 
 speed=0; 
 move++; //位移
 if(move>16) //是否完成一个汉字
 move=0; //从头开始
 } 
 
 for(num=0;num<16;num++) 
 { 
 WriteByte(table[2*num+move*2]); //送出一个字节
 
 WriteByte(table[2*num+1+move*2]); 
 P1=num; //行选
 
 STB=1;
 
 STB=0; 
 delay(2); 
 } 
 } 
}


        可以看到这个程序和静态显示的程序没有太大的差距,主要就是加入了一个move变量来控制移动, WriteByte(table[2*num+move*2])中当move变量变化的时候更改了写入595中的数据,正好实现了移动显示的效果。而speed变量的if判断语句能够控制移动速度的大小。下面重点讲左移。

点阵的左移:

        因为点阵的数据最终是一个一个字节的并行送出的,所以要实现点阵的左移,我们就需要考虑如何才能够动态的更改每一个发送字节的数据,而汉字的每一个字节的编码是固定的,这里我们可以使用一个数据缓冲区来完成点阵的左移。重点说一下点阵左移中关键的一步操作temp-(BUFF[s>>tempyid) | (BUFF[s+1]<<(8-tempyid))。这里 temp 作为要发送的一个字节数据,它由数据缓冲区中的数据组合而成,并且动态的变化,大致来说就是首先第一个字节的数据右移tempyid 位,第二个字节的数据左移8-tempyid 位,两者相或后组成一个字节新的数据,只要我们一直不断地移位、相或、发送,就能实现左移的效果。不太好理解,先来看实例(循环左移显示“邢台学院”),效果图如下:

程序源码:

#include <AT89x51.H> 
#define uchar unsigned char 
#define uint unsigned int 
uchar yid,h; 
uint zimuo; //字模计数器 
uchar code hanzi[]; //汉字字模
 
uchar BUFF[4]; //缓存
void in_data(void); //调整数据
void rxd_data(void); //发送数据
void sbuf_out(); //16段扫 
uchar code table[]={//编码,使用字模软件,可自行更改字模};

void main(void) 
{ 
 uchar i,d=10; 
 yid=0; 
 zimuo=0; 
 while(1) 
 { 
 while(yid<16) //移位
 
 { 
 for(i=0;i<d;i++) //移速
 { 
 sbuf_out(); 
 } 
 yid++; //一步
 
 } 
 yid=0; 
 zimuo=zimuo+32; 
 if(zimuo>=96) //从头开始
 
 zimuo=0; 
 } 
} 
/********************************/ 
void sbuf_out() 
 { 
 for(h=0;h<16;h++) //行扫
 { 
 in_data(); 
 rxd_data(); //串口发送数据
 
 P1=0x7f; //关闭显示
 P1_7=1; 
 P1=h; 
 }
 }

void in_data(void) 
{ 
 char s; 
 for(s=1;s>=0;s--) 
 { 
 BUFF[2*s+1]=table[zimuo+1+32*s+2*h];  
 BUFF[2*s]=table[zimuo+32*s+2*h]; 
 } 
} 
/*******************************************************/ 
void rxd_data(void) 
{ 
 char s; 
 uchar inc,tempyid,temp; 
 if(yid<8) 
 inc=0; 
 else 
 inc=1; 
 for(s=0+inc;s<2+inc;s++) 
 
 { 
 if(yid<8) 
 tempyid=yid; 
 else 
 tempyid=yid-8; 
 temp=(BUFF[s]>>tempyid)|(BUFF[s+1]<<(8-tempyid)); 
 SBUF=temp;
 while(!TI);
 TI=0;
}
}

        首先来看定义的数据缓冲区 BUFF[],这里一开始将会存储第一个汉字与第二个汉字的第一行的编码,该缓冲区动态的 存储点阵屏每一行要发送的数据,注意这里 BUFF 的大小为 4个字节,比16*16点阵屏要显示的汉字多了一个汉字行的大小,这一点是必要的,这样我们才能实现利用该缓冲区进行左移控制,接着来看in_data(void)函数,利用该函数,我们实现了动态的修改缓冲区中的数据,这里不再详述过程,重点看程序的注释即可。

        然后看rxd-data(void)函数,该函数的作用正是利用串口串行发送数据,也就是上面提到的移位、相或然后发送,关于在移位过程中的具体实现细节以及如何协调的进行数据发送,首先来看ine变量,该变量决定了从BUFF 缓冲区中的第一个还是第二个数据开始读取,当移位开始后,在移完一个字节的数据之前我们都从BUFF 数据缓冲区中的第一个字节开始读取,当移完一个字节后, inc变成1,这时我们从BUFF数据缓冲区中的第二个字节开始读取,于此同时后一个字节总是在和前一个字节的数据进行移位相或,达到慢慢向前推进的效果,这里有一个临界点,就是当移位满16位后,即一个汉字移出点阵屏后,这时候我们就需要将数据缓冲区中的数据进行更新,即后移一个字,这时数据缓冲区中的数据就变成了第二个汉字和第三个汉字的第一行汉字的编码,以此类推。

        下面来看sbuf_out()函数,该函数实现了16行的扫描,最后来看 while循环内,这时主函数内已经很简单了,首先在 while(yid<16)内,有控制移动速度的for循环,即显示几次静态的画面移动一步,而zimuo变量为移位过程中汉字的选择变量,它每32位的变化,正好是一个16*16汉字的编码个数。这样就完成了整个点阵左移的控制(这里使用了串口实现点阵的左移,当然我们也可以不用串口,关于非串口实现的左移后面介绍),它的过程比较复杂,需反复思考。

项目源码:

LED点阵屏16x16左移显示.rar资源-CSDN文库

时光の尘_千题千解·Java面试宝典,Linux学习,C++学习-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142271.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简历自动生成工具

简历自动生成工具 简历自动生成工具&#xff0c;可根据提供的关键字生成完整内容&#xff0c;并应用于多个模板中。避免想更换简历风格的小伙伴&#xff0c;重复编辑简历的烦恼。 使用方法 每个求职者都需要认真对待自己的简历&#xff0c;特别是那些实力还不错的&#xff0c…

Centos如何安装Mysql

1、安装前检查是否存在mysql yum list installed mysql* ①如或显示了列表&#xff0c;说明系统中有MySQL **yum卸载 ** 根据列表上的名字&#xff08;[中括号为可选项]&#xff09; yum remove [填写列表显示出来的所有内容] rm -rf /var/lib/mysql rm /etc/my.cnf②rpm查…

【Linux】zip 命令使用

zip 命令用于压缩文件。压缩后的文件后缀名为 .zip。 语法 zip [参数] [文件] zip命令 -Linux手册页 命令选项及作用 执行令 zip --help 和 zip --help2 执行命令结果 参数 -A 调整可执行的自动解压缩文件。-b<工作目录> 指定暂时存放文件的目录。-c 替每个被压缩的…

LrC 13 ACR 16:镜头模糊

的Adobe Lightroom Classic 13 &#xff08; 2023 年 10 月版&#xff09;及 Adobe Camera Raw 16 新增的镜头模糊 Lens Blur功能可以基于 AI 技术生成深度图&#xff0c;并依据深度图对图像添加模糊和焦外成像&#xff08;散景光斑&#xff09;效果。 LrC&#xff1a;修改照片…

devCpp显示文件未编译

问题背景 刚刚去下载了devcpp&#xff0c;然后保存好代码之后点击编译运行出现文件未编译 问题细节 单独编译的时候显示这个当时没怎么注意 然后一直点编译运行死活显示文件未编译 目录下也没有exe文件 具体原因及代码 const int maxLine1e510; int arr[maxLine][maxLine]…

Windows VS C++工程:包含目录、库目录、附加依赖项、附加包含目录、附加库目录配置与静态库、动态库的调用——以OCCI的配置为例

文章目录 1 包含目录&#xff08;Include Directories&#xff09;/ 附加包含目录&#xff08;Additional Include Directories&#xff09;1.1 区别和作用1.2 设置路径 2 库目录&#xff08;Library Directories&#xff09;/ 附加库目录&#xff08;Additional Library Direc…

三篇论文:速览GPT在网络安全最新论文中的应用案例

GPT在网络安全领域的应用案例 写在最前面论文1&#xff1a;Chatgpt/CodeX引入会话式 APR 范例利用验证反馈LLM 的长期上下文窗口&#xff1a;更智能的反馈机制、更有效的信息合并策略、更复杂的模型结构、鼓励生成多样性和GPT类似的步骤&#xff1a;Conversational APR 对话式A…

模型对象CSS2DObject始终在画布的左上角(问题解决)

写了个简单案例模拟一下这个问题&#xff0c;看下图片 下面看下c2渲染器相关代码部分 this.css2DRenderer new CSS2DRenderer(); this.css2DRenderer.render(this.scene, this.camera); this.css2DRenderer.setSize(width, height); this.css2DRenderer.domElement.style.pos…

C/C++计算表达式值 2020年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C计算表达式值 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C计算表达式值 2020年12月 C/C编程等级考试一级编程题 一、题目要求 计算(ab)*(c-b)的值 1、编程实现 给定3个整数a、b、c&…

MYSQL批量插入并发场景下的DEADLOCK

一、背景 公元2023-10-12(周四)上午&#xff0c;组内的亚梅反馈&#xff0c;用户生成标签报死锁异常 二、排查异常日志 查到当时报错的日志 具体异常信息如下 server-provider-info-2023-10-12.0.log:2023-10-12 09:40:50.593 [TID:bf623bded189486cbb0b6a64d81b64b4.357.16970…

【C语言】memmove()函数(拷贝重叠内存块函数详解)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 一.memmove()函数简介 1.函数功能 2.函数参数 1>.void * destination 2>.onst void * source 3>.size_t num 3.函数返回值 4.函数头文件 二.memmove()函数…

【爬虫】charles手机抓包环境设置(设置系统证书)

1.说明 想要对手机抓包&#xff0c;最关键的是需要设置好根证书&#xff0c;用户证书在安卓7.0之后就不受信任了&#xff0c;想要对手机app抓包&#xff0c;就需要把用户证书设置为系统证书&#xff08;根证书&#xff09; 注意&#xff0c;想要设置为根证书&#xff0c;你的…

JavaScrip的DOM接口

JavaScript的DOM&#xff08;Document Object Model&#xff09;是一种接口&#xff0c;它允许程序和脚本动态地访问和更新文档的内容、结构和样式。DOM是一种将HTML或XML文档表示为对象树的标准方式。 在JavaScript中&#xff0c;DOM提供了一种方式来操作HTML或XML文档的元素…

基于nodejs+vue人脸识别考勤管理系统的设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

unocss和tailwindcss css原子引擎

第一种tailwindcss&#xff1a; tailwindcss官网 https://tailwindcss.com/docs/grid-column 基本介绍及优点分析 Tailwind CSS 中文文档 - 无需离开您的HTML&#xff0c;即可快速建立现代网站 PostCss 处理 Tailwind Css 基本流程 PostCSS - 是一个用 JavaScript 工具和插…

分享Keil5设置忽略编译过程中的警告

Keil5忽略编译过程中的警告 分享Keil5设置忽略编译过程中的警告 分享Keil5设置忽略编译过程中的警告 加上这段字符就好了 --diag_suppress68 --diag_suppress111 --diag_suppress188 --diag_suppress223 --diag_suppress546 --diag_suppress1295实测有效

Vue3-02_Vue基础入门

背景 这里&#xff0c;跟vue官网的介绍章节稍有差异。官网上侧重组件原理&#xff0c;从浅到深介绍各种组件。后续是系统生态。 教程上更偏路线化&#xff0c;需要用到的优先讲解。完成综合案例。所以我主要按照教程的思路来进行学习。 ◆ 能够知道 vue 的基本使用步骤 ◆ 掌…

知识图谱相关的操作

微软生成自己的图谱&#xff1a;GitHub - microsoft/SmartKG: This project accepts excel files as input which contains the description of a Knowledge Graph (Vertexes and Edges) and convert it into an in-memory Graph Store. This project implements APIs to searc…

SSH安全登录远程主机

SSH服务器简介 SSH即Security SHell的意思&#xff0c;它可以将连线的封包进行加密技术&#xff0c;之后进行传输&#xff0c;因此相当的安全。 SSH是一种协议标准&#xff0c;其目的是实现安全远程登录以及其它安全网络服务。 SSH协定&#xff0c;在预设的状态下&#xff0c;…

计算机网络重点概念整理-第一章 计算机网络概述【期末复习|考研复习】

第一章 计算机网络概述 【期末复习|考研复习】 计算机网络系列文章传送门&#xff1a; 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称&缩写 文章目录 第一章 计算机网络概述 【…