51 点阵屏

51 点阵屏

文章目录

  • 51 点阵屏
    • 显示原理
      • 开发板上的点阵屏
        • 74HC595的工作方式
      • sfr和sbit关键字
    • 点亮点阵屏
      • 简单运用74HC595
      • 显示笑脸
      • 模块化点阵屏
      • 显示动态图像

LED点阵屏由若干个独立LED以阵列的形式排列构成,

根据颜色分类有单色、双色(红+绿,一起亮为黄)、全彩;

根据像素分类有8*8、16*16等(点阵可以拼接,大规模的LED点阵通常由很多个小点阵拼接而成)(可以是任意像素,但是一般是8的倍数,因为一个字节是8倍,使字节每一位被充分利用)

显示原理

LED显示屏的连接方式类似于数码管,都是将每行、列的LED以共阳/共阴的方式进行连接

单色点阵屏的连接方式(图源:B站普中科技视频截图)

51 点阵屏_第1张图片

点阵屏上LED的引脚有可能是按最近引脚引出,因此可能是乱序排列

共阴还是共阳对单色点阵影响不大,但对双色或是彩色存在明显影响(电流的输入输出的设置不同)

双色点阵屏的连接方式(图源:B站江协科技视频截图)

51 点阵屏_第2张图片

和数码管一样,点阵屏的图像显示也是通过不断扫描来实现的,扫描方式有逐行扫描和逐列扫描。

开发板上的点阵屏

开发板上的点阵屏(图源:普中科技开发手册)

51 点阵屏_第3张图片

阴极直接连到P0,阳极利用74HC595扩展IO,实现三个IO控制8个引脚

开发板上的74HC595(图源:普中科技开发手册)

51 点阵屏_第4张图片

用P35、P36、P34来控制(跳线帽的OE要接GND进行短接)

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

OE(上面带横线,低电平有效):输出使能,接低电平才输出(即接GND)

PCLK:接在P35,为寄存器时钟

SRCLR(serial clear):串行清零,会清空数据,接VCC代表不清零

SRCLK:串行时钟

SER:串行数据

OH’:用于多片级联

74HC595的工作方式

74HC595的工作方式(图源:B站江协科技视频截图)
51 点阵屏_第5张图片

左边是移位寄存器,右边是输出缓存

串行数据(数据是一个一个输出的(并行即为所有数据一起输出)输出到移位寄存器,串行时钟每给一次移位上升沿,数据输出一位,当寄存器时钟有上升沿时,将移位寄存器中的数据输出到输出缓存中

eg:输出1010 0000的流程:SRCLK、RCLK置0->SER输出1->SRCLK置1->SER中的1被移入移位寄存器->SRCLK、SER置0->SRCLK置1->1被移到第二位,0被移入寄存器->…->RCLK置1->数据由移位寄存器输出到输出缓存->所有IO同时输出(并行输出)

多片级联时,将QH’接到下一片的SER,两片共用SRCLK、RCLK,当级联的数量过大时,会出现较大延迟,印象影响使用

74HC138也可以扩展IO,但是每次只能输出一位,不能并行输出

如果不用芯片,直接将阳极接到单片机IO口用于电灯不太可行,因为单片机的IO是弱上拉(输出低电平能接受大电流,输出高电平是的电流小(相当于低电平直接到GND,高电平和GND之间有个电阻)),即输出高电平时驱动能力弱,灯会比较暗(可以接一个PNP三极管,三极管上再接一个VCC,IO控制三极管开关,输出0时VCC和LED导通(NPN型则相反))

芯片输出的电流的能力也是有限的(恒压输出),点亮的LED数量多时,亮度下降(恒流输出则可以保证亮度一致)

sfr和sbit关键字

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

​ 例:sfr P0 = 0x80;

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

sbit(special bit):特殊位声明

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

​ 声明P0寄存器的第1位

可位寻址/不可位寻址:在单片机系统中,操作任意寄存器或者某一位的数据时,必须给出其物理地址,又因为一个寄存器里有8位,所以位的数量是寄存器数量的8倍,单片机无法对所有位进行编码,故每8个寄存器中,只有一个是可以位寻址的。对不可位寻址的寄存器,若要只操作其中一位而不影响其它位时,可用“&=”、“|=”、“^=”的方法进行位操作

STC89C52RC上的寄存器(图源:普中科技开发手册)

51 点阵屏_第6张图片

点亮点阵屏

简单运用74HC595

#include 

sbit RCK = P3^5;
//位声明重新声明IO,方便使用(避免重定义,以CLK位名)
sbit SCK = P3^6;
sbit SER = P3^4;

void _74HC595_WriteByte(unsigned char Byte)
{
    unsigned char i = 0;
    for(i = 0; i < 8; i++)
    {
    SER = Byte & (0x80 >> i);//1000 0000
    //SER为一位,赋值时非0即1,即赋值任何非0数,SER = 1
    //取出最高位(第8位是1,则Byte = 0x80,如果是1,则Byte = 0)

    SCK = 1;
    SCK = 0;
    }

    RCK = 1;
    //将数据移入IO进行输出
    RCK = 0;
}


void main()
{
    SCK = 0;
    RCK = 0;
    //时钟复位
    P0 = 0;
    //接通阴极
    while(1)
    {   
        _74HC595_WriteByte(0xF0);
    }
}

显示笑脸

点阵屏在段选和位选循环的过程中,下一次段选的内容可能影响上一次位选,因此需要位清零

即:->段选->位选->位清零->段选

手动计算显示笑脸对应的位码(图源:普中科技开发手册)

51 点阵屏_第7张图片

#include 
#include"Delay.h"

sbit RCK = P3^5;
//位声明重新声明IO,方便使用(避免重定义,以CLK位名)
sbit SCK = P3^6;
sbit SER = P3^4;

#define MATRIX_LED_PORT   P0

void _74HC595_WriteByte(unsigned char Byte)
{
    unsigned char i = 0;
    for(i = 0; i < 8; i++)
    {
    SER = Byte & (0x80 >> i);//1000 0000
    //SER为一位,赋值时非0即1,即赋值任何非0数,SER = 1
    //取出最高位(第8位是1,则Byte = 0x80,如果是1,则Byte = 0)

    SCK = 1;
    SCK = 0;
    }

    RCK = 1;
    //将数据移入IO进行输出
    RCK = 0;
}

void MatrixLED_ShowColmn(unsigned char Column, unsigned char Data)
{
    _74HC595_WriteByte(Data);//选择行
    MATRIX_LED_PORT = ~(0x80 >> Column);//选择列
    Delay(1);
    MATRIX_LED_PORT = 0xff;//位清零
}

void main()
{
    SCK = 0;
    RCK = 0;
    //时钟复位
    while(1)
    {   
        //位选时按列为单位
        MatrixLED_ShowColmn(0, 0x3c);
        MatrixLED_ShowColmn(1, 0x42);
        MatrixLED_ShowColmn(2, 0xa9);
        MatrixLED_ShowColmn(3, 0x85);
        MatrixLED_ShowColmn(4, 0x85);
        MatrixLED_ShowColmn(5, 0xa9);
        MatrixLED_ShowColmn(6, 0x42);
        MatrixLED_ShowColmn(7, 0x3c);
    }
}

模块化点阵屏

#include 
#include "Delay.h"

#define MATRIX_LED_PORT   P0

sbit RCK = P3^5;
//位声明重新声明IO,方便使用(避免重定义,以CLK位名)
sbit SCK = P3^6;
sbit SER = P3^4;


/**
 * @brief 74HC595写入一个字节
 * @param Byte 要写入的字节
 * @retval void 
 */

void _74HC595_WriteByte(unsigned char Byte)
{
    unsigned char i = 0;
    for(i = 0; i < 8; i++)
    {
    SER = Byte & (0x80 >> i);//1000 0000
    //SER为一位,赋值时非0即1,即赋值任何非0数,SER = 1
    //取出最高位(第8位是1,则Byte = 0x80,如果是1,则Byte = 0)

    SCK = 1;
    SCK = 0;
    }

    RCK = 1;
    //将数据移入IO进行输出
    RCK = 0;
}



/**
 * @brief Led点阵屏显示一列数据
 * 
 * @param Column 要选择的列,范围(0~7)
 * @param Data 选择列显示的数据,高位在上,1为亮,0为灭
 * @retval void
 */

void MatrixLED_ShowColmn(unsigned char Column, unsigned char Data)
{
    _74HC595_WriteByte(Data);//选择行
    MATRIX_LED_PORT = ~(0x80 >> Column);//选择列
    Delay(1);
    MATRIX_LED_PORT = 0xff;//位清零
}


/**
 * @brief 点阵屏初始化
 * 
 */
void MatrixLED_Init()
{
    SCK = 0;
    RCK = 0;
    //时钟复位
}

显示动态图像

我们可以通过文字取模软件自动获得需要显示的图像的位码

在“参数设置-其他设置”中可以选择横向/纵向取模、字节倒序(高位在下时用)

在“基本操作”中选择“新建图像”并设置图像的高(一般为8)和宽(合适即可),并直接用鼠标指针绘制图像

在绘制图像后,选择“取模方式-C51格式”即可生成图像对应位码

51 点阵屏_第8张图片

#include 
#include"Delay.h"
#include "MatrixLED.h"

unsigned char code Animation[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                            0xFF, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x1F, 0x15,
                            0x15, 0x1D, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x1F,
                            0x11, 0x11, 0x11, 0x1F, 0x00, 0x3D, 0x00, 0x00,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//显示的图像,在最前面加8位0,用于防止图像突然被切换,实现图像的连贯显示
//ram的空间比较小,不能存放太多数据,且这里的数据无需改变值,可以用code,将数据放入Flash,此时数据不能被更改

void main()
{
    unsigned char i = 0;
    unsigned char offset = 0;
    //偏移量
    unsigned char count = 0;
    MatrixLED_Init();
    while(1)
    {   
       for(i = 0; i < 8; i++)
       {
            MatrixLED_ShowColmn(i, Animation[i + offset]);
            //利用循环,实现一行语句点亮整个点阵屏
       }
       count++;
       if(count>10)
       //在一个状态扫描10次后,进入下一个状态(左移1位)
       {
            count = 0;
            offset++;
            //图像左移
            if(offset > 32)
            //完整显示一次图像后重置
            {
                offset = 0;
            }

       }
    }
}

你可能感兴趣的:(51单片机学习,单片机,嵌入式硬件,51单片机)