【51单片机】LED点阵屏(江科大)

9.1LED点阵屏

1.LED点阵屏介绍

LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。

2.LED点阵屏工作原理

LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以"8"字型排列而已。原理图如下

每一行的阳极连在一起,每一列的阴极连在一起

LED点阵屏需要进行逐行或逐列扫描(扫描的速度很快),才能使所有LED同时显示

例如,要想显示第二行第二列的LED灯,只需将DPg置1,其余行置0,P06置0,其余列置1,即可

尽管使用8*8的矩阵来控制64个LED等,但16个10口还是比较多的,并且也不能直接使用16个10口,因为本单片机IO口输出是弱上拉的,

输出高电平的电流较小,输出低电平的电流较大(正常),所以如果直接用16个10口的话,LED点阵屏的每一行的输出的电流较小,会使每个的灯光较暗。

于是本开发板使用了74HC595模块来控制A1-A8这8行的I0口,74HC595模块原理图如下,使用P34、P35、P36三个10口来控制8个10口

的输出。J24模块在LED点阵屏的左上方。

3.74HC595

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

等,常用于IO口扩展。

OE:输出使能,低电平有效,接GND,即使用跳线帽将J24的OE和GND连起来

RCLK:寄存器时钟

SRCLR:串行清零,接VCC,表示不清空数据

SRCLK:串行时钟,用于输入串行数据

SER: 串行数据输入端

QH':用于多片级联,接到下一个74HC595的SER口

74HC595工作原理:

74HC595工作原理简图如下:

该模块可用于数据串行输入,并行输出

左边是个移位寄存器,SER输入一位数据,SERCLK在上升沿到来时,将移位寄存器的数据向下移动一位,之后SER再输入一位数据,在SERCLK时钟的上升沿时移位,数据填满移位寄存器后,在RCLK的上升沿到来时,将该寄存器的数据复制到右边的数据缓冲寄存器中,即为输出的数据 。同时数据也可以通过QH'输出到下一个74HC595的SER口作为串行数据输入

4.开发板引脚对应关系

LED点阵屏的列直接接在IO口上,通过P0口直接输入,行通过74HC595来进行数据输入

9.2LED点阵屏显示图形

C51的sfr、sbit

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

例:sfr PO=0x80;

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

·sbit(special bit):特殊位声明

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

声明P0寄存器的第1位

·可位寻址/不可位寻址:在单片机系统中,操作任意寄存器或者某一位的数据时,必须给出其物理地址,又因为一个寄存器里有8位,所

以位的数量是寄存器数量的8倍,单片机无法对所有位进行编码,故每8个寄存器中,只有一个是可以位寻址的。对不可位寻址的寄存器,

若要只操作其中一位而不影响其它位时,可用"&="、"="、"A="的方法进行位操作

1、位声明

根据原理图,将IO口进行位声明,方面之后使用

2、74HC595写入字节函数

当i=0时,0x80为1000 0000,Byte第一位为1,SER为1;第一位为0,SER为0,即写入第一位

当i=1时,0x80>>i为0100 0000,Byte第二位为1,SER为1;第二位为0,SER为0,即写入第二位

...

SCK=1为上升沿,Byte每写入一位,向下移动一位

RCK=1为上升沿,将八位数据送到IO口

3、显示数据函数

为了消除残影,需要在函数的最后进行P0口的清零

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

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

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

顺便加一段延时过程

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

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

4、LED点阵屏显示笑脸

main.c

c 复制代码
#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;		//RCLK
sbit SCK=P3^6;		//SRCLK
sbit SER=P3^4;		//SER

#define MATRIX_LED_PORT		P0

/**
  * @brief  74HC595写入一个字节
  * @param  Byte 要写入的字节
  * @retval 无
  */
void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SER=Byte&(0x80>>i);
		SCK=1;
		SCK=0;
	}
	RCK=1;
	RCK=0;
}

/**
  * @brief  LED点阵屏显示一列数据
  * @param  Column 要选择的列,范围:0~7,0在最左边
  * @param  Data 选择列显示的数据,高位在上,1为亮,0为灭
  * @retval 无
  */
void MatrixLED_ShowColumn(unsigned char Column,Data)
{
	_74HC595_WriteByte(Data);
	P0=~(0x80>>Column);
	Delay(1);
	P0=0xFF;
}

void main()
{
	SCK=0;
	RCK=0;
	while(1)
	{
		MatrixLED_ShowColumn(0,0x3C);
		MatrixLED_ShowColumn(1,0x42);
		MatrixLED_ShowColumn(2,0xA9);
		MatrixLED_ShowColumn(3,0x85);
		MatrixLED_ShowColumn(4,0x85);
		MatrixLED_ShowColumn(5,0xA9);
		MatrixLED_ShowColumn(6,0x42);
		MatrixLED_ShowColumn(7,0x3C);
	}
}

9.3LED点阵屏显示动画

1、模块化

MatrixLED.c

c 复制代码
#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;		//RCLK
sbit SCK=P3^6;		//SRCLK
sbit SER=P3^4;		//SER

#define MATRIX_LED_PORT		P0

/**
  * @brief  74HC595写入一个字节
  * @param  Byte 要写入的字节
  * @retval 无
  */
void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SER=Byte&(0x80>>i);
		SCK=1;
		SCK=0;
	}
	RCK=1;
	RCK=0;
}

/**
  * @brief  点阵屏初始化
  * @param  无
  * @retval 无
  */
void MatrixLED_Init()
{
	SCK=0;
	RCK=0;
}

/**
  * @brief  LED点阵屏显示一列数据
  * @param  Column 要选择的列,范围:0~7,0在最左边
  * @param  Data 选择列显示的数据,高位在上,1为亮,0为灭
  * @retval 无
  */
void MatrixLED_ShowColumn(unsigned char Column,Data)
{
	_74HC595_WriteByte(Data);
	MATRIX_LED_PORT=~(0x80>>Column);
	Delay(1);
	MATRIX_LED_PORT=0xFF;
}

MatrixLED.h

c 复制代码
#ifndef __MATRIX_LED_H__
#define __MATRIX_LED_H__

void MatrixLED_Init();
void MatrixLED_ShowColumn(unsigned char Column,Data);

#endif

2、利用文字取模软件生成图像数据

点击"基本操作",再点击"新建图像",高度选8,宽度随意,这里选32

之后点击"参数设置",再点击"其他选项",在这里选择纵向取模,不选择字节倒序,其余不变

点击"模拟动画",再点击"放大格点",将图像进行放大

描绘自己想要的图像

点击"取模方式",选择C51格式,将生成的数据保存

3、保存图像数据

将数据保存在数组中,数组的每一个元素表示一列LED的数据

main.c

c 复制代码
#include <REGX52.H>
#include "Delay.h"
#include "MatrixLED.h"

//动画数据
unsigned char code Animation[]={
	0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
	0x3C,0x42,0xA1,0x85,0x85,0xA1,0x42,0x3C,
	0x3C,0x42,0xA5,0x89,0x89,0xA5,0x42,0x3C,
};

void main()
{
	unsigned char i,Offset=0,Count=0;
	MatrixLED_Init();
	while(1)
	{
		for(i=0;i<8;i++)	//循环8次,显示8列数据
		{
			MatrixLED_ShowColumn(i,Animation[i+Offset]);
		}
		Count++;			//计次延时
		if(Count>15)
		{
			Count=0;
			Offset+=8;		//偏移+8,切换下一帧画面
			if(Offset>16)
			{
				Offset=0;
			}
		}
	}
}

Animation数组是存储在RAM中,当要显示的图像很多时,数据量会很大,RAM可能会不够,所以可以将数据保存在Flash里面,

在char后面添加一个code就行。但是定义之后便不能更改(ROM的特性)。

c 复制代码
unsigned char code Animation[]={};
相关推荐
学习路上_write18 分钟前
FPGA/Verilog,Quartus环境下if-else语句和case语句RT视图对比/学习记录
单片机·嵌入式硬件·qt·学习·fpga开发·github·硬件工程
非概念24 分钟前
stm32学习笔记----51单片机和stm32单片机的区别
笔记·stm32·单片机·学习·51单片机
iiiiiankor1 小时前
C/C++内存管理 | new的机制 | 重载自己的operator new
java·c语言·c++
小辛学西嘎嘎1 小时前
C/C++精品项目之图床共享云存储(3):网络缓冲区类和main
c语言·开发语言·c++
jjjxxxhhh1232 小时前
FPGA,使用场景,相比于单片机的优势
单片机·嵌入式硬件·fpga开发
无敌最俊朗@2 小时前
stm32学习之路——八种GPIO口工作模式
c语言·stm32·单片机·学习
EterNity_TiMe_2 小时前
【论文复现】STM32设计的物联网智能鱼缸
stm32·单片机·嵌入式硬件·物联网·学习·性能优化
2301_799084673 小时前
超全排序C语言实现
c语言·数据结构·算法·排序算法
changingshow3 小时前
Arduino IDE Windows 系统 离线安装 esp32 开发板 亲测好用。
单片机·嵌入式硬件
7yewh5 小时前
嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻
驱动开发·stm32·嵌入式硬件·mcu·物联网·硬件架构·pcb工艺