第12章 LED点阵实验

第十二章 LED点阵实验

1. LED点阵介绍

LED 点阵是由发光二极管排列组成的显示器件,比如:

通常应用较多的是 8x8 点阵, 然后使用多个 8x8点阵可组成不同分辨率的 LED点阵显示屏, 比如 16x16 点阵可以使用 4 个 8x8 点阵构成。 因此理解了 8x8 LED点阵的工作原理, 其他分辨率的 LED 点阵显示屏都是一样的。 这里以 8x8LED 点阵来做介绍。 其内部结构图如下所示:

当对应的某一行置 1 电平, 某一列置 0 电平, 则相应的二极管就亮;如要将第一个点点亮, 则 1 脚接高电平 a 脚接低电平, 则第一个点就亮了; 如果要将第一行点亮, 则第 1 脚要接高电平, 而( a、 b、 c、 d、 e、 f、 g、 h ) 这些引脚接低电平, 那么第一行就会点亮; 如要将第一列点亮, 则第 a 脚接低电平,而( 1、 2、 3、 4、 5、 6、 7、 8) 接高电平, 那么第一列就会点亮。 由此可见, LED点阵的使用也是非常简单的。

2. 硬件设计

本实验使用到硬件资源如下:

  • 16*16LED 点阵模块

  • 74HC595 模块

74HC595 模块、 16*16LED 点阵模块电路在前面章节都介绍过, 电路如下:

从上图中可以看出, 该电路是独立的, 74HC595 模块内使用了 4 块 74HC595芯片, 它们采用了级联方式, 即 RCLK 和 SRCLK 管脚并联在一起, 并且 74HC595 ( A) 的输出 QH 非连接到 74HC595( B) 的串行输入口 SER, 而 74HC595( B) 的输出 QH 非又连接到 74HC595( C) 的串行输入口 SER, 依次类推。 并且每块芯片的输出端都连接到对应的端子上, 74HC595( A) 的输出连接到 J27 端子, 74HC595 ( B)的输出连接到 J32 端子, 74HC595( C)的输出连接到 LED 点阵前 8 列, 74HC595 ( D) 的输出连接到 LED 点阵后 8 列。 图上的 NEGx 是网络标号, 与 LED 点阵列相连。 74HC595 需要用到的控制管脚 RCLK、 SRCLK、 SER 并未直接连接到 51 单片机的 IO 上, 而是连接到 J24 端子上。

如果要想 51 单片机能够控制 74HC595 输出数据, 就必须将单片机管脚通过导线连接到 J24 端子上。 因此需使用 3 根杜邦线将单片机的管脚与 J24 端子连接。由于 74HC595 模块电路是独立的, 所以使用任意单片机管脚都可以, 为了与我们例程程序配套, 这里使用 P3.4-P3.6 管脚来控制 74HC595 输出数据, 将 74HC595 ( A) 的输出端子 J27 连接在点阵模块行端口 J28 上, 将 74HC595( B) 的输出端子 J32 连接在点阵模块行端口 J34 上, 即行为 LED 发光二极管的阳极, LED 点阵的列则为发光二极管的阴极。

要想控制 LED 点阵, 可以将单片机管脚按照 74HC595 芯片的通信时序要求来传输数据, 因为使用了 4 片 74HC595 芯片, A/B 两块控制点阵行 POS1-POS16, C/D两块控制点阵列 NEG1-NEG16。 这样即可控制 LED 点阵。 根据 LED 发光二极管导通原理, 当阳极为高电平, 阴极为低电平则点亮, 否则熄灭。 因此通过单片机发送 4 组数据, 通过 595 将这四组数据分配到对应输出从而控制 LED 点阵。

3. 软件设计

3.1 LED点阵(点亮一个点)

代码很简单, 与上一章核心代码是一样的, 这里主要是理解如何让 LED 点阵的左上角第一个点点亮, 实际上就是将第一个点对应的行为高电平, 列为低电平即可。 也就是让第一个 74HC595 输出 0X01( 0000 0001) , 这样点阵第一行就是高电平, 而第 3 个 74HC595 输出 0XFE( 1111 1110) , 第 4 个 74HC595 输出 0XFF ( 1111 1111) , 这样点阵第一列就是低电平, 从而让 LED 点阵第一个点点亮。

#include "reg51.h"

//定义74HC595控制管脚
sbit SRCLK = P3^6; // 移位寄存器时钟输入
sbit RCLK = P3^5; // 存储寄存器时钟输入
sbit SER = P3^4; // 串行数据输入

// 延时函数
void delay_10us(unsigned int ten_us)
{
    while(ten_us--);    
}

/*
写入数据函数
向74HC595写入4个字节的数据
dat1:对应74HC595(A)输出第1行-第8行
dat2:对应74HC595(B)输出第9行-第16行
dat3:对应74HC595(C)输出第1列-第8列
dat4:对应74HC595(D)输出第9列-第16列
*/
void hc595_write_data(unsigned char dat1, unsigned char dat2, unsigned char dat3, unsigned char dat4)
{
    // 循环8次即可将一个字节写入寄存器中,因为一个字节有8位 1bit = 8byte
    unsigned char i = 0;

    // 重点理解这个,后面同理
    for(i = 0; i < 8; i++) // 循环8次即可将一个字节写入寄存器中
    {
        SER = dat4 >> 7; // 优先传输一个字节中的高位
        dat4 <<= 1; // 将低位移动到高位
        /*
        在 74HC595 移位寄存器中,SRCLK 控制移位寄存器的时钟信号。
        当 SRCLK 信号从低电平切换到高电平时,数据会被移入移位寄存器的内部寄存器中的下一个位置。
        */
        SRCLK = 0; // 时钟拉低,准备写入数据
        delay_10us(1);
        SRCLK = 1; // 时钟拉高,写入数据结束
        delay_10us(1);    
    }

    // 看了上面那个例子,下面就是照葫芦画瓢了
    for(i = 0; i < 8; i++)
    {
        SER = dat3 >> 7;
        dat3 <<= 1;
        SRCLK = 0;
        delay_10us(1);
        SRCLK = 1;
        delay_10us(1);    
    }

    for(i = 0; i < 8; i++)
    {
        SER = dat2 >> 7;
        dat2 <<= 1;
        SRCLK = 0;
        delay_10us(1);
        SRCLK = 1;
        delay_10us(1);    
    }

    for(i = 0; i < 8; i++)
    {
        SER = dat1>>7;
        dat1 <<= 1;
        SRCLK = 0;
        delay_10us(1);
        SRCLK = 1;
        delay_10us(1);    
    }

    RCLK = 0; // 将存储寄存器时钟引脚设置为低电平,这样在移位寄存器的数据还未准备好或者还未完成移位操作时,不会触发存储寄存器的时钟上升沿
    delay_10us(1);
    RCLK = 1; // 将存储寄存器时钟引脚设置为高电平,这个操作触发了存储寄存器时钟的上升沿,将移位寄存器中的数据复制到存储寄存器中。
}

void main()
{    
    unsigned char i = 0;

    while(1)
    {            
        hc595_write_data(0x01, 0x00, 0xfe, 0xff); // 将LED点阵上边第一行设置为1,即LED阳极为高电平,其余行为0,即低电平            
        // 0x01 转换成二进制就是0000 0001
        // 0x00 转换成二进制就是0000 0000
        // 0xfe 转换成二进制就是1111 1110
        // 0xff 转换成二进制就是1111 1111    

        /*
        那么这么设置为什么就可以点亮LED点阵上边第一行的第一个LED呢?
        因为74HC595的输出端有16个,对应LED点阵的16个LED,所以我们只需要设置第一个LED的输出端为高电平即可。
        所以我们设置0x01,即第一个字节的最高位为1,其余位为0,这样74HC595的输出端就会点亮第一个LED。
        dat1dat2管理的是行,我们已经理解了,但是dat3dat4管理的是列,怎么理解,又为什么设置为0xfe,0xff呢?
        第三个字节0xfe,对应74HC595的列控制,使第一列LED点亮,其余列灭。
        第四个字节0xff,虽然在这个设置中未直接使用到,但通常用于保持其他列的状态,确保其它LED保持亮或灭的状态。

        我们可以简单的理解为行高电平,列低电平,这样就可以点亮LED点阵上边第一行的第一个LED。
        比如我们这里就是第1行为1,第1列为0,如此就可以点亮啦。

        举一反三:我们想点亮第二行第二列的led(就是行0000 0010和列1111 1101嘛)
        hc595_write_data(0x02, 0x00, 0xfd, 0xff)
        */                
    }        
}

后面显示汉字,显示数字,显示图像三个实验由于内容过多,大部分重复就不再此处展示,可以在工程文件中自行查看

4. 小结

实现LED点阵点亮某一个灯还是很简单的,把上一章的代码直接拿来,现在我们就有了控制的权力,那么如何控制才能点亮目标呢?实验中我们点亮左上角的一个,那么就是A11,即第一行第一个,我们知道,LED点阵点亮的条件是行为低电平列为高电平,那么我们就可以用我们的hc595_write_data()函数,给第一行0x01(000 0001)给第一列0xfe(1111 1110),我们看到就对应起来啦,如此A11成功点亮

关于显示汉字和动画,可以参考工程文件


2024.8.20 第一次修订,后期不再维护

posted @ 2024-08-20 09:31  hazy1k  阅读(6)  评论(0编辑  收藏  举报