STC89C52RC 实现一个滑动的led点阵程序
- 1 概述
- 2 LED点阵介绍
- 2.1 LED概述
- 2.2 LED点阵注意事项
- 3 LED点阵原理
- 3.1 Led点阵内部电路
- 3.2 原理图电路
- 4 软件实现点阵图案的滑动
- 4.1 软件工程代码
- 4.2 Protues仿真
- 5 扩展74HC595(后续专题开展)
- 6 总结
第十一节
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 Sda P12 //定义总线连接端口
#define Scl P11
#define WP P10 //写保护,这里不使用
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点阵应用场景的总结:
-
信息显示:LED点阵屏可用于显示各种信息,如时间、日期、温度、湿度等。它们常见于数字时钟、温度计、计时器、计数器等设备中。
-
文字和图形显示:LED点阵屏可用于显示文字和简单图形,如在电子信息牌、广告显示屏、户外显示屏、室内装饰等场合中。
-
游戏和娱乐:由于其灵活性和可编程性,LED点阵屏广泛应用于小型游戏机、游戏控制器和娱乐设备中,如迷宫游戏、井字棋、俄罗斯方块等。
-
交通指示:LED点阵屏可用于交通信号灯、公交站牌、路牌等场景中,提供交通指示、公告和倒计时等信息。
-
仪器仪表:LED点阵屏在仪器仪表中用于显示各种测量数据、参数和状态,如数字多用表、频谱分析仪、电子天平等。
-
电子设备控制面板:LED点阵屏可用于控制面板,提供用户界面和操作指示,如家电控制面板、工业设备控制面板等。
-
艺术装置和装饰:由于其视觉效果和可编程性,LED点阵屏被广泛用于艺术装置、装饰灯光和节日装饰等场合中,创造各种独特的光影效果。
-
教育和学习工具:LED点阵屏可用于教育和学习工具,如编程教育工具、学生实验平台等,帮助学生理解和实践编程和电子原理。
-
DIY项目:由于其易于使用和灵活性,LED点阵屏也常用于各种DIY项目中,如电子艺术作品、电子积木、自制游戏机等。
总而言之,LED点阵屏在信息显示、游戏娱乐、交通指示、仪器仪表、控制面板、艺术装置、教育工具等许多领域都有广泛的应用。其低功耗、可编程性和高可见性使其成为一种常用的显示技术。