❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。⭐️ 专栏主要内容: 主要学习51单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v
本学习过程参考:https://space.bilibili.com/383400717
单片机安装软件、各种资料以及源码的路径:
https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng
提取码:gdzf
本节主要介绍学习LED点阵屏的相关知识,包括LED点阵屏基础知识介绍、本节目标等;并利用两个小实验来进行练习,分别是LED点阵屏显示图形以及LED点阵屏显示动画。
文章目录
- 一、LED点阵屏基础和本节目标
- 1.1 LED点阵屏基础
- 1.1.1 LED点阵屏介绍
- 1.1.2 点阵屏的显示原理
- 1.1.3 74HC595 移位寄存器
- 1.1.4 C51的sfr、sbit
- 1.2 本节目标
- 1.2.1 目标1:LED点阵屏显示图形
- 1.2.2 目标2:LED点阵屏显示动画
- 二、LED点阵屏显示图形
- 三、LED点阵屏显示动画
一、LED点阵屏基础和本节目标
1.1 LED点阵屏基础
1.1.1 LED点阵屏介绍
LED点阵屏在单片机开发板上的位置如下图所示,使用时应该注意,将图中两个地方的条形帽插上。
LED点阵屏介绍
按像素分,可以分为88,1616等;一般来说,长和宽设置为8的倍数,因为一个字节是8位,将长和宽设置为8的倍数能保证1个字节的每一位都能不浪费。
1.1.2 点阵屏的显示原理
如果需要使某一个灯亮起来,则需要使其阳极为1,阴极为0,此LED就能亮起来。如下图所示,如果想要让左上角的那个LED亮起来,则使左边的第一行(阳极)为1,其他行为0;第一列(阴极)为0,其他列为1;则左上角的LED亮,其他等均灭。
同样的,如果想使第二行第二列的这个灯亮起来,如下图所示,则需要第二行(阳极)给1,其他行给0;第二列(阴极)给0,其他列给1;则第二行第二列的这个LED灯亮起来了。
LED点阵屏的原理图如下所示:
图中的io口和MCU引脚的对应关系图如下:
D0-D7连接的是点阵屏的阳极,P00-P07连接的是点阵屏的阴极。
P00-P07对应的就是单片机MCU的P0口;但是D0-D7对应的不是MCU,而是连在74HC595上,如下图所示
1.1.3 74HC595 移位寄存器
上面已经分析了,P00-P07对应的就是单片机MCU的P0口;但是D0-D7对应的不是MCU,而是连在74HC595上,如下图所示
由上图可知,74HC595的八个输出端接在了点阵屏的D0-D7口;74HC595的输入端RCLK(接在MCU的P35)、SRCLK(接在MCU的P36)和SER(接在MCU的P34)三个输出端控制其8个输出端。
原理图中的OE是控制输出使能的;类似于开关;OE上面加了一个横杠表示低电平有效;也就是说OE=0时,D0-D7八个输出端才有效。
那么74HC595是如何利用三个输入端控制8个输出端的呢?
原理的详细视频讲解参考(https://www.bilibili.com/video/BV1Mb411e7re?p=21&vd_source=e2638d12685eef84cda913d9d67be0a9第27分钟08秒)
下面总结一下如何用74HC595控制点阵屏进行显示;首先需要进行行选择和列选择,
列是直接接在io口P0上的;所以操作列的话直接对P0进行赋值即可;
而行是接在D0-D7的,即接在74HC595上的;通过控制74HC595的三个输入对行进行赋值。
1.1.4 C51的sfr、sbit
1.2 本节目标
1.2.1 目标1:LED点阵屏显示图形
目标1就是在LED点阵屏上显示一个特定的图形:
1.2.2 目标2:LED点阵屏显示动画
目标2则是在LED点阵屏上显示动画,显示了一个流动的字母HELLO!,如下图所示:
二、LED点阵屏显示图形
代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\9-1 LED点阵屏显示图形
具体代码
#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
/**
* @brief 74HC595写入一个字节
* @param Byte 要写入的字节
* @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);
//延时并清零,消除残影
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);
}
}
代码解释:
sbit RCK=P3^5; //RCLK
sbit SCK=P3^6; //SRCLK
sbit SER=P3^4; //SER
sbit RCK=P3^5
表示定义RCK为P3口的第五位,也就是P3_5,也就是表示74HC595的RCLK;
sbit SCK=P3^6
表示定义SCK为P3口的第六位,也就是P3_6,也就是表示74HC595的SRCLK;
sbit SER=P3^4
表示定义SER为P3口的第四位,也就是P3_4,也就是表示74HC595的SER;
相当于对P3_5、P3_6、P3_4进行重新的声明。
SER=Byte&(0x80>>i);
表示取byte的第i位的值给到SER;SER是一个二进制位,而Byte是八个二进制位,当这样赋值时,只有当右边的值是0,SER才等于0;当右边值非0时,SER就等于1;
for(i=0;i<8;i++)
{
SER=Byte&(0x80>>i);
SCK=1;
SCK=0;
}
参考74HC595的三个输入转8个输出的过程:
以上代码中,先SER=Byte&(0x80>>i)
得到SER要赋值的值是0还是1;将要赋值的值给到SER后,SCK=1
,表示将SER的值移进去;然后将SCK=0
,表示清零,为下一次移位做准备;因为74HC595的原理中,将SCK置为高电平1,才会将SER的值往下移动一位;8次for循环后,输入参数byte的8为就全都移动进74HC595里了。
那么我们生成一个要显示的具体图形,比如生成一个笑脸,那么各个亮灯位置怎么确认呢?
方法:在Excel里画出来,如下图,每一列设置什么值,一目了然
三、LED点阵屏显示动画
代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\9-2 LED点阵屏显示动画
具体代码
#include <REGX52.H>
#include "Delay.h"
#include "MatrixLED.h"
//动画数据
unsigned char code Animation[]={
0x3C,0x42,0xA9,0x85,0x85,0xA9,0x42,0x3C,
0x3C,0x42,0xA1,0x85,0x85,0xA1,0x42,0x3C,
0x3C,0x42,0xA5,0x89,0x89,0xA5,0x42,0x3C,
};
void main()
{
unsigned char i,Offset=0,Count=0;
MatrixLED_Init();
while(1)
{
for(i=0;i<8;i++) //循环8次,显示8列数据
{
MatrixLED_ShowColumn(i,Animation[i+Offset]);
}
Count++; //计次延时
if(Count>15)
{
Count=0;
Offset+=8; //偏移+8,切换下一帧画面
if(Offset>16)
{
Offset=0;
}
}
}
}
那上面代码中,动画数据是如何生成的呢?可以利用子模提取软件;具体的使用参考视频:https://www.bilibili.com/video/BV1Mb411e7re?p=22&spm_id_from=pageDriver&vd_source=e2638d12685eef84cda913d9d67be0a9第47分钟;