10.LED点阵实验

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 数组中的数据代表着特定的显示图案序列,属于固定不变的数据。把这些数据存放在程序存储器中,既能保证数据的稳定性,又能避免因意外修改数据而引发的显示错误。
相关推荐
Lay_鑫辰10 小时前
西门子诊断-状态和错误位(“轴”工艺对象 V1...3)
服务器·网络·单片机·嵌入式硬件·自动化
无垠的广袤12 小时前
【工业树莓派 CM0 NANO 单板计算机】本地部署 EMQX
linux·python·嵌入式硬件·物联网·树莓派·emqx·工业物联网
雲烟14 小时前
嵌入式设备EMC安规检测参考
网络·单片机·嵌入式硬件
泽虞14 小时前
《STM32单片机开发》p7
笔记·stm32·单片机·嵌入式硬件
田甲14 小时前
【STM32】 数码管驱动
stm32·单片机·嵌入式硬件
up向上up15 小时前
基于51单片机垃圾箱自动分类加料机快递物流分拣器系统设计
单片机·嵌入式硬件·51单片机
纳祥科技1 天前
Switch快充方案,内置GaN,集成了多个独立芯片
单片机
资料,小偿1 天前
4.1.2基于51单片机汇编语言出租车计价器proteus仿真出租车计价器,汇编语言51单片机
汇编·51单片机·proteus
单片机日志1 天前
【单片机毕业设计】【mcugc-mcu826】基于单片机的智能风扇系统设计
stm32·单片机·嵌入式硬件·毕业设计·智能家居·课程设计·电子信息
松涛和鸣1 天前
从零开始理解 C 语言函数指针与回调机制
linux·c语言·开发语言·嵌入式硬件·排序算法