10.LED点阵实验

发布于:2025-03-04 ⋅ 阅读:(14) ⋅ 点赞:(0)

        LED点阵是一种由发光二极管排列而成的显示器件,在生活里的各种电器中很常见,像汽车报站器和广告屏等地方都会用到它。

        平时用得比较多的是 8×8 点阵。多个 8×8 点阵能组合成不同大小的 LED 点阵显示屏,比如 4 个 8×8 点阵可以拼成一个 16×16 点阵。只要懂了 8×8LED 点阵是怎么工作的,其他大小的 LED 点阵显示屏原理也就差不多了。下面就来讲讲 8×8LED 点阵。

        8 x 8点阵里一共有64个发光二极管,这些二极管都放在行线和列线交叉的地方。要让某个二极管亮起来,,只要让对应的哪一行接上1电平(也就是高电平,相当于有电),那一列接上0电平(也就是低电平,相当于没有电)就行。   

        举个例子,要是想点亮第一个点,把 1 脚接上高电平,a 脚接上低电平,这个点就会亮了。

        要是想点亮第一行,那就把第 1 脚接上高电平,然后把(a、b、c、d、e、f、g、h )这些引脚都接上低电平,这样第一行的所有点就都亮起来了。

        要是想点亮第一列,把第 a 脚接上低电平,再把(1、2、3、4、5、6、7、8)这些引脚都接上高电平,第一列的点就都亮了。        

        所以说,LED 点阵用起来其实并不难,只要控制好行和列的电平高低,就能让它按我们的想法显示出不同的图案或者文字。      

 1.8x8LED和74HC595

        8*8LED 点阵模块由 8 行 8 列共 64 个发光二极管组成,这些二极管整齐排列在点阵之上,通过控制行与列的电平,就能实现不同二极管的亮灭,进而呈现出各种图案或文字。

        而 74HC595 模块则是一种移位寄存器芯片,它在本实验中起着至关重要的作用,主要用于协助控制 LED 点阵的行数据。

        在电路连接方面,74HC595 模块有三个关键的控制管脚,分别为 SER(串行数据输入引脚)、RCLK(存储寄存器时钟输入引脚)以及 SRCLK(移位寄存器时钟输入引脚)。这三个管脚被直接连接至 51 单片机的 P3.4 - P3.6 IO 口。当单片机向这些管脚发送不同的电信号时,就能依据 74HC595 芯片的通信时序,精准地控制数据的传输。

        74HC595 模块的输出端,与 8*8LED 点阵模块的行端口相连,由于该连接,LED 点阵模块行端口就等同于 LED 发光二极管的阳极。而 LED 点阵模块的列端口,自然就对应着发光二极管的阴极。

        在实际控制过程中,要实现对 LED 点阵的有效操控,我们需要严格依照 74HC595 芯片既定的通信时序,通过 51 单片机的相应管脚来传输数据。具体来说,当单片机按照 74HC595 芯片的通信要求,向其控制管脚发送数据时,74HC595 芯片会将接收到的串行数据,转换为并行数据输出至 LED 点阵的行端口,从而控制 LED 点阵的行数据。

        再依据 LED 发光二极管的导通原理,当阳极施加高电平,阴极施加低电平时,对应的二极管就会点亮;反之,若阳极电平低于阴极电平,二极管则熄灭。

        所以,在本实验设计里,我们利用单片机的 P0 口来控制 LED 点阵的列,通过改变 P0 口各管脚的电平高低,就能控制 LED 点阵列端口的电平状态;同时,借助 74HC595 模块来控制点阵的行,以此实现对整个 8*8LED 点阵的全面控制,让其按照我们的预期显示出各类信息。

2.显示笑脸

#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


// 向 74HC595 写入一个字节的数据
void _74HC595_WriteByte(unsigned char Byte)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        // 从高位到低位依次取出字节的每一位
        SER=(Byte & (0x80 >> i))? 1 : 0;
        // 上升沿将数据移入移位寄存器
        SCK=1;
        SCK=0;
    }
    // 上升沿将移位寄存器的数据锁存到存储寄存器
    RCK=1;
    RCK=0;	
}



// LED显示屏显示一列数据
void MatrixLED_ShowColumn(unsigned char Column, unsigned char Data)
{
    // 向 74HC595 写入数据	0~0xFF 高位在上,1为亮,0为灭
    _74HC595_WriteByte(Data);
    // 选择要显示的列	0~7
    MATRIX_LED_PORT=~(0x80 >> Column);
	Delay(1);
	MATRIX_LED_PORT=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);
    }
}

 

3.显示爱心

#include <REG51.H>

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

#define MATRIX_LED_PORT		P0
//向74HC595写入一个字节的数据
void _74HC595_WriteByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		//从高位到低位依次取出字节的每一位
		SER=(Byte&(0x80>>i))? 1:0;
		//上升沿将数据移入移位寄存器
		SCK=1;
		SCK=0;
	}
	//上升沿将移位寄存器数据锁存到存储寄存器
	RCK=1;
	RCK=0;
}
void MatrixLED_ShowColumn(unsigned char Column,unsigned char Data)
{
	//向74HC595写入数据,0~0xFF 高位在上,1为亮,0为灭
	_74HC595_WriteByte(Data);
	//选择要显示的列 0~7
	MATRIX_LED_PORT=~(0x80>>Column);
	
}
unsigned char picture[] = {0x30,0x78,0x7C,0x3E,0x3E,0x7C,0x78,0x30};
void main()
{
	//初始化时钟信号
	SCK=0;
	RCK=0;
	while(1)
	{
		unsigned char i;
		for(i=0;i<8;i++)
		{
			MatrixLED_ShowColumn(i,picture[i]);
		}
		
	}
}

 

4.单片鸡点阵屏之坤坤跳舞

main.c

#include <REGX52.H>
#include "MatrixLED.h"
unsigned char code action[]=
{
	0x00,0x03,0x24,0x58,0xA4,0x02,0x01,0x00,
	0x00,0x01,0x02,0x14,0x2C,0x56,0x01,0x00,
	0x00,0x01,0x02,0x04,0x14,0x2E,0x51,0x00,
	0x00,0x01,0x02,0x14,0x2C,0x56,0x01,0x00,
	0x00,0x03,0x24,0x58,0xA4,0x02,0x01,0x00
};
void main()
{
	unsigned char i,offset=0,Count=0;
	
  MatrixLED_Init();
	while(1)
	{
		for(i = 0;i<8;i++)
		{
			MatrixLED_ShowColumn(i,action[i+offset]);}
			Count++;
			if(Count>40)
			{
				Count=0;
				offset+=8;
				if(offset>24)
					offset = 0;
			}
		}
}

MaatrixLED.c

#include <REGX52.H>
#include "Delay.h"
 
 
sbit RCK = P3^5;
sbit SCK = P3^6;
sbit SER = P3^4;
 
#define MATRIX_LED_PORT    P0
/**
	* @brief 74HC595写入一个字节
	* @param 要写入的字节
	* @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);
	MATRIX_LED_PORT = ~(0x80>>Column);
	
}
 
void MatrixLED_Init()
{
	SCK = 0;
	RCK = 0;
}

在 51 单片机编程里,code 是一个存储类型修饰符,使用 code 来修饰 action 数组,主要基于以下几个原因:

1. 节省内部 RAM 空间

  • 51 单片机内存结构特点:51 单片机的内存资源相对有限,它的内部 RAM 空间较小(通常为 128 字节或 256 字节),并且要用于存储变量、栈空间等。
  • 数据存储位置:使用 code 修饰的数组会被存放在程序存储器(ROM)里,而非内部 RAM。像你代码中的 action 数组存有大量的显示数据,若不使用 code 修饰,这些数据就会占用内部 RAM 空间,这样可能导致内部 RAM 不够用,进而影响其他变量的存储和程序的正常运行。

2. 程序存储器读取稳定

  • ROM 特性:程序存储器(ROM)是只读存储器,其数据在程序运行期间不会被修改,数据的存储和读取十分稳定。
  • 适合存储固定数据action 数组中的数据代表着特定的显示图案序列,属于固定不变的数据。把这些数据存放在程序存储器中,既能保证数据的稳定性,又能避免因意外修改数据而引发的显示错误。