【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】

8*8 LED矩阵第一个灯

为了提升软件编码能力,不愿当码农的码农发起向软件工程师征程的号角,学习硬件,首先从简单的51开始,慢慢扩展知识点。

看了几节基础视频,LED点亮的原理就是控制板子上连接LED的阳极方的电平为高电平(1),阴极为低电平(0)才能点亮,其他情况,双高,双低,接反的情况都不能正常工作。


首先上图(我的51版型号是HC6800-ES),此次学习的是8*8矩阵LED模块,74HC595芯片。
【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第1张图片

上图中画圈的地方是控制74HC595的OE引脚的电平,OE位低电平时(重要),74HC595芯片输出正常。

8*8LED矩阵是通过74HC595芯片和P0 I/O口(8个I/O口)控制。如上图所示,P0口控制显示列, D0-D7(595芯片的输出口)控制行,相交处为一个LED点。


此款单片机的8*8LED模式

【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第2张图片

可以看到,阳极接到D0-D7,阴极接到P0^0-P0^7口,要让某个LED点亮,例如左上角第一个,只需让D7=1(高电平),D0-D6=0P0^7=0(低电平),P0^0-P0^6=1即可(这里=0也可以,由于D0-D6=0,LED阳极方向低电平,电流总是不通)。 P0口可以直接控制,使P0=0x7f(0111 1111)即可。

下面讲解如何控制D0-D7。


74HC595串行输入,并行输出

我理解串行输入就是一次次输入一个0或者1,最后输出的时候输出8位的数比如 1001 0110。

【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第3张图片

重要的地方:

  • 595芯片只有一个输入口,即P34 I/O口,对应图中的SER,引脚号时14
  • P36,对应图中SRCLK,引脚号是11,它的作用是,每当它发生一次上升沿,则P34口的电平值会在位移寄存器中左移一位。当下一次上升沿发生时,移位寄存器的所有位都往左移一位。
  • P35,对应图中RCLK,引脚号12,当它发生一次上升沿,移位寄存器的值会输出到DA-DH(D0-D7),这里注意一下,D7是高位。
  • 由于移位寄存器是一直往左移,那么第一个进入移位寄存器的就是最高位,所以,P34第一个值是高位。

请看下面两张图对照。

程序说明:

【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第4张图片

spi_shcp对应引脚号是11,P36口,SRCLK。
spi_ds对应引脚号是13,P34口,SER。
spi_stcp对应引脚是12,P35口,RCLK。

引脚说明

【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第5张图片

SHCP对应P36,STCP对应P35,DS对应P34。

我们可以得出结论:595芯片是通过P3^4,P3^5,P3^6进行输入输出。

为了有助于理解(假如我们要通过595芯片输出 1000 0000),我模拟过程如下:

  • 第一次:
    1. P3^4=1*(P34是一个I/O口,只能有0或者1)*;
    2. 让P3^6发生一次上升沿(P3^6初始位0),P3^6=1;
    3. 移位寄存器里面值为1;
  • 第二次:
    1. 让 P3^4=0;
    2. P3^6发生一次上升沿,P3^6=0*(之前发生过上升沿,需要重置为0)*,P3^6=1;
    3. 移位寄存器里面值为10;
  • 第三次:
    1. 让 P3^4=0;
    2. P3^6发生一次上升沿,P3^6=0;P3^6=1;
    3. 移位寄存器里面值为100;
  • 循环8次后,移位寄存器里面的值为1000 0000

  • 最后,通过P3^5的上升沿(P3^5=0;P3^5=1),移位寄存器中的值会被输出到D0-D7,最后D7=1,D0-D6=0;

(我的理解是这样,实际运行我不太懂)

教程代码如下:

#include "reg51.h"
#include

typedef unsigned int u16;  //无符号的2个字节  51单片机int占2字节
typedef unsigned char u8;  //无符号的1个字节

sbit SRCLK=P3^6;    // P3^6 IO口 SHCP
sbit RCLK=P3^5;     // P3^5 IO口 STCP
sbit SER=P3^4;      // P3^4 IO口 DS


void Hc595SendByte(u8 dat) 
{
    u8 a;
    SRCLK=0;
    RCLK=0;
    for(a=0;a<8;a++)  // 8次循环
    {
        SER=dat>>7;  //DS等于传入值的最高位
        dat<<=1;   //最高位获取过了,将最高位移除,这一次的次高位位下次最高位

        SRCLK=1;  //SHCP 上升沿
        _nop_();  //intrins.h中的方法。
        _nop_();
        SRCLK=0;  // SHCP 下降沿,什么都不会发生
    }

    RCLK=1;  // STCP上升沿,移位寄存器的数据输出
    _nop_();
    _nop_();
    RCLK=0; // STCP下降沿,移位寄存器的数据输出
}


void main()
{       
    Hc595SendByte(0x80);  //1000 0000 控制第一行的led
    P0=0x7f;  // 0111 1111 控制第一列led
    while(1);       
}

编译后,烧录到单片机中的效果。
【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第6张图片

为什么这里左边一列全部都亮了,预测效果应该是之亮第一列,第一个led,一开始我也是看了好久,以为代码错了,或者是595芯片的原理没有掌握好,最后我还是发现,原来一开始我的板子JOE (对应引脚是13,文档里面的OE) 接到了VCC,也就是高电平,OE在文档里面说明的是低电平才可以正常输出(但是为啥是一列全亮我也没搞明白),所以我重新将OE介入GND,此时就位低电平正常了,重新按下电源,一切正常了。

【51单片机】【8*8 LED矩阵如何开发】【点亮一个led却出现一列全部点亮问题解决】_第7张图片

你可能感兴趣的:(学习,问题解决,C语言)