自学内容网 自学内容网

51单片机嵌入式开发:11、 STC89C52RC 实现一个滑动的led点阵程序


第十一节

1 概述

LED点阵是由多个LED(发光二极管)组成的矩阵型显示器件。它通常以行和列的形式排列,每个LED代表一个像素点。通过控制每个LED的亮灭状态,可以在点阵上显示各种图形、字符或动画。

2 LED点阵介绍

2.1 LED概述

常见的LED点阵屏有各种尺寸和类型,如8x8、16x16、32x32等。每个像素点通常由一个LED和一个驱动电路组成,该驱动电路负责控制LED的亮灭状态。
为了使用LED点阵屏,一般需要通过微控制器或单片机来控制。控制LED点阵屏的基本原理是通过逐行或逐列扫描的方式,将要显示的图形数据发送到对应的行和列,从而控制LED的亮灭状态。具体操作步骤如下:
连接硬件:将LED点阵屏与微控制器或单片机连接。根据点阵屏的引脚布局和控制器的IO口分配,连接适当的引脚,确保数据和控制信号传输正确。
编写驱动代码:根据点阵屏的型号和规格,编写相应的驱动代码。这通常包括设置引脚模式、发送数据、控制扫描等操作。
数据处理:根据需要显示的内容,将图形、字符或动画等转换为对应的点阵模式。可以使用预定义的字符模式数组或自定义生成字符模式的方法。
显示控制:根据点阵屏的工作原理,控制扫描的顺序和速度,逐行或逐列将数据发送到点阵屏上。通过适当的延时和刷新频率,可以实现所需的显示效果。

2.2 LED点阵注意事项

具体的驱动代码和操作步骤可能会因所使用的LED点阵屏型号和控制器类型而有所差异。通常,LED点阵屏的厂商会提供相应的文档和示例代码,可根据具体情况进行参考和调整。

3 LED点阵原理

3.1 Led点阵内部电路

8x8LED点阵内部结构图如下,这两种图片只是接法不同,要点亮LED,左图需要行置为高电平,列置为低电平;右图则需要行置为低电平,列置为高电平。

8x8LED点阵内部结构图

8x8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置高电平,某一列置低电平,则相应的二极管将点亮。

比如对于左图,如果要将第一个点点亮,则将第一行的⑨脚接高电平,第一列的13脚接低电平,第一个点就会点亮;如果要将第一行点亮,则第一行的⑨脚接高电平,所有列(13、3、4、10、6、11、15、16脚)接低电平,第一行就会点亮;如果要将第一列点亮,则第一列的13脚接低电平,所有行(9、14、8、12、1、7、2、5脚)接高电平,第一列就会点亮;如果要将对角线点亮,可以动态显示,首先点亮第一个点,然后点亮第2行第2列的点…这样依次循环点亮,就可以显示对角线的点。

在这里插入图片描述

如果要显示数字或字符,在需要的位置点亮,比如显示0(如下),可以循环点亮如下位置的LED。

3.2 原理图电路

在这里插入图片描述

仿真电路:
在这里插入图片描述

4 软件实现点阵图案的滑动

4.1 软件工程代码

软件代码工程:

在这里插入图片描述

软件代码:

//main.c文件

#include "includes.h"



/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void delay_us(unsigned int us)//delay us
{
while(us--)
{
}
}

/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void delay_ms(unsigned int Ms)//delay us
{
while(Ms--)
{
delay_us(100);
}
}

/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}


//P2 = 0xFF;//代表列 发光二级管的负端
//P0 = 0x00;//代表行 发光二级管的正端
//
//P20 = 0;
//P00 = 1;
//P01 = 1;
#define rowp P0
#define colp P2
//0-9字模
unsigned char disp[][8]={
{0x0c,0x12,0x22,0x44,0x22,0x12,0x0c,0x00},//?
{0x00,0x00,0x3e,0x41,0x41,0x3e,0x00,0x00},//0
{0x00,0x40,0x44,0x7e,0x7f,0x40,0x40,0x00},//1
{0x00,0x00,0x66,0x51,0x49,0x46,0x00,0x00},//2
{0x00,0x00,0x22,0x41,0x49,0x36,0x00,0x00},//3
{0x00,0x10,0x1c,0x13,0x7c,0x7c,0x10,0x00},//4
{0x00,0x00,0x27,0x45,0x45,0x45,0x39,0x00},//5
{0x00,0x00,0x3e,0x49,0x49,0x32,0x00,0x00},//6
{0x00,0x03,0x01,0x71,0x79,0x07,0x03,0x00},//7
{0x00,0x00,0x36,0x49,0x49,0x36,0x00,0x00},//8
{0x00,0x00,0x26,0x49,0x49,0x3e,0x00,0x00},//9
};

// 定义字符模式数组
unsigned char code charPatterns[8] = {
    0x0c,0x12,0x22,0x44,0x22,0x12,0x0c,0x00//0x18, 0x24, 0x42, 0x81, 0x42, 0x24, 0x18, 0x00
};

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
    unsigned char i, j,m;
    unsigned char displayData[8] = {0}; // 初始化显示数据

IIC_AT24C02_Test1();


delay(2);
while (1)
{
// 滚动效果
        for (j = 0; j < 8; j++) 
{
            for (i = 0; i < 8; i++) 
{
                displayData[i] = (displayData[i] << 1) | (charPatterns[i] >> (7 - j));
            }
            // 逐行扫描点阵屏
for(m=0;m<20;m++)
{

for (i = 0; i < 8; i++)
{
P2 = ~(1 << i); // 控制点阵屏的行
P0 = displayData[i]; // 发送数据
delay_ms(1); // 延时
//P0 = 0x00; // 清空数据
}
//delay_ms(500); // 控制滚动速度
}
for (i = 0; i < 8; i++)
{
P2 = ~(1 << i); // 控制点阵屏的行
P0 = 0x00; // 发送数据
delay_ms(1); // 延时
//P0 = 0x00; // 清空数据
}
        }
}
}

// c51_iic.c 文件

#include "includes.h"





/*------------------------------------------------
                   (1)启动IIC总线
------------------------------------------------*/
void Start(void)
{
Sda=1;
_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Sda=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=0;
}


/*------------------------------------------------
                    (2)停止IIC总线
------------------------------------------------*/
void Stop(void)
{
Sda=0;
_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Sda=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=0;
}


/*------------------------------------------------
                  (3) 应答IIC总线
------------------------------------------------*/
void Ack(void)
{
Sda=0;
_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=0;
_nop_();_nop_();
}


/*------------------------------------------------
                (4) 非应答IIC总线
------------------------------------------------*/
void NoAck(void)
{
Sda=1;
_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=0;
_nop_();_nop_();
}


/*------------------------------------------------
             (1) 发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{ 
unsigned char BitCounter=8;
unsigned char temp;

do
{
temp=Data;
Scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;


Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}


/*------------------------------------------------
               (2)读入一个字节并返回
------------------------------------------------*/
unsigned char Read(void)
{
unsigned char temp=0;
unsigned char temp1=0;
unsigned char BitCounter=8;

Sda=1;
do
{
Scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
if(Sda)
temp=temp|0x01;
else
temp=temp&0xfe;

if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}
 
/*------------------------------------------------
                   (1) 写入数据
------------------------------------------------*/
void WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num)
{
unsigned char i;
unsigned char *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(AddWr);    //写入芯片地址
Ack();
Send(Address+i);//写入存储地址
Ack();
Send(*(PData+i));//写数据
Ack();
Stop();
delay_ms(20);
}
}

/*------------------------------------------------
                (2) 读出数据
------------------------------------------------*/
void RdFromROM(unsigned char Data[],unsigned char Address,unsigned char Num)
{
unsigned char i;
unsigned char *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();        //写入芯片地址
Send(AddWr);
Ack();
Send(Address+i);//写入存储地址
Ack();
Start();
Send(AddRd);    //读入地址
Ack();
*(PData+i)=Read();//读数据
Scl=0;
NoAck();
Stop();
}
}


void IIC_AT24C02_Test1(void)
{
unsigned char Number[1];
WP=0;//写保护关掉

RdFromROM(Number,0,1);//调用存储数据 从地址0开始写一个数据
Number[0]++;
WrToROM(Number,0,1);//写入24c02
P1 =  Number[0];//在P1口上显示 反向显示 LED亮代表1
}

//includes.h文件

#ifndef __INCLUDES_H__
#define __INCLUDES_H__

//#include<reg52.h> 

#include<intrins.h> //汇编指令_nop_
#include<stdio.h> //标准输入输出

//_nop_(); 产生一条NOP指令
//作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
//NOP指令为单周期指令,可由晶振频率算出延时时间。
//对于12M晶振,延时1uS。
//11.0592M晶振,延时1.0851uS。
//对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。


//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"

//应用层头文件
//#include "c51_gpio.h"
//#include "c51_ledtube.h"
//#include "c51_key.h"
//#include "c51_timer.h"
//#include "c51_exit.h"
//#include "c51_lcd1602.h"
#include "c51_iic.h"


extern void delay(unsigned int cnt);
extern void delay_us(unsigned int us);//delay us;
extern void delay_ms(unsigned int Ms);//delay Ms;


#endif

//c51_iic.h文件

#ifndef __C51_IIC_H__
#define __C51_IIC_H__

#include "STC89C5xRC_RDP.h"


#define AddWr 0xAE   //写数据地址,需要参考24c02芯片文档
#define AddRd 0xAF   //读数据地址


#define SdaP12       //定义总线连接端口
#define SclP11
#define WPP10       //写保护,这里不使用



extern void Start(void);
extern void Stop(void);
extern void Ack(void);
extern void NoAck(void);
extern void Send(unsigned char Data);
extern unsigned char Read(void);
extern void WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num);
extern void RdFromROM(unsigned char Data[],unsigned char Address,unsigned char Num);

extern void IIC_AT24C02_Test1(void);


#endif

4.2 Protues仿真

在这里插入图片描述

5 扩展74HC595(后续专题开展)

5.1 74HC595原理 5.2 多点阵屏仿真电路 5.3 74HC595驱动程序 5.4 实现滑动显示点阵屏

6 总结

LED点阵在许多应用场景中得到广泛应用,以下是一些常见的LED点阵应用场景的总结:

  1. 信息显示:LED点阵屏可用于显示各种信息,如时间、日期、温度、湿度等。它们常见于数字时钟、温度计、计时器、计数器等设备中。

  2. 文字和图形显示:LED点阵屏可用于显示文字和简单图形,如在电子信息牌、广告显示屏、户外显示屏、室内装饰等场合中。

  3. 游戏和娱乐:由于其灵活性和可编程性,LED点阵屏广泛应用于小型游戏机、游戏控制器和娱乐设备中,如迷宫游戏、井字棋、俄罗斯方块等。

  4. 交通指示:LED点阵屏可用于交通信号灯、公交站牌、路牌等场景中,提供交通指示、公告和倒计时等信息。

  5. 仪器仪表:LED点阵屏在仪器仪表中用于显示各种测量数据、参数和状态,如数字多用表、频谱分析仪、电子天平等。

  6. 电子设备控制面板:LED点阵屏可用于控制面板,提供用户界面和操作指示,如家电控制面板、工业设备控制面板等。

  7. 艺术装置和装饰:由于其视觉效果和可编程性,LED点阵屏被广泛用于艺术装置、装饰灯光和节日装饰等场合中,创造各种独特的光影效果。

  8. 教育和学习工具:LED点阵屏可用于教育和学习工具,如编程教育工具、学生实验平台等,帮助学生理解和实践编程和电子原理。

  9. DIY项目:由于其易于使用和灵活性,LED点阵屏也常用于各种DIY项目中,如电子艺术作品、电子积木、自制游戏机等。

总而言之,LED点阵屏在信息显示、游戏娱乐、交通指示、仪器仪表、控制面板、艺术装置、教育工具等许多领域都有广泛的应用。其低功耗、可编程性和高可见性使其成为一种常用的显示技术。


原文地址:https://blog.csdn.net/sinat_30943509/article/details/140478654

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!