普中51单片机:LED点阵屏组成结构及实现方法详解(九)

news2024/11/23 20:39:03

在这里插入图片描述

文章目录

  • 引言
  • 什么是LED点阵屏?
  • 工作原理
  • 74HC595移位寄存器
    • 基本引脚作用
    • 级联工作原理
  • 电路图
  • 代码演示——16*16LED点阵屏轮播点亮每行LED
  • 代码演示——显示数字0
  • 代码演示——16*16游动字幕显示

引言

LED点阵屏作为一种广泛应用于现代显示技术的设备,因其能够高效、清晰地展示文字、图形和视频内容而备受青睐。它们在广告宣传、公共信息发布、交通指引、舞台背景等领域具有重要作用。本文将详细介绍LED点阵屏的工作原理、组成结构及其实现方法,以16x16点阵屏为例进行具体说明,并展示如何通过编程实现LED点阵屏的控制与显示。

什么是LED点阵屏?

LED点阵屏是一种由多个LED(发光二极管)组成的显示设备,通过控制每个LED的亮灭来实现图像和文字的显示。常见的LED点阵屏规格有8x8、16x16等,本文以16x16点阵屏为例进行讲解。根据颜色的不同,LED点阵屏可以分为单色、双色和全彩三种类型,分别适用于不同的应用场景。
在这里插入图片描述

工作原理

LED点阵屏的核心在于如何控制每个LED的亮灭。通常使用行列扫描的方法,通过快速切换行和列的电流来点亮特定的LED。为了实现这一点,常用的控制芯片包括74HC595移位寄存器和MAX7219驱动芯片。利用行线和列线的交叉点上的LED,通过编程控制这些LED的亮灭来实现图像的显示。例如,当某一行电平被拉高,某一列电平被拉低时,对应交叉点的LED就会点亮。需要进行逐行或逐列扫描,利用人眼的余晖效应进行显示。

LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以'8'字型排列而已。LED点阵与数码管一样,有共阴极和共阳级两张接法,不同的接法对应的电路结构不同。

  1. 共阳极:所有的LED阳极(正极)连接在一起,通常接到电源正极。点亮某个段时,需将相应的段的阴极(负极)接地 GND。
  2. 共阴极:所有的LED阴极(负极)连接在一起,通常接地。点亮某个段时,需将相应的段的阳极(正极)接电源正极。

在之前第四章数码管也提到的对应讲解:普中51单片机:数码管显示原理与实现详解(四)

74HC595移位寄存器

74HC595是一种常用的串行输入并行输出移位寄存器。它可以将串行数据转换为并行数据,从而控制多个LED。通过级联多个74HC595,可以控制更大规模的LED矩阵。LED点阵屏因为需要多个IO引脚,所以需要使用到74HC595芯片。

基本引脚作用

74HC595移位寄存器有三个主要引脚用于数据传输:

  • DS(数据输入):串行数据输入引脚。(引脚14)
  • SH_CP(移位时钟):每次时钟脉冲时,数据向移位寄存器中移位一位。(引脚11)
  • ST_CP(存储时钟):将移位寄存器中的数据锁存到输出寄存器中。(引脚12)

此外,还有一个 OE(输出使能) 13引脚,用于控制输出是否有效。具体根据电路图上的引脚序号进行查看和说明。在此博客中对74HC595芯片进行的讲解:深入解析74HC595移位寄存器的工作原理

级联工作原理

本次采用的时候16*16LED点阵屏作为演示,所以需要用到级联,级联工作原理与单独595芯片类似,主要分为四个步骤:

  1. 数据输入:数据通过串行输入引脚(SER)输入到第一个74HC595芯片的移位寄存器中。每个时钟脉冲(SCK)的上升沿会使移位寄存器中的数据向左移动一位,新的数据从SER输入。
  2. 数据移位:在每个时钟脉冲的上升沿,移位寄存器中的数据向左移动一位,新的数据从SER输入并进入移位寄存器的最低位。当移位寄存器填满8位数据后,继续输入的数据会从移位寄存器的最后一个位(Q7)挤出,并从串行数据出口引脚(引脚9)输出。
  3. 级联连接:将第一个74HC595芯片的串行数据出口引脚(引脚9)连接到下一个74HC595芯片的串行数据输入引脚(SER)。这样,第一个芯片移位寄存器中的数据在填满后,会自动通过引脚9传递到下一个芯片的移位寄存器中,形成级联。可以继续将下一个74HC595芯片的串行数据出口引脚连接到再下一个芯片的串行数据输入引脚,以此类推,实现多级级联。
  4. 数据锁存:当需要将移位寄存器中的数据输出到并行输出引脚时,通过输出寄存器时钟引脚(RCLK)提供一个上升沿的时钟信号。在RCLK的上升沿,移位寄存器中的数据被锁存到输出寄存器中,并通过并行输出引脚(Q0-Q7)输出。

通常将OE引脚接地(GND),确保输出引脚始终处于使能状态。低电平时使能输出,高电平时禁止输出。

电路图

博主使用的是四个74HC595芯片操作的LED点阵,操作原理相同,由74HC595电路图和LED点阵屏1616电路图可知第三片和第四片的74HC595芯片(级联)用于控制LED点阵屏1616的每一列的阴极(系统默认连接),行需要自行进行连接(第一片控制前八行的阳极,第二片控制后八行的阳极)。

  • LED点阵屏16*16电路图

在这里插入图片描述

  • 74HC595电路图

在这里插入图片描述

代码演示——16*16LED点阵屏轮播点亮每行LED

主函数中的两个循环分别控制LED点阵的前8行和后8行。每个循环中的 hc595_write_data 调用负责发送行数据和清零数据,以实现行的控制。

#include <REGX52.H>

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

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void hc595_write_data(unsigned char dat1,unsigned char dat2,unsigned char dat3,unsigned char dat4)
{
	int i = 0;
	//第四片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat4>>7;
		dat4<<=1;
		SRCLK = 0;
		DelayXms(1);
		SRCLK = 1;//产生上升沿,进行移位
		DelayXms(1);
	}
	//第三片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat3>>7;
		dat3<<=1;
		SRCLK = 0;
		DelayXms(1);
		SRCLK = 1;//产生上升沿,进行移位
		DelayXms(1);
	}
	//第二片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat2>>7;
		dat2<<=1;
		SRCLK = 0;
		DelayXms(1);
		SRCLK = 1;//产生上升沿,进行移位
		DelayXms(1);
	}
	//第一片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat1>>7;
		dat1<<=1;
		SRCLK = 0;
		DelayXms(1);
		SRCLK = 1;//产生上升沿,进行移位
		DelayXms(1);
	}
	RCK = 0;
	SRCLK = 1;//产生上升沿,进行存储输出
	RCK = 1;
}

unsigned char hc595_arrbuf[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void main()
{
	unsigned int i = 0;
	while(1)
	{
		for(i = 0;i < 8;i++)//1到8行
		{
			hc595_write_data(hc595_arrbuf[i],0x00,0x00,0x00);
			DelayXms(1000);		
			hc595_write_data(0x00,0x00,0x00,0x00);
		}
		for(i = 0;i < 8;i++)//8到16行
		{
			hc595_write_data(0x00,hc595_arrbuf[i],0x00,0x00);
			DelayXms(1000);		
			hc595_write_data(0x00,0x00,0x00,0x00);
		}
	}
}

代码演示——显示数字0

这段代码是用于控制LED点阵显示数字0的程序,因为是16*16的LED点阵屏使用了四个74HC595移位寄存器进行级联。hc595_col 数组定义了显示数字0的列数据,可以使用对应取模软件进行数据获取。在单片机编程中,_nop_() 是一个非常有用的内联函数,它的作用是执行一个空操作(No Operation)。简单来说,它不进行任何实质性的操作,但会消耗一个或多个机器周期的时间。用于进行纳秒级别延时。实物图连接:SRCLK 是移位寄存器时钟引脚,连接到P3.6。RCK 是存储寄存器时钟引脚,连接到P3.5。SEK 是串行数据输入引脚,连接到P3.4。显示汉字同理。

#include <REGX52.H>
#include <intrins.h>

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

void DelayXms(unsigned int xms)	//@12.000MHz
{
	unsigned char data i, j;
	
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void hc595_write_data(unsigned char dat1,unsigned char dat2,unsigned char dat3,unsigned char dat4)
{
	int i = 0;
	//第四片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat4>>7;
		dat4<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第三片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat3>>7;
		dat3<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第二片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat2>>7;
		dat2<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第一片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat1>>7;
		dat1<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	RCK = 0;
	SRCLK = 1;//产生上升沿,进行存储输出
	RCK = 1;
}
unsigned char hc595_col[] = {0x00,0x00,0x00,0x00,0xE0,0x07,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,
0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0x10,0x08,0xE0,0x07,0x00,0x00,0x00,0x00};
unsigned char hc595_row[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void main()
{
	unsigned int i = 0;
	while(1)
	{
		for(i = 0;i < 16;i++)
		{
			hc595_write_data(hc595_row[i],hc595_row[i+16],~hc595_col[i*2],~hc595_col[i*2+1]);
			_nop_();;		
			hc595_write_data(0x00,0x00,0x00,0x00);
		}
	}
}

代码演示——16*16游动字幕显示

这段代码是游动字幕显示:Hello!字符,main 函数中的无限循环不断刷新LED矩阵的显示。通过 offset 变量控制动画的播放,每10次刷新后更新 offset,实现动画的循环播放。使用 code 关键字定义的数组存储在代码存储区,通常用于存储只读数据,如动画帧数据。MatrixLed_ShowColumn 函数根据列索引 column 决定如何显示数据。当列索引大于或等于8时,选择第9到16列;否则选择第1到8列。通过位操作选择特定的列。hc595_write_data 函数用于将数据发送到四片74HC595移位寄存器。每片595接收8位数据,通过控制 SEK 引脚发送数据位,SRCLK 引脚控制数据移位。

#include <REGX52.H>
#include <intrins.h>

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

void hc595_write_data(unsigned char dat1,unsigned char dat2,unsigned char dat3,unsigned char dat4)
{
	int i = 0;
	//第四片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat4>>7;
		dat4<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第三片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat3>>7;
		dat3<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第二片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat2>>7;
		dat2<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	//第一片595
	for(i = 0;i < 8;i++)
	{
		SEK = dat1>>7;
		dat1<<=1;
		SRCLK = 0;
		_nop_();
		SRCLK = 1;//产生上升沿,进行移位
		_nop_();
	}
	RCK = 0;
	SRCLK = 1;//产生上升沿,进行存储输出
	RCK = 1;
}

void MatrixLed_ShowColumn(unsigned char column,dat1,dat2)
{
	
	if(column >= 8)
	{
		hc595_write_data(dat1,dat2,~0x00,~(0x01<<column - 8));	
	}
	else
	{
		hc595_write_data(dat1,dat2,~(0x01<<column),~0x00);
	}
}

unsigned char code hc595_Animations_row1[] = {0x02,0xFC,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0xC0,0x20,0x10,0x10,0x10,0x20,0x40,
	0x80,0x00,0x04,0xF8,0x00,0x00,0x00,0x00,0x00,0x04,0xF8,0x00,0x00,0x00,0x00,0x00,
	0x00,0x80,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00};
unsigned char code hc595_Animations_row2[] = {0x20,0x1F,0x00,0x00,0x00,0x00,0x1F,0x20,0x00,0x07,0x19,0x21,0x21,0x21,0x21,0x11,
	0x08,0x00,0x00,0x1F,0x20,0x20,0x10,0x00,0x00,0x00,0x1F,0x20,0x20,0x10,0x00,0x00,
	0x0F,0x10,0x20,0x20,0x20,0x20,0x10,0x0F,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x00};

void main()
{
	unsigned char i,offset = 0,count = 0;
	//0到15分别对应1到16列
	while(1)
	{
		for(i = 0;i < 16;i++)
		{
			MatrixLed_ShowColumn(i,hc595_Animations_row1[i+offset],hc595_Animations_row2[i+offset]);
		}
		count++;
		if(count>=10)
		{
			count = 0;
			offset++;
			if(offset == 32)
			{
				offset = 0;	
			}
		}
	}
}

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

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

相关文章

Linux_线程的使用

目录 1、线程与进程的关系 2、线程的优缺点 3、创建线程 4、查看启动的线程 5、验证线程是共享地址空间的 6、pthread_create的重要形参 6.1 线程id 6.2 线程实参 7、线程等待 8、线程退出 9、线程取消 10、线程tcb 10.1 线程栈 11、创建多线程 12、__th…

学生信息管理系统设计

学生信息管理系统的设计是一个综合性的项目&#xff0c;涉及到数据的存储、检索、更新和删除等基本操作&#xff0c;同时也需要考虑系统的易用性、安全性和扩展性。以下是一些关键步骤和要素&#xff0c;用于指导设计这样一个系统&#xff1a; 1. 需求分析 目标用户&#xff…

wls2下的centos使用桥接模式连接宿主机网络独立静态ip

前提&#xff1a;wsl2已安装&#xff0c;可正常更新 1.在控制面板中&#xff0c;打开开启或关闭windows功能&#xff0c;将里面的 Hyper-V功能打开&#xff0c;此处涉及重启 2. 按一下win键&#xff0c;输入hy&#xff0c;上面可以看到Hyper-V Manager,点进去 3.选择右边的 Vi…

Redis系列命令更新--Redis有序集合命令

Redis有序集合&#xff08;sorted set&#xff09; &#xff08;1&#xff09;说明&#xff1a; A、Redis有序集合和集合一样也是string类型元素的集合&#xff0c;且不允许重复的成员&#xff1b;不同的是每个元素都会关联一个double类型的分数&#xff1b;redis正式通过分数…

Java语言程序设计——篇五(1)

数组 概述数组定义实例展示实战演练 二维数组定义数组元素的使用数组初始化器实战演练&#xff1a;矩阵计算 &#x1f4ab;不规则二维数组实战演练&#xff1a;杨辉三角形 概述 ⚡️数组是相同数据类型的元素集合。各元素是有先后顺序的&#xff0c;它们在内存中按照这个先后顺…

【ProtoBuf】通讯录实现(网络版)

Protobuf 还常用于通讯协议、服务端数据交换场景。那么在这个示例中&#xff0c;我们将实现一个网络版本的通讯录&#xff0c;模拟实现客户端与服务端的交互&#xff0c;通过 Protobuf 来实现各端之间的协议序列化。 需求如下&#xff1a; 客户端可以选择对通讯录进行以下操…

电脑文件恢复哪个好?分享四个建议记住常备的方法!

当我们发现电脑误删文件的时候&#xff0c;一定会感到焦虑和困惑&#xff0c;但是一味地焦虑和困惑是没有任何帮助的。我们需要保持冷静&#xff0c;然后通过以下几个方法找回。 电脑文件恢复的方法有很多&#xff0c;选对适合自己的数据恢复软件很重要&#xff0c;本文罗列了几…

引领小模型潮流!OpenAI发布功能强大且成本低的GPT-4o mini

GPT-4o mini的成本比GPT-3.5 Turbo低了超过60%&#xff0c;其聊天表现优于Google的Gemini Flash和Anthropic的Claude Haiku。该模型从周四开始对ChatGPT的免费用户、ChatGPT Plus用户和团队订阅用户开放&#xff0c;并将在下周向企业用户开放。OpenAI计划未来将图像、视频和音频…

Linux——五种IO模型

目录 一、I/O的理解 二、五种IO模型 1.阻塞式IO 2.非阻塞式IO 3.信号驱动IO 4.多路复用IO 5.异步IO 一、I/O的理解 I/O的本质就是输入输出&#xff0c;C语言的stdio&#xff0c;C的iostream&#xff0c;添加了这两个库&#xff0c;我们才能够进行printf、scanf、cin、c…

UDP网口(1)概述

文章目录 1.计算机网络知识在互联网中的应用2.认识FPGA实现UDP网口通信3.FPGA实现UDP网口通信的方案4.FPGA实现UDP网口文章安排5.传送门 1.计算机网络知识在互联网中的应用 以在浏览器中输入淘宝网为例&#xff0c;介绍数据在互联网是如何传输的。我们将要发送的数据包称作A&a…

人工智能AI合集:1、嵌入式LinuxAI开发套件OrangePI AIPRO初体验

前言 随着人工智能技术的飞速发展&#xff0c;AI已经不再是遥不可及的高科技概念&#xff0c;而是逐渐融入到我们的日常生活中。从智能手机的语音助手到家庭中的智能音箱&#xff0c;再到工业自动化和医疗诊断&#xff0c;AI的应用无处不在。然而&#xff0c;要想真正掌握并应用…

数学建模学习(111):改进遗传算法(引入模拟退火、轮盘赌和网格搜索)求解JSP问题

文章目录 一、车间调度问题1.1目前处理方法1.2简单案例 二、基于改进遗传算法求解车间调度2.1车间调度背景介绍2.2遗传算法介绍2.2.1基本流程2.2.2遗传算法的基本操作和公式2.2.3遗传算法的优势2.2.4遗传算法的不足 2.3讲解本文思路及代码2.4算法执行结果&#xff1a; 三、本文…

基于java的设计模式学习

PS &#xff1a;以作者的亲身来看&#xff0c;这东西对于初学者来说有用但不多&#xff0c;这些东西&#xff0c;更像一种经验的总结&#xff0c;在平时开发当中一般是用不到的&#xff0c;因此站在这个角度上用处不大。 1.工厂模式 1.1 简单工厂模式 我们把new 对象逻辑封装…

SpringBoot缓存注解使用

背景 除了 RedisTemplate 外&#xff0c; 自Spring3.1开始&#xff0c;Spring自带了对缓存的支持。我们可以直接使用Spring缓存技术将某些数据放入本机的缓存中&#xff1b;Spring缓存技术也可以搭配其他缓存中间件(如Redis等)进行使用&#xff0c;将某些数据写入到缓存中间件…

【Linux】信号(signal)

目录 一、信号概念&#xff1a; 二、信号的常见状态&#xff1a; 信号递达&#xff1a; 信号未决&#xff1a; 阻塞信号&#xff1a; 忽略信号&#xff1a; 信号在内核中的表示&#xff1a; 三、信号相关函数&#xff1a; sigset_t &#xff08;类型&#xff09;&…

2024.7.19 作业

1.链表的排序 int list_sort(NodePtr L) {if(NULLL || L->len<1){printf("排序失败");return -1;}int lenL->len1;NodePtr p;int i,j;for( i1;i<len;i){for( j0,pL;j<len-i;j,pp->next){if( p->data > p->next->data ){datatype tp-&…

基于51单片机的步进电机控制系统proteus仿真

地址&#xff1a;https://pan.baidu.com/s/1jFlIJ9I5qxjW8sYKd6vrBQ?pwd9d6q 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMic…

阿里开源的音频模型_原理与实操

英文名称: FunAudioLLM: Voice Understanding and Generation Foundation Models for Natural Interaction Between Humans and LLMs 中文名称: FunAudioLLM: 人与LLMs之间自然互动的语音理解和生成基础模型 论文地址: http://arxiv.org/abs/2407.04051v3 相关论文&#xff1a;…

1、springboot3 vue3开发平台-后端-项目构建

文章目录 1. 创建项目1.1 前置环境条件1.2 项目创建 2. 模块配置2.1 父工程配置概述2.2 配置启动模块2.3 父工程相关依赖管理 1. 创建项目 1.1 前置环境条件 idea2023, jdk17 1.2 项目创建 创建父工程并删除不需要的文件目录&#xff1a; 右键父工程依次创建其他模块 最…

Java | Leetcode Java题解之第260题只出现一次的数字III

题目&#xff1a; 题解&#xff1a; class Solution {public int[] singleNumber(int[] nums) {int xorsum 0;for (int num : nums) {xorsum ^ num;}// 防止溢出int lsb (xorsum Integer.MIN_VALUE ? xorsum : xorsum & (-xorsum));int type1 0, type2 0;for (int n…