清翔零基础教你学51单片机_个人学习笔记(8)_8x8点阵屏

说明

本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。

本次笔记对应清翔视频教程的第23,24,25 8x8点阵屏(理论+实践)

目录

一、LED点阵屏简介

1.1 组成

1.2 优点

1.3 分类

1.4  实际图片

 1.5 共阳极点阵屏原理图

二、点阵屏芯片74HC595

2.1 芯片工作原理

2.2 点阵原理图

2.2.1 点阵部分

2.2.2 开发板部分

​编辑 

2.2.3 芯片总结

2.3 点阵在开发板的连接方式

三、编程

3.1 创建工程

3.2 main.c

3.3 main.h代码

3.4 现象

 3.5 封装函数

3.5.1 main.c

3.5.2 main.h

 3.5.3 main函数

3.6 再次封装

3.6.1 main.c

3.6.2 main.h

3.7 动态显示

3.7.1 原理

3.7.2 取模

3.7.3 main.c

 3.7.4 main.h

 3.7.5 现象

3.7.6 两个字符循环显示

main.c代码


一、LED点阵屏简介

1.1 组成

LED点阵屏(LED Matrix Display)是一种显示设备,由许多LED(Light Emitting Diode,发光二极管)组成的矩阵排列而成。每个LED都可以独立控制,通过控制不同LED的亮灭状态以及亮度,可以显示出各种图案、文字和动画。LED安装方便,一大块屏幕可以由很多小块拼接而成,便捷低成本,方便运输。

1.2 优点

LED点阵屏广泛应用于数字时钟、计数器、信息显示、广告牌、游戏机等领域。它们有很高的亮度、对比度和可见性,因此在各种环境下都能清晰显示内容。此外,LED点阵屏具有低功耗、长寿命、反应速度快等优点。

1.3 分类

根据LED点阵屏的特性,常见的LED点阵屏可以分为以下几种类型:

  1. 单色点阵屏:由单色LED组成,通常是红色或绿色。可以显示简单的图案和文字。

  2. 双色点阵屏:由两种颜色的LED(通常是红色和绿色)组成,可以显示更丰富的图案和文字,并支持一些简单的动画效果。

  3. 全彩点阵屏:由多种颜色的LED组成,可以显示出丰富的颜色,支持更复杂的图案、文字和动画。

为了控制LED点阵屏的显示,通常需要使用微控制器或其他驱动芯片。这些芯片提供了控制LED点阵屏的接口和功能,可以通过编程来实现所需的显示效果。

1.4  实际图片

 

 1.5 共阳极点阵屏原理图

 点亮指定位置的LED就可以显示出想要的图案,比如给⑨1,给⑬0,其余的行都为0,其余的列都为1,那么左上角的就会点亮。

如果要显示不同位置的点,需要动态扫描。同一时刻只有1个点被点亮

二、点阵屏芯片74HC595

芯片:2片74HC595级联,只需要3个IO口就可以驱动,节省IO口

2.1 芯片工作原理

以下内容均来自清翔给的文档

串行输入,并行输出

8 位串行输入/输出或者并行输出移位寄存器,具有高阻关断状态。三态。
特点
8 位串行输入
8 位串行或并行输出
存储状态寄存器,三种状态
输出寄存器可以直接清除
100MHz 的移位频率


输出能力
并行输出,总线驱动
串行输出;标准
中等规模集成电路

74595 的控制端说明:
/SCLR(10 脚): 低点平时将移位寄存器的数据清零。通常我将它接 Vcc。
SCK(11 脚):上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;下
降沿移位寄存器数据不变。(脉冲宽度:5V 时,大于几十纳秒就行了。)
RCK(12 脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄
存器数据不变。通常我将 RCK 置为低点平,当移位结束后,在 RCK 端产生一
个正脉冲(5V 时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
/G(13 脚): 高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引
脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。
注:74164 和 74595 功能相仿,都是 8 位串行输入转并行输出移位寄存器。74164
的驱动电流(25mA)比 74595(35mA)的要小,14 脚封装,体积也小一些。
74595 的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以
保持不变。这在串行速度慢的场合很有用处,数码管没有闪烁感。
与 164 只有数据清零端相比,595 还多有输出端时能/禁止控制端,可以使输出为
高阻态。

程序说明:
每当 spi_shcp 上升沿到来时,spi_ds 引脚当前电平值在移位寄存器中左移
一位,在下一个上升沿到来时移位寄存器中的所有位都会向左移一位,
同时 Q7'也会串行输出移位寄存器中高位的值,
这样连续进行 8 次,就可以把数组中每一个数(8 位的数)送到移位寄存器;
然后当 spi_stcp 上升沿到来时,移位寄存器的值将会被锁存到锁存器里,
并从 Q1~7 引脚输出

清翔PPT截图,讲的很清晰

 

2.2 点阵原理图

2.2.1 点阵部分

2.2.2 开发板部分

 

可以看到

14脚数据输入(DI)  是接在单片机的P3^4

 11输入时钟 (CLK) 接在单片机P3^5

12输出控制     (LE)     接在单片机P3^6

2.2.3 芯片总结

 14脚串行输入

9脚级联输出端,接下一个74HC595的14脚(也就是下一个74HC595的数据输入脚)

11脚 输入时钟,在它的上升沿数据从14脚串行输入。

12脚 上升沿时数据从Q0~Q7并行输出

移位寄存器:假设要发送的数据是1011 0001,从高位往低位发,过程如表

发送顺序Q1Q2Q3Q4Q5Q6Q7Q8
11
001
1101
11101
001101
0001101
00001101
110001101

 注:上方动图来源于CSDN文章:51单片机 74hc595使用用法(利用proteus仿真)

第1个发送的数据最终会被放到Q7,最后发送的数据最终会被放到Q0。如果从高位往低位发,那么最终Q7~Q0的数据就与我们发送的数据相同,如果从最低位开始发送,那么最终Q7~Q0的数据与我们实际的字节顺序相反

上升沿:从低电平到高电平的变化

下降沿:从高电平到低电平的变化

注:在视频教程中对芯片的讲解中,最先发送的位被放在了Q0,最后发送的位被放在了Q7,根据我自己查的资料以及仿真,我发现最先发送的位其实是被放在了Q7,所以在上面的分析中我也是按照最先发送的位被放在Q7位基准的。

2.3 点阵在开发板的连接方式

对应插下就行 

三、编程

3.1 创建工程

复制一份工程模板,修改名称为“8.点阵屏”,进入项目文件夹,打开工程文件

3.2 main.c

非全部代码,仅提供改变部分的代码,头问件等格式请自行补全

void main()
{
    //先发送一个b1111 1110 1000 0000看一下点亮的是哪个点
    //发送时要先发送高位,因为移位寄存器会自动把先接收到的数据放到高位上
    //定义一个字符型变量
    uchar i;
    uchar temp;
    LE = 0;
    CLK = 0;
    temp = 0xfe;    //11111110
    for (i = 0; i < 8; i++) //发送第一个字节(高8位)
    {
        DI = temp & 0x80;
        CLK = 1;
        CLK = 0;
        temp <<= 1;
    }
    temp = 0x80;    //1000 0000
    for (i = 0; i < 8; i++) //发送第2个字节(低8位)
    {
        DI = temp & 0x80;
        CLK = 1;
        CLK = 0;
        temp <<= 1;
    }
    LE = 1;     //发送完毕,打开数据输出
    LE = 0;
}

注意,我传输的数据是按照行从右往左,列从上往下的顺序,也可以按照别的顺序,只需要改变传输过程的传输方式就可以了,不要弄错位了

我的数据顺序 

 

 

 

 

3.3 main.h代码

//非全部代码,仅提供改变部分代码

typedef unsigned char uchar;
typedef unsigned int uint;


sbit DI = P3^4;
sbit LE = P3^6;
sbit CLK = P3^5;

3.4 现象

 3.5 封装函数

3.5.1 main.c

void SendDat(uchar dat)
{
    uchar i;
    LE = 0;
    CLK = 0;
    for (i = 0; i < 8; i++)
    {
        DI = dat & 0x80;
        CLK = 1;
        CLK = 0;
        dat <<= 1;
    }
}

 这样只需要把要发送的数据写在参数里面就行了

3.5.2 main.h

在main.h里面写函数的声明

void SendDat(uchar dat);

 3.5.3 main函数

在main.c里面写完函数本体,在main.h写完函数声明之后,可以开始改造main函数的内容了,现在在main函数内部调用刚才写的函数

void main()
{
    SendDat(0xfe);
    SendDat(0x80);
    LE = 1;     //发送完毕,打开数据输出
    LE = 0;
}

下载编译,左上角的点被点亮,证明封装没问题。既然封装了,那么可以再进一步封装,直接一次发送两个字节,并且把打开数据输出也封装进去

3.6 再次封装

3.6.1 main.c

void main()
{
    SendDat2(0xfe, 0x80);
    while (1)
    {
        
    }
}

void SendDat2(uchar col, uchar row)
{
    SendDat(col);
    SendDat(row);
    LE = 1;     //发送完毕,打开数据输出
    LE = 0;
}

封装后在main函数里面要加一个while循环,否则显示不正常,目前还不清楚是什么原因

3.6.2 main.h

void SendDat2(uchar col, uchar row);

 只需要在main.h写一下函数声明

3.7 动态显示

3.7.1 原理

人眼视觉暂留效应,每次只点亮1行的某些点,如果快速刷新下一行的点,人眼就会认为这几行是一起在现实的,从而实现动态显示。

在先代码的时候,需要先通过软件取模,获得每行对应要显示的列的位置,再通过循环去刷新界面

3.7.2 取模

软件PCtoLCD2002

具体设定如下

  1. 点击设置图标 
  2. 按照图片设置

设置完成点击确定,就可以在主界面输入框输入汉字了。 

 软件有2种模式,字符模式和图片模式,在上方工具栏“模式”里面可以选择

3.7.3 main.c

#include <intrins.h>

void main()
{
    uchar i;
    for (i = 0; i < 8; i++)
        SendDat2(chara[i], _cror_(0x80,i));
}

 3.7.4 main.h

main.h里面需要存放刚才取得的字模

uchar code chara[] = {
    0xF7,0xC1,0xD5,0xC1,0xD5,0xC1,0x77,0x87,//电,0
    0xFF,0xA3,0xDF,0x81,0xEF,0xEF,0xEF,0xF7//"子",1
};

 3.7.5 现象

如何编译下载已不必多说,下载完成后可以看到如图现象

 这样我们就可以通过取模软件来取模,然后把字模放在main.h的数组里面,通过main函数的调用,就可以显示想要的字符了。

3.7.6 两个字符循环显示

循环原理就是循环显示一个字符很多次,然后再循环另一个字符很多次,比如循环显示“电”,“子”

main.c代码
void main()
{
    uchar i;
    uint j;
    for (j = 0; j < 1000; j++)
    {
        for (i = 0; i < 8; i++)
            SendDat2(chara[i], _cror_(0x80,i));
    }
    for (j = 0; j < 1000; j++)
    {
        for (i = 0; i < 8; i++)
            SendDat2(chara[8 + i], _cror_(0x80,i));
    }
}

当然你也可以选择使用二维数组,或者其他的嵌套循环来显示这两个字,动图制作不便,就不放了

本次笔记对应清翔视频教程的第23,24,25 8x8点阵屏(理论+实践),到此结束,下一篇笔记将对应视频教程的26,27 中断系统和外部中断(理论+实践)

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值