【自学51单片机】7--LED点阵学习

最新更新时间:2021-10-20来源: eefocus关键字:51单片机  LED点阵  8*8 手机看文章 扫描二维码
随时随地手机看文章

1、LED点阵介绍

LED点阵由多个LED小灯构成,以8*8LED点阵介绍,实物图和内部原理图如下。

图7-2左侧8个引脚为内部LED小灯阳极,上侧8个引脚为阴极。


2、点亮LED点阵

2.1 原理

点亮LED点阵与点亮LED小灯原理相似,根据LED点阵电路图分析即可,详细见第三章。


2.2 点亮全部LED点阵程序

利用定时器中断和数码管动态显示原理,就不进行说明,详细见第六章


3、取模软件简单介绍

取模软件可以将LED点阵图形的数据转换为程序中的数据。取模软件中黑色为LED熄灭,值为1,白色为LED点亮,值为0。如下图绘制了一个心形。

下面来说明取模软件参数的选取。

取模方式:根据LED点阵结构原理图,PO口控制的是一行,选择“横向取模”,控制的是一列,则选择“纵向取模”。


字节倒序:根据LED点阵结构原理图,若PO口左侧控制的是低位,右侧控制高位,勾选该选项,否则不勾选。


4、点阵动画显示

原理:对多张图片进行取模,利用程序算法切换图片形成动画。


4.1 横向左右移动(I ❤ U)动画程序

//LED点阵I love you 左右横向移动

#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


unsigned char code image[60][8]={ //图片字模表

{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},  //往左动画

{0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F}, //动画帧2

{0xFF,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F}, 

{0xFF,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F}, 

{0xFF,0x0F,0x9F,0x9F,0x9F,0x9F,0x9F,0x0F}, 

{0xFF,0x87,0xCF,0xCF,0xCF,0xCF,0xCF,0x87}, 

{0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3}, 

{0xFF,0xE1,0x73,0x73,0x73,0xF3,0xF3,0xE1}, 

{0xFF,0x70,0x39,0x39,0x39,0x79,0xF9,0xF0}, 

{0xFF,0x38,0x1C,0x1C,0x1C,0x3C,0x7C,0xF8}, 

{0xFF,0x9C,0x0E,0x0E,0x0E,0x1E,0x3E,0x7C}, 

{0xFF,0xCE,0x07,0x07,0x07,0x0F,0x1F,0x3E}, 

{0xFF,0x67,0x03,0x03,0x03,0x07,0x0F,0x9F}, 

{0xFF,0x33,0x01,0x01,0x01,0x03,0x87,0xCF}, 

{0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7}, 

{0xFF,0xCC,0x80,0x80,0x80,0xC0,0xE1,0xF3}, 

{0xFF,0xE6,0xC0,0xC0,0xC0,0xE0,0xF0,0xF9}, 

{0xFF,0x73,0x60,0x60,0x60,0x70,0x78,0xFC}, 

{0xFF,0x39,0x30,0x30,0x30,0x38,0x3C,0x7E}, 

{0xFF,0x9C,0x98,0x98,0x98,0x9C,0x1E,0x3F}, 

{0xFF,0xCE,0xCC,0xCC,0xCC,0xCE,0x0F,0x1F}, 

{0xFF,0x67,0x66,0x66,0x66,0x67,0x07,0x0F}, 

{0xFF,0x33,0x33,0x33,0x33,0x33,0x03,0x87}, 

{0xFF,0x99,0x99,0x99,0x99,0x99,0x81,0xC3}, 

{0xFF,0xCC,0xCC,0xCC,0xCC,0xCC,0xC0,0xE1},

{0xFF,0xE6,0xE6,0xE6,0xE6,0xE6,0xE0,0xF0}, 

{0xFF,0xF3,0xF3,0xF3,0xF3,0xF3,0xF0,0xF8}, 

{0xFF,0xF9,0xF9,0xF9,0xF9,0xF9,0xF8,0xFC}, 

{0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFE}, 

{0xFF,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF}, //动画帧 30

{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //往右动画

    {0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},

    {0xFF,0xFC,0xFE,0xFE,0xFE,0xFE,0xFE,0xFC},

    {0xFF,0xF8,0xFC,0xFC,0xFC,0xFC,0xFC,0xF8},

    {0xFF,0xF0,0xF9,0xF9,0xF9,0xF9,0xF9,0xF0},

    {0xFF,0xE1,0xF3,0xF3,0xF3,0xF3,0xF3,0xE1},

    {0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3},

    {0xFF,0x87,0xCE,0xCE,0xCE,0xCF,0xCF,0x87},

    {0xFF,0x0E,0x9C,0x9C,0x9C,0x9E,0x9F,0x0F},

    {0xFF,0x1C,0x38,0x38,0x38,0x3C,0x3E,0x1F},

    {0xFF,0x39,0x70,0x70,0x70,0x78,0x7C,0x3E}, 

    {0xFF,0x73,0xE0,0xE0,0xE0,0xF0,0xF8,0x7C},

    {0xFF,0xE6,0xC0,0xC0,0xC0,0xE0,0xF0,0xF9},

    {0xFF,0xCC,0x80,0x80,0x80,0xC0,0xE1,0xF3},

    {0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7},

    {0xFF,0x33,0x01,0x01,0x01,0x03,0x87,0xCF},

    {0xFF,0x67,0x03,0x03,0x03,0x07,0x0F,0x9F},

    {0xFF,0xCE,0x06,0x06,0x06,0x0E,0x1E,0x3F},

    {0xFF,0x9C,0x0C,0x0C,0x0C,0x1C,0x3C,0x7E},

    {0xFF,0x39,0x19,0x19,0x19,0x39,0x78,0xFC},

    {0xFF,0x73,0x33,0x33,0x33,0x73,0xF0,0xF8},

    {0xFF,0xE6,0x66,0x66,0x66,0xE6,0xE0,0xF0},

    {0xFF,0xCC,0xCC,0xCC,0xCC,0xCC,0xC0,0xE1},

    {0xFF,0x99,0x99,0x99,0x99,0x99,0x81,0xC3},

    {0xFF,0x33,0x33,0x33,0x33,0x33,0x03,0x87},

    {0xFF,0x67,0x67,0x67,0x67,0x67,0x07,0x0F},

    {0xFF,0xCF,0xCF,0xCF,0xCF,0xCF,0x0F,0x1F},

    {0xFF,0x9F,0x9F,0x9F,0x9F,0x9F,0x1F,0x3F},

    {0xFF,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x7F},

    {0xFF,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0xFF}, //动画帧60


};


void main()

{

EA = 1;//使能总使能

ENLED = 0;//使能U4,选择点亮点阵

ADDR3 = 0;

TMOD = 0x01;//为T0配置模式一

TH0 = 0xFC;//为T0赋值,定时1ms

TL0 = 0x67;

ET0 = 1; //使能T0中断

TR0 = 1; //开启T0

while(1);

}


void intertuptTimer0() interrupt 1

{

static unsigned char i = 0;//动态扫描索引

static unsigned int tmr = 0;//250ms软件定时器

static unsigned char index = 0;//图片刷新索引


TH0 = 0xFC; //重新加载初值

TL0 = 0x67;

//以下代码为点阵动态扫描刷新

P0 = 0xFF;//消除鬼影

switch(i)

{

case 0: ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=image[index][0];break;

case 1: ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=image[index][1];break;

case 2: ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=image[index][2];break;

case 3: ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=image[index][3];break;

case 4: ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=image[index][4];break;

case 5: ADDR2=1;ADDR1=0;ADDR0=1;i++;P0=image[index][5];break;

case 6: ADDR2=1;ADDR1=1;ADDR0=0;i++;P0=image[index][6];break;

case 7: ADDR2=1;ADDR1=1;ADDR0=1;i=0;P0=image[index][7];break;

default:break;

}

//以下代码完成每250ms改变一帧图像

tmr++;

if(tmr >= 250)//达到250ms改变一次图片索引

{

tmr = 0;

index++;

if(index >= 60) //图片索引达60后归零

{

index = 0;

}

}

}


左右移动动画和上下移动动画,会因LED点阵原理图中是横向取模或纵向取模而显得难度不同,若LED点阵是横向取模,则上下移动动画容易实现(因不同图片字模数据是连续的),而左右移动动画不易实现(因不同图片字模数据是不连续的)。博主用的LED点阵为横向取模,上下移动动画程序就不展示了,上面展示了左右移动动画程序。


4.2 LED点阵动画9 - 0倒计时程序

 //LED点阵动画9-0倒计时

#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


unsigned char code image[11][8]={ //图片字模表

{0xC3, 0x81, 0x99, 0x99, 0x99, 0x99, 0x81, 0xC3},  //数字0

    {0xEF, 0xE7, 0xE3, 0xE7, 0xE7, 0xE7, 0xE7, 0xC3},  //数字1

    {0xC3, 0x81, 0x9D, 0x87, 0xC3, 0xF9, 0xC1, 0x81},  //数字2

    {0xC3, 0x81, 0x9D, 0xC7, 0xC7, 0x9D, 0x81, 0xC3},  //数字3

    {0xCF, 0xC7, 0xC3, 0xC9, 0xC9, 0x81, 0xCF, 0xCF},  //数字4

    {0x81, 0xC1, 0xF9, 0xC3, 0x87, 0x9D, 0x81, 0xC3},  //数字5

    {0xC3, 0x81, 0xF9, 0xC1, 0x81, 0x99, 0x81, 0xC3},  //数字6

    {0x81, 0x81, 0x9F, 0xCF, 0xCF, 0xE7, 0xE7, 0xE7},  //数字7

    {0xC3, 0x81, 0x99, 0xC3, 0xC3, 0x99, 0x81, 0xC3},  //数字8

    {0xC3, 0x81, 0x99, 0x81, 0x83, 0x9F, 0x83, 0xC1},  //数字9

    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},  //全亮


};


void main()

{

EA = 1;//使能总使能

ENLED = 0;//使能U4,选择点亮点阵

ADDR3 = 0;

TMOD = 0x01;//为T0配置模式一

TH0 = 0xFC;//为T0赋值,定时1ms

TL0 = 0x67;

ET0 = 1; //使能T0中断

TR0 = 1; //开启T0

while(1);

}


void intertuptTimer0() interrupt 1

{

static unsigned char i = 0;//动态扫描索引

static unsigned int tmr = 0;//1s软件定时器

static signed char index = 9;//图片刷新索引


TH0 = 0xFC; //重新加载初值

TL0 = 0x67;

//以下代码为点阵动态扫描刷新

P0 = 0xFF;//消除鬼影

switch(i)

{

case 0: ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=image[index][0];break;

case 1: ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=image[index][1];break;

case 2: ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=image[index][2];break;

case 3: ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=image[index][3];break;

case 4: ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=image[index][4];break;

case 5: ADDR2=1;ADDR1=0;ADDR0=1;i++;P0=image[index][5];break;

case 6: ADDR2=1;ADDR1=1;ADDR0=0;i++;P0=image[index][6];break;

case 7: ADDR2=1;ADDR1=1;ADDR0=1;i=0;P0=image[index][7];break;

default:break;

}

//以下代码完成每1s改变一帧图像

tmr++;

if(tmr >= 1000)//达到1s改变一次图片索引

{

tmr = 0;

index--;

if(index < 0) //图片索引达-1后赋值为10

{

index = 10;

}

}

}


4.3 流水灯、数码管和LED点阵同时点亮程序

#include


sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;


void main()

{

    EA = 1; //使能总中断

ENLED = 0; //使能U3,U4,因动态扫描,点亮数码管,ADDR0-3需动态变化

TMOD = 0x10;//配置T1为模式一

TH1 = 0xFE; //为T1赋0xFE33,定时0.5ms

TL1 = 0x33;

ET1 = 1; //使能T1中断

TR1 = 1;//开启定时器T1

while(1);//在语句中一直循环,直到定时器T1中断

}


//以下为定时器T1的中断函数

void InterruptTimer1()  interrupt 3

{

static unsigned char i = 0; //动态扫描索引


TH1 = 0xFE; //为T1赋0xFE33,定时0.5ms

TL1 = 0x33;


//以下代码为LED小灯、数码管和LED点阵动态扫描

P0 = 0xff;//显示消隐

switch(i)

{

//点亮LED小灯部分

case 0: ADDR3=1;ADDR2=1;ADDR1=1;ADDR0=0;i++;P0=0;break;


//数码管的动态扫描部分

case 1: ADDR3=1;ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=0;break;

case 2: ADDR3=1;ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=0;break;

case 3: ADDR3=1;ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=0;break;

case 4: ADDR3=1;ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=0;break;

case 5: ADDR3=1;ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=0;break;

case 6: ADDR3=1;ADDR2=1;ADDR1=0;ADDR0=1;i++;P0=0;break;


//LED点阵的动态扫描部分

case 7: ADDR3=0;ADDR2=0;ADDR1=0;ADDR0=0;i++;P0=0;break;

case 8: ADDR3=0;ADDR2=0;ADDR1=0;ADDR0=1;i++;P0=0;break;

case 9: ADDR3=0;ADDR2=0;ADDR1=1;ADDR0=0;i++;P0=0;break;

case 10: ADDR3=0;ADDR2=0;ADDR1=1;ADDR0=1;i++;P0=0;break;

case 11: ADDR3=0;ADDR2=1;ADDR1=0;ADDR0=0;i++;P0=0;break;

case 12: ADDR3=0;ADDR2=1;ADDR1=0;ADDR0=1;i++;P0=0;break;

case 13: ADDR3=0;ADDR2=1;ADDR1=1;ADDR0=0;i++;P0=0;break;

case 14: ADDR3=0;ADDR2=1;ADDR1=1;ADDR0=1;i=0;P0=0;break;

default:break;

}


}

关键字:51单片机  LED点阵  8*8 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic551878.html

上一篇:【自学51单片机】8 -- 按键的学习,单片机最小系统
下一篇:keil中C51关键字code用法

推荐阅读

基于51单片机电子秒表倒计时器
刚刚咱们讲了电子秒表用的是C语言,接下来咱们再讲一讲用汇编。硬件设计(末尾附文件)电路图1:数码管显示;时间清零;启动计时;暂定计时;继续计时;电路图2程序设计TLOW    EQU  78HTHIGH   EQU  0ECHLED_WEI_Pro EQU 0f0H;数码管位选 保护位;寄存器设置COUN_INT    EQU 21H     ;5ms * 20 = 100ms = 0.1SCOUN_PASSNUM EQU 22H ;COUN_TIME_L EQU 23H ;时间累加 低位 100MS加1COUN_T
发表于 2021-11-26
基于<font color='red'>51单片机</font>电子秒表倒计时器
51单片机60秒倒计时 数码管显示
本资源适用于初学者,使用单片机型号为普中51单片机:下面展示 代码。#include"reg52.h"sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;//38译码器控制位选char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};char a1,a2,s=60;//s为要定时 60秒void timer0(){ TMOD|=0x01;TH0=0xfc;TL0=0x18;//¶¨定时1MSEA=1;ET0=1;TR0
发表于 2021-11-26
【C51单片机】数码管实现99秒倒计时
C51单片机之数码管实现99秒倒计时(结合定时器)—STC89C52单片机代码如下:#include <reg52.h>typedef unsigned char u8;typedef unsigned int u16;sbit b1 = P2^2;sbit b2 = P2^3;sbit b3 = P2^4;u8 duan[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};u16 count = 99;u16 digit = 0;//延时函数void delay(u16
发表于 2021-11-26
关于两块51单片机之间的串口通信(排队叫号系统)
一、项目要求叫号:按下按键叫号,数码管显示叫号的号数,蜂鸣器响。取号:按下按键取号,两个数码管分别显示取到的号数和等待的人数。(PS:推荐使用串口调试助手进行调试)二、可能使用到的工具1.串口调试助手(百度网盘自行下载)链接:https://pan.baidu.com/s/1XmCBUDD7kF8a5393fh_bBg提取码:znv3三、串口通信原理1.由51单片机引脚图可看出,P3.1(TXD)和P3.0(RXD)为串行通信口,P3.0为串行接收口,P3.1为串行发送口。要使两块单片机板可以进行串口通信,则将两块板之间的RXD/TXD交叉连接。四、设计流程图五、硬件设计六、界面实现七、代码主机:#include "
发表于 2021-11-25
关于两块<font color='red'>51单片机</font>之间的串口通信(排队叫号系统)
51单片机UART 串口通信[ 方式1 ]实现
1  51串行口结构51单片机的UART串行通信是基于其串行口的可编程硬件结构,只要用正确的程序代码通过初始化串行口对应寄存器的形式将其串行硬件结构初始化,再编写符合此串行口通信的程序代码便能够实现串行通信,其硬件结构决定了编程机制( 当然还要靠51芯片内CPU等机制 )。此结构具有UART( 通用异步收发器 )的全部功能,能同时进行数据的发送和接收,也可作为同步移位寄存器使用。此结构集成于单片机内部。Figure1:51串行口结构2  51串行口通信编程机制决定编程机制的先决条件是51单片机的硬件结构及51芯片内部CPU的执行机制。根据串行通信口硬件结构,实现UART通信可以分为两步:(1)初始化串行通信
发表于 2021-11-25
<font color='red'>51单片机</font>UART 串口通信[ 方式1 ]实现
51单片机内部定时器使用
/*------------------------------Function: generate pulse signalAuthor: Zhang KaizhouDate: 2019-5-15 22:50:43------------------------------*/#include <reg51.h>#define uchar unsigned charsbit output = P1^0;uchar period = 250;uchar high = 50;uchar tcount = 0;void timer0() interrupt 1 using 1{ TH0 = (65536 - 10000) /
发表于 2021-11-25
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved