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

news2024/12/23 23:29:30

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点阵应用场景的总结:

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

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

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

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

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

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

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

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1931094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL篇:主从复制

概述 话不多说&#xff0c;直接上概念&#xff1a; DDL&#xff08;Data Definition Language&#xff09;语句&#xff1a; 数据定义语言&#xff0c;主要是进行定义/改变表的结构、数据类型、表之间的链接等操作。常用的语句关键字有 CREATE、DROP、ALTER 等。 DML&#xff…

Redis实战—附近商铺、用户签到、UV统计

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P88 - P95 目录 附近商铺 数据导入 功能实现 用户签到 签到功能 连续签到统计 UV统计 附近商铺 利用Redis中的GEO数据结构实现附近商铺功能&#xff0c;常见命令如下图所示。…

逻辑漏洞-支付漏洞

【实验目的】 通过本次实验&#xff0c;掌握最基础的支付漏洞 【实验环境】 win7操作机&#xff1a;10.0.0.2 centos7靶机&#xff1a;10.0.0.3 【实验步骤】 1. 启动实验环境 点击“启动场景”按钮&#xff0c;成功启动后&#xff0c;点击操作机按钮进入操作界面。 打开浏…

景区客流统计系统提升服务精准度

在当今旅游业蓬勃发展的时代&#xff0c;景区面临着越来越多的挑战和机遇。如何在保障游客良好体验的同时&#xff0c;实现景区的高效管理和可持续发展&#xff0c;成为了摆在景区管理者面前的重要课题。景区客流统计系统的出现&#xff0c;为解决这一问题提供了有力的支持&…

如何通过成熟的外发平台,实现文档安全外发管理?

文档安全外发管理是企业信息安全管理的重要组成部分&#xff0c;它涉及到企业向外发送的文件&#xff0c;需要进行严格的控制和管理&#xff0c;防止敏感或机密信息的泄露。以下是一些关键考虑因素&#xff1a; 文件外发的挑战&#xff1a;企业在文件外发时面临的主要挑战包括…

Python数据分析-植物生长数据分析(机器学习模型和神经网络模型)

一、研究背景 植物生长受多种环境因素的影响&#xff0c;包括土壤类型、日照时间、浇水频率、肥料类型、温度和湿度等。这些因素不仅影响植物的生长速度和健康状况&#xff0c;还对植物在不同生长阶段的表现有显著影响。随着气候变化和环境污染问题的加剧&#xff0c;研究如何…

【NLP实战】基于TextCNN的新闻文本分类

TextCNN文本分类在pytorch中的实现 基于TextCNN和transformers.BertTokenizer的新闻文本分类实现&#xff0c;包括训练、预测、数据加载和准确率评估。 目录 项目代码TextCNN网络结构相关模型仓库准备工作项目调参预测与评估 1.项目代码 https://github.com/NeoTse0622/Te…

数电基础 - 硬件描述语言

目录 一. 简介 二. Verilog简介和基本程序结构 三. 应用场景 四. Verilog的学习方法 五.调式方法 一. 简介 硬件描述语言&#xff08;Hardware Description Language&#xff0c;HDL&#xff09;是用于描述数字电路和系统的形式化语言。 常见的硬件描述语言包括 VHDL&…

如何落地实际场景,解决跨境传输共性需求?免费白皮书可下载

在全球化的背景下&#xff0c;海外市场对于数据驱动的产品和服务的需求不断增加&#xff0c;各行业数据跨境传输也日趋频繁&#xff0c;在这种前景下&#xff0c;越来越多的企业寻求更深度的跨国业务及合作&#xff0c;因此&#xff0c;企业数据跨境流动也成为了势不可挡的趋势…

LabVIEW异步和同步通信详细分析及比较

1. 基本原理 异步通信&#xff1a; 原理&#xff1a;异步通信&#xff08;Asynchronous Communication&#xff09;是一种数据传输方式&#xff0c;其中数据发送和接收操作在独立的时间进行&#xff0c;不需要在特定时刻对齐。发送方在任何时刻可以发送数据&#xff0c;而接收…

Internet 控制报文协议 —— ICMPv4 和 ICMPv6 详解

ICMP 是一种面向无连接的协议&#xff0c;负责传递可能需要注意的差错和控制报文&#xff0c;差错指示通信网络是否存在错误 (如目的主机无法到达、IP 路由器无法正常传输数据包等。注意&#xff0c;路由器缓冲区溢出导致的丢包不包括在 ICMP 响应范围内&#xff0c;在 TCP 负责…

[C++]——同步异步日志系统(6)

同步异步日志系统 一、日志器模块设计1.1 同步日志器模块设计1.1.1 局部日志器建造者模式设计1.1.2 同步日志器基本功能测试 1.2 异步日志器模块设计1.2.1 单缓冲区设计1.2.2 异步工作线程的设计&#xff08;双缓冲区思想&#xff09;1.2.3 异步日志器设计1.2.4 异步日志器建造…

5.串口通信

文章目录 串口的介绍TTLRS-232RS-485 分类方式串口并口同步异步 相关寄存器SCONPCONTMODSBUFIE 中断处理函数代码编写main.cdelay.cdelay.hUart.cUart.hmain.h回环 继电器ESP8266AT指令代码编写main.cdefine.cdefine.hsend.csend.hreceive.cdelay.cdelay.h 串口的介绍 UART&am…

项目发布部署:如何发布.NETCore项目到IIS服务器?

前言&#xff1a;本文将详细介绍如何发布.NET Core项目到IIS服务器。首先&#xff0c;第一步需要安装IIS&#xff0c;介绍了在本地电脑和服务器中进行安装。然后需要安装SDK和运行时才能发布.NETCore项目。其次介绍了如何发布.NETCore项目和Vue项目&#xff0c;并配置IIS。最后…

自适应键盘,自带隐藏键盘的输入框(UITextField)

引言 在iOS开发中&#xff0c;输入框占据着举足轻重的地位。与安卓不同&#xff0c;iOS输入框经常面临键盘遮挡的问题&#xff0c;或者无法方便地取消键盘。为了解决这些问题&#xff0c;有许多针对iOS键盘管理的库&#xff0c;如IQKeyboardManager、TPKeyboardAvoiding和Keyb…

数仓实践:维度建模标准规范定义

一、引言 指以维度建模作为理论基础,构建总线矩阵,划分和定义数据域、业务过程、维度、度量/原子指标、业务限定、时间周期、统计粒度、派生指标。 规范定义如下: 二、名词术语 名词解释数据域面向业务分析,将业务过程或者维度进行抽象的集合。其中,业务过程可以概括为…

idea中使用maven

默认情况下&#xff0c;idea会自动下载并安装maven&#xff0c;这不便于我们管理。 最好是自行下载maven&#xff0c;然后在idea中指定maven的文件夹路径

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【获取密钥属性(C/C++)】

获取密钥属性(C/C) HUKS提供了接口供业务获取指定密钥的相关属性。在获取指定密钥属性前&#xff0c;需要确保已在HUKS中生成或导入持久化存储的密钥。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 构造对应参数。 keyAlias&…

华为OD七日集训第1期 - 按算法分类,由易到难,循序渐进,玩转OD

目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第2期五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、逻辑分析第2天、数组第3天、双指针第4天、数据结构第5天、队列第6天、栈第7天、滑动窗口 六、集训总结 大家好&#xff0c;我是哪吒。 最近一直…

Idea如何快速高效的修改项目的包名

文章目录 前言一、全局替换的快捷键二、弹出如下的界面 前言 当我们有时候在做项目迁移的时候&#xff0c;需要快速的修改项目的包名&#xff01;那么如何快速高效的修改项目的报名呢&#xff1f; 经过尝试了很多方法&#xff01;最简单的方法就是利用全局替换来直接替换报名&…