51单片机之LED点阵屏

目录

1.LED点阵屏简介

2.配置LED点阵屏代码


1.LED点阵屏简介

        LED点阵屏真的是遍布我们我们生活的每个角落,从街边的流动显示字的招牌到你的液晶显示屏,都是基于点阵屏的原理研究出来的。还有那个世界上最大的球状建筑物:MSG Sphere,也是基于LED点阵的原理实现的:

        把单色的LED换成彩色的RGB,实现幻彩般的视觉观感,这也是科技的魅力吧。

        我们单片机上的就是比较简单的一种点阵屏,它不仅仅是一些LED,我们需要了解的更多应该是怎么实现使用更少的IO口控制这个LED点阵屏。

        我们开发板上的LED点阵屏一共有16个,我们使用这些点阵屏可以制作很多有意思的东西。比如网上很火的坤坤跳舞(doge)和贪吃蛇小游戏,这里我们就来了解一下它到底是使用什么方式实现的吧。

        首先LED点阵屏和数码管还有矩阵键盘都有异曲同工之处,使用循环行列式扫描实现图像显示,然后是使用共阴共阳连接减少IO口占用。至于行列扫描,我们应该都比较熟悉了,还是一样的,这里主要介绍一下IO口的占用。

        如果说,数码管的显示数据减少IO口的方式是使用74HC138芯片实现位选,74HC245芯片实现数选,这里我们对LED点阵屏的使用也要有相应的芯片达到减少IO占用的结果,而这里我们使用的是74HC595芯片来减少IO占用。

        74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位、24位、32位等,常用于IO口扩展。

具体功能的实现像一个队列,只不过换了一种形式:

        这个是大概的实现原理的流程图:我们使用从SRC端口接入数据,当上升沿移位寄存器从0变成1的时候,从SER的数据就再进入一个,把前面得到的数据往下移1位,SERCLK变回0。当上升沿锁存寄存器RCLK置为1的时候,在整个寄存器中的数据就会全部移到和输出端相连的输出缓存处,直接输出数据,从而实现全部数据同时输出的作用。

        当当前的数据储存存满了之后,我们可以使用片级联的方法,使得再进入数据可以继续储存数据,从而实现16位32位甚至更多。

        像这样,离总输出端最近的部分再次输入数据,数据就会通过最下方传输到下一个级联的SER,为下一个级联的部分输入数据。等到上升沿锁存置为1的时候,所有的芯片都会向IO口输出数据,从而实现更多位的LED输出。

2.配置LED点阵屏代码

        这里配置一下LED点阵屏的代码

        这里可以看到我们需要配置三个引脚,RCLK,SRCLK,SER。

        我们可以把这几个引脚使用sbit重新命名一下。

这里说明一下,类似引脚这样的重命名是使用sbit和sfr两种

针对P0,P1,P2等这样的寄存器重新命名使用sfr,比如我们可以把使用LED时把P2命名成LED,即sfr LED = P2;

这样我们就可以直接对我们取的名字直接操纵,比如LED = 0xf0;

sbit针对的是一个寄存器中更加精确的位,例如P2^2,我们使用sbit LED = P2^2;就定义了单位,如果我们不重新命名,我们就要使用P2^2就只能使用P2_2 = 0;这样才可以使用,因为在头文件中定义的只有P2_2这样的形式,P2^2这样的定义意思其实就是P2寄存器中第二位的意思,这样才找到的这个位。

这里我们使用sbit重新定义这几个引脚,目的是增加代码可读性

        这里我们不能直接定义P3^5为RCLK,在头文件的184行有一个定义过的RCLK,所以我们就要使用别的名字,只要知道谁是谁就好了。

sbit RCK = P3^5;
sbit SRCLK = P3^6;
sbit SER = P3^4;

        现在开始编写函数实现输入一个8位二级制数据,使用74HC595芯片把内容写入。首先我们要知道的是,我们是使用一位一位的把数据输入到芯片SER引脚,每次需要把一位数据输入到芯片里面,我们的SERCLK就要置为高电平,然后数据才会移位,我们再把SERCLK置为0.。循环这个过程,直到我们的数据全部都进入,这个时候我们就要使用上升沿锁存RCLK置为高电平,把数据输出到缓存区。

void Write74HC595(unsigned char byte)
{
	unsigned char i = 0;
	for(i = 0;i<8;i++)
	{
		SER = byte&(0x80>>i);
		SRCLK  = 1;
		SRCLK  = 0;
	}
	RCK = 1;
	RCK = 0;
}

        这样我们调用函数,我们就可以把数据输出了。但是我们要实现点阵屏亮,还要实现一点东西:

        根据原理图我们可以知道:我们74HC595芯片输出的是LED点阵的一列A1-A8的阳极,我们还需要在K1-K8输入低电平才可以让LED点阵亮起来。

        假设我想要让一个对角线亮起来,我们就要使用循环控制行和列来实现,就好像我们的数码管的数选和位选,我们就要使用循环的形式达成。

        这里我们再实现一个函数,让我们可以通过输入列的数和输入芯片的数据,然后输出一列的对应的LED

void MartixLEDShow(unsigned char col,unsigned char byte)
{
	SRCLK  = 0;
	RCK = 0;
	Write74HC595(byte);
	P0 = ~(0x80>>(col-1));
}

然后我们调用函数:

void main()
{
	while(1)
	{
		MartixLEDShow(1,0x80);
		MartixLEDShow(2,0x40);
		MartixLEDShow(3,0x20);
		MartixLEDShow(4,0x10);
		MartixLEDShow(5,0x08);
		MartixLEDShow(6,0x04);
		MartixLEDShow(7,0x02);
		MartixLEDShow(8,0x01);
	}
}

        然后到了这里如果LED点阵还没亮,不要慌,把LED点阵旁边的跳线帽J24拔下来,插到另外两个针头上就可以了

          这样我们就可以在我们的LED上显示一个对角线的灯光了,但是我们还有一点问题,就是我们会发现:我们的LED点阵屏上有一些本来不该亮的地方亮了,其实就和前面讲过的数码管一样的原理,就是位选+数选的叠加导致上一个数选和下一个位选结合或者上一个数选和下一个位选结合然后导致显示的错误,所以我们就要做一件事:消隐。保证消除上一次的位选或者数选。

        同时,消隐会道义一点问题:就是我们的这个亮度会变暗,所以我们就要消隐前使用Delay函数把这个LED亮的时长增加,就可以实现正常亮度了。

        更改之后的函数如下:

void MartixLEDShow(unsigned char col,unsigned char byte)
{
	SRCLK  = 0;
	RCK = 0;
	Write74HC595(byte);
	P0 = ~(0x80>>(col-1));
	Delay(1);
	P0 = 0Xff;//消隐
}

        这样就实现了一个对角线的LED点阵亮。

        实现一个对角线还是比较简单的,这里我们再实现一个笑脸:

        这里实现这个笑脸,红色部分是需要点亮的地方,我们要把每一列的数据都记录在一个数组里面:

unsigned char Image[] = {0x3c,0x42,0xa9,0x85,0x85,0xa9,0x42,0x3c};

 对了,这里可以在数组名字前面加上51的关键字:code,这样我们就可以把数组的内容存储在单片机的flash缓存中了,我们也就可以写入更多的数据了:
 

unsigned char code Image[] = {0x3c,0x42,0xa9,0x85,0x85,0xa9,0x42,0x3c};

然后再在main函数里调用函数就可以实现一个笑脸了:

void main()
{
	while(1)
	{
		unsigned char i = 0;
		for(i=0;i<8;i++)
		{
			MartixLEDShow(i+1,Image[i]);
		}
	}
}

这里再封装一个函数,我们输入数组的名字+长度就可以实现调用了:

void ImageShow(unsigned char*Image,unsigned int len)
{
		unsigned char i = 0;
		for(i=0;i<len;i++)
		{
			MartixLEDShow(i+1,Image[i]);
		}
}

void main()
{
	while(1)
	{
			ImageShow(Image,8);
	}
}

        对了,这里可以使用一个软件,也是买板子的时候给的:

        这个是取模软件,我们可以自行生成想要图案,但是这个生成文字的功能需要16*16以上的点阵,这里就只使用8*8的功能:

选择新建一个8*8的图像

放大,以便操作

点击格点画图

点击生成之后复制代码到自己的数组中使用即可。

当然,还想要实现什么都可以靠自己实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GridView控件的使用(一)

GridView控件通常用于在Windows窗体或Web应用程序中显示数据表格。它是一个强大的数据绑定控件&#xff0c;能够灵活地显示和编辑数据源中的数据。 在何种情况下应使用GridView进行绑定控件&#xff1a; 显示结构化数据&#xff1a;当您需要展示一系列具有相同字段的数据记录…

机器学习 —— 使用机器学习进行情感分析 详细介绍版

机器学习 —— 使用机器学习进行情感分析 详细介绍版 机器学习 —— 使用机器学习进行情感分析 演示版 目录 一、 绪论二、 数据处理1. 构建CSV文档2. 构建模型前的思考2.1. 问题2.2. 解决方法 3. 读取数据4. 用正则表达式来进行对特定符号的剔除5. 使用口袋模型进行文本处理和…

稀碎从零算法笔记Day44-LeetCode:整数转罗马数字

题型&#xff1a;贪心、模拟 链接&#xff1a; 12. 整数转罗马数字 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 …

【Springboot开发】后端代码基础框架

前言&#xff1a;主要介绍最基础的springboot开发架构 目录 1. overall2. 配置文件2.1 YAML2.2 properties2.3 配置文件加载顺序2.4 多配置文件 3. 代码包3.1 infrastructure3.1.1 persistence 3.2 application3.2.1 dto3.2.2 converter3.2.3 service 3.3 api3.3.1 vo3.3.2 req…

go websocket

WebSocket 是一种网络协议&#xff0c;建立在 HTTP 协议之上&#xff0c;允许双向通信。WebSocket 协议允许服务器发送数据到客户端&#xff0c;同时也可以让客户端向服务器发送数据。WebSocket 使用 HTTP 协议的升级请求和响应来建立连接。WebSocket 的主要优点在于它可以通过…

【JavaSE】接口 详解(下)

前言 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 接口实例运用 代码举例理解 比较对象的年龄 比较对象的姓名 利用冒泡排序实现Array.sort 年龄比较器 姓名比较器 比较示例测试 clone接口 浅拷贝和深拷贝 浅…

代码随想录学习Day 26

332.重新安排行程 题目链接 from collections import defaultdictclass Solution:def findItinerary(self, tickets):targets defaultdict(list) # 创建默认字典&#xff0c;用于存储机场映射关系for ticket in tickets:targets[ticket[0]].append(ticket[1]) # 将机票输入…

GlusterFS分布式存储

目录 前言 一、GlusterFS分布式存储概述 1、GFS概念 2、GFS特点 3、GFS术语 4、GFS构成 5、GFS工作流程 6、后端存储如何定位文件 7、GlusterFs的卷类型 7.1 Distributed Volume&#xff08;分布式卷&#xff09; 7.2 Striped Volume&#xff08;条带卷&#xff09…

【JavaEE初阶系列】——网络初识—TCP/IP五层网络模型

目录 &#x1f6a9;网络的发展史 &#x1f388;局域网LAN &#x1f388;广域网WAN &#x1f6a9;网络通信基础 &#x1f388;IP地址 &#x1f388;端口号 &#x1f388;协议类型 &#x1f388;五元组 &#x1f6a9;协议分层 &#x1f388;什么是协议分层 &#x…

Web前端-Ajax

Ajax 概念:Asynchronous JavaScript And XML,异步的JavaScript和XML。 作用: 1.数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。 2.异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等…

TryHackMe - HTTP Request Smuggling

学完、打完后的复习 HTTP 1 这部分比较简单&#xff0c;直接略过 HTTP2请求走私 首先要了解HTTP2的结构&#xff0c;与HTTP1之间的一些差异 HTTP2中不再使用CRLF来作为字段的边界限定&#xff0c;而是在二进制中直接通过长度、名字、值长度、值&#xff0c;来确认边界 而这…

Leetcode算法训练日记 | day21

一、二叉搜索树的最小绝对差 1.题目 Leetcode&#xff1a;第 530 题 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,…

不到6毛钱的I2C总线实时时钟日历芯片LK8563

前言 8563实时时钟芯片&#xff0c;国内外均有多家生产&#xff0c;今推荐一个性价比极高的RTC芯片&#xff0c;LK8563&#xff0c;一片不到6毛钱. 特点 基于32.768kHz晶体的秒&#xff0c;分&#xff0c;小时&#xff0c;星期&#xff0c;天&#xff0c;月和年的计时 带有世…

Redis系列之基于Linux单机安装

Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语言的 API。最近学习需要用到Redis&#xff0c;所以就去Linux服务器上部署一个&#xff0c;做下记录&#xff0c;方便…

web安全学习笔记【22】——文件上传(1)

WEB攻防-PHP应用&文件上传&函数缺陷&条件竞争&二次渲染&黑白名单&JS绕过 演示案例&#xff1a; PHP-原生态-文件上传-前后端验证PHP-原生态-文件上传-类型文件头验证PHP-原生态-文件上传-后缀黑白名单验证PHP-原生态-文件上传-解析配置&二次渲染…

JUC 线程及创建线程

最近想再系统地复习一遍并发&#xff0c;随便再把以前整理的笔记整理为博客。 概念 了解线程前先要了解一下进程&#xff0c;进程是程序的一次执行过程&#xff0c;是系统运行的基本单位&#xff0c;其可以拥有资源&#xff0c;一个进程在执行期间会执行一系列的命令。 什么…

华为OD机试真题-模拟数据序列化传输 -2024年OD统一考试(C卷)

题目描述: 模拟一套简化的 序列化只 传输方式,请实现下面的数据编码与解码过程 1、编码前数据格式为 [位置,类型,值],多个数据的时候用逗号分隔,位置仅支持数字,不考虑重复等场景;类型仅支持:Integer/String/Compose(Compose的数据类型表示该存储的数据也需要编码) 2.编码…

【攻防世界】Confusion1

php的标志是大象&#xff0c;Python的标志是蛇 。Python 的 Flask 框架( Flask 使用 Jinja2 作为模板引擎 ) 点进register.php 输入{{3*4}} 输入 {{config}} 也有回显&#xff0c;ssti 判断是否存在ssti注入&#xff1a; 1. {{8*8}} 2. {{config}} 过滤了关键字&#xff0…

二、显示图片、提取边缘特征并保存(C# + OpenCV)

实现功能&#xff1a; 1&#xff0c;打开照片&#xff0c;并显示 2&#xff0c;对选择的照片进行Canny边缘检测 3&#xff0c;保存边缘检测之后的结果 一、布局 打开在视图下打开工具箱 选择一个PictureBox&#xff0c;仨Button 对Button改个名字 仨Button&#xff0c;分别…

Python从0到100(十二):函数的定义及模块

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…