江协科技51单片机学习- p21 LED点阵屏(8*8)

🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大51单片机的视频为主以及自己的总结梳理📚 

前言:

本文是根据哔哩哔哩网站上“江协科技51单片机”视频的学习笔记,在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了江协科技51单片机教学视频和链接中的内容。

引用:

51单片机入门教程-2020版 程序全程纯手打 从零开始入门_哔哩哔哩_bilibili

​​​​​​c51语言变量语句意思,C51中循环语句-CSDN博客

LED点阵引用:

小白跟做江科大51单片机之LED点阵屏-CSDN博客

江科大51单片机学习笔记之LED点阵屏_江科大led点阵屏-CSDN博客

51单片机关键字code,idata:

keil中C51关键字code用法_c51 code-CSDN博客

【51】单片机中的data、idata、xdata、code等关键字的作用-CSDN博客

模拟电梯控制:

【51单片机练习3——智能电梯控制系统1】_智能电梯系统-CSDN博客

基于51单片机的四层电梯控制系统_51单片机电梯控制系统设计-CSDN博客

51单片机学习——1天学完普中基本实验例程,走马观花式学习,大家切勿效仿。_普中单片机实验-CSDN博客

参考:

51单片机常用功能及相关内容_单片机_浪客小子-GitCode 开源社区

正文:

0. 🌿概述

在淘宝上购买了江协科技51单片机开发板套件(普中科技STC51单片机A2型号),就上在上一篇博文里说的自己计划学习下江协科技51单片机开发教程,通过STC51单片机这种MCU这种贴近于裸机的开发来增加对于系统硬件层面知识的了解和掌握。

1. 🚀51单片机控制LED点阵屏(8*8)

LED点阵屏(8*8)的点阵规格,可以分为单色屏,双色屏,三色屏(红绿蓝三色可以组成全彩色)

8*8 LED点阵显示屏的显示原理和8段LED数码段的驱动原理相似,LED点阵显示屏也需要按行或者按列的方式依次扫描显示每一行/列,控制行/列显示的内容。

8*8 LED显示点阵和数码管一样,有共阴极和共阳极两种接法,因为点阵矩阵可以按行或整案列查看所以单色LED 显示矩阵的共阴极和共阳极接线方法没有什么差异。但是对于双色的8*8 LED显示矩阵共阴极和共阳极的接线方法就有差异了。

2. 🚀51单片机开发板LED点阵屏电路原理图

我本次实验使用的普中科技51单片机开发板LED点阵屏电路原理图如下

经过测试开发板的实际接线如下,D0~D7接在 8*8 LED点阵的行,P00~P07接在LED点阵的列。

😎如果直接使用单片机的IO口来驱动 8*8 LED点阵则需要16个IO口,为了节约单片机IO口资源使用 74HC595移位寄存器来减少单片机IO口资源使用。

😎74HC595使用 3 个输入IO口,看控制8个IO口的输出。

3.  🚀 74HC595的使用

74HC595的工作原理

🚀 74HC595 是串行输入并行输出移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位,24位,32位等,常用于IO口扩展。

串行输入,并行输出。

🌵左边是移位寄存器

🌵右边是暂存寄存器 

🛍️单片机IO口上电默认是高电平,所以需要初始化为低电平。

🛍️单片机IO口电路示意通中引脚符号上的“上划横线”表示低电平有效。

引脚说明
RCLK (Register Clock)寄存器时钟
SRCLK (Serial Clock)串行时钟
SRCLR (Serial Clear)串行清零
SER串行数据

🛍️单片机IO口输出是若上拉,其特性是输出低电平可以通过较大电流,输入高电平通过电流较弱。单片机IO口输出高电平驱动LED能力较弱,所以输出高电平驱动LED灯可以通过一个 74HC245缓冲器或者三极管来缓冲一下,增强IO口高电平信号的驱动能力。

 即使是使用了74HC595来增大引脚的驱动能力驱动能力,输出点亮LED的亮度还是不均匀。

 🛍️74HC595是恒压输出的,观察点阵屏的输出效果可以发现当74HC595一次点亮多个(例如8个)LDE灯时,LED灯的亮度要比一次点亮2个LED灯的亮度要弱。点阵显示屏显示动态数据的时候亮度不均匀。

🛍️原因是 74HC595是恒压输出的,解决方法可以是使用恒流输出的缓冲器,让每一个输出引脚的输出电流恒定当要驱动多个引脚时会自动增大总的输入电流。

74HC595 移位寄存器的串行输入引脚的移位寄存器的时序裸机操作:

🛍️ SER 为输入信号,当SRCLK时钟上升沿时SER的信号的一位数据(高电平为1,低电平为0)被保存到移位寄存器的最低位,同时移位寄存器里原有的数据位被往下平移一位。每次 SRCLK时钟上升沿时进行一次SER输入信号数据的锁存和移位,以此类推,SRCLK 出现8次时钟上升沿,SER输入的8为数据被保存到移位寄存器里。📚️

🛍️RCLK 寄存器时钟上升沿,移位寄存器里的8位数据被并行的输出到锁存寄存器里,当RCK寄存器为低电平时移位寄存器里的值对输出寄存器里的值不产生影响。📚️

🛍️74HC595移位寄存器可以多片级联,74HC595移位寄存器的 QH' 输出引脚可以连接到下一片74HC595一位寄存器的 SER 输入引脚,实现74HC595的多片级联,可以实现16位或32为IO口的扩展📚️

4. 🚀 Keil5 特殊功能寄存器 sfr 和 sbit 关键字

📚️ sfr (special function register):特殊功能寄存器

📚️ sbit(special bit):特殊位声明

📚️ 可位寻址/不可位寻址:在单片机系统中,操作任意寄存器或者寄存器某一位的数据时,必须给出其物理地址,又因为一个寄存器有8位,所谓位的数量是寄存器的8倍。单片机无法对所有的位进行编码,故每8个寄存器,只有一个是可以位寻址的。

5. 🚀 LED点阵屏显示笑脸

使用Excel 手动计算“笑脸”段码

第0列:0011 1100 = 0x3C

第1列:0100 0010 = 0x42

第2列:1001 1001 = 0x99

第3列:1000 0101 = 0x85

第4列:1000 0101 = 0x85

第5列:1001 1001 = 0x99

第6列:0100 0010 = 0x42

第7列:0011 1100 = 0x3c

 编写源码,每次选中一列,在每一列上输出段码显示笑脸。

#include <REGX52.H>
#include <INTRINS.H>
#include "delay.h"

//sfr
//special function register
//special bit 
sbit SER 	= P3^4;		//SER
sbit RCK	= P3^5;		//RCLK
sbit SRCLK 	= P3^6;		//SRCLK


void _74HC595_WriterByte(unsigned char Byte)
{
	
	SER = Byte & 0x80;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x40;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x20;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x10;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	
	SER = Byte & 0x08;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x04;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x02;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x01;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	
	//移位寄存器并行输出到锁存寄存器
	RCK = 1;
	RCK = 0;
	
}


void _74HC595_Init()
{
	//单片机启动默认IO口为高电平,需要初始化RCLK, SRCLK为低电平
	SRCLK = 0;
	RCK = 0;
}

//最左边列为低0列,最右边列为第7列
void _74HC595_ShowColumn(unsigned char Column, unsigned char Data)
{
	
	_74HC595_WriterByte(Data);
	P0 = ~(0x80 >> Column);
	
	//同数码管一样,LED点阵也需要消影
	Delay(1); 		//延时1ms给数据显示时间,延时时间太短的话LED亮度不够
	P0 = 0xFF;		//清除位选
	
}


void main()
{
	unsigned char i = 0;
	
	P0 = 0xFF;
	
	_74HC595_Init();
	_74HC595_WriterByte(0xFF);
	
	
	
	
	while(1)
	{
//		P0 = ~(1 << i);
//		Delay(200);
//		
//		i++;
//		if(i >= 8)
//			i = 0;
		
		_74HC595_ShowColumn(0, 0x3C);
		_74HC595_ShowColumn(1, 0x42);
		_74HC595_ShowColumn(2, 0x99);
		_74HC595_ShowColumn(3, 0x85);
		_74HC595_ShowColumn(4, 0x85);
		_74HC595_ShowColumn(5, 0x99);
		_74HC595_ShowColumn(6, 0x42);
		_74HC595_ShowColumn(7, 0x3C);
		
		
	}
}

下载到单片机开发板,实际显示效果如下图所示:

6. 🚀 LED点阵屏显示动画-取模软件

附带资料里的取模软件,“新建图像”,选择高度为8宽度为32

默认格点太小了,选择“模拟动画”,“放大格点”,放大格点显示的大小方便操作,

放大格点之后效果

在取模软件里“参数设置”,“其它选型”,就是我们取模的方式配置:

📗LED点阵屏显示有纵向扫描,也有横向扫描,我们这里使用的是纵向扫描每次扫描一列。

📗高位在上还是低位在上

鼠标狂点,在点阵里点击显示"Hello !" 字符。

提取子模,点击“取模方式”,“C51”格式

复制拷贝生成的子模,拷贝到我们的Keil5 源码编辑器里。

7 🚀 LED点阵屏显示动画-源码编写

流动文字显示的原理

流动字幕的显示原理:

📝第一次显示0到7列,然后偏移1列第二次显示1到8列,再偏移1列,第三次显示2-9列,这样每次偏移1列进行显示。

main.c 文件

#include <REGX52.H>
#include <INTRINS.H>
#include "delay.h"
#include "MatrixLED.h"




//默认放在RAM里面的

//code关键字,把数组放到Flash里面
unsigned char code Animation [] = {
	/*--  调入了一幅图像:这是您新建的图像  --*/
	/*--  宽度x高度=32x8  --*/
	0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,
	0xFF,0x08,0x08,0x08,0xFF,0x00,0x3E,0x49,
	0x49,0x49,0x39,0x00,0xFF,0x01,0x02,0x00,
	0xFF,0x01,0x03,0x00,0x3E,0x41,0x41,0x3E,
	0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00,
};

void main()
{
	unsigned char i = 0;
	unsigned char offset = 0;
	unsigned char count = 0;
	
	P0 = 0xFF;
	MatrixLED_Init();
	
	
	Animation[0] = 0x00;
	
	while(1)
	{
		
		for(i=0; i< 8; i++){
			MatrixLED_ShowColumn(i, Animation[i + offset]);
		}
		
		count++;
		if(count >= 20)
		{
			count = 0;
			
			offset++;
			if(offset > (40 - 8))
				offset = 0;
		}
	}
}

MatrixLED.c 文件

#include <REGX52.H>
#include <INTRINS.H>
#include "delay.h"
#incldue "MatrixLED.h"


//sfr
//special function register
//special bit 
sbit SER 	= P3^4;		//SER
sbit RCK	= P3^5;		//RCLK
sbit SRCLK 	= P3^6;		//SRCLK


#define MATRIX_LED_PORT P0

/**
  * @brief  74HC595写入一个字节
  * @param  Byte 要写入的字节
  * @retval 无
  */
void MatrixLED_WriterByte(unsigned char Byte)
{
	
	SER = Byte & 0x80;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x40;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x20;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x10;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	
	SER = Byte & 0x08;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x04;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x02;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	SER = Byte & 0x01;		//非0即1
	SRCLK = 1;
	SRCLK = 0;
	
	
	//移位寄存器并行输出到锁存寄存器
	RCK = 1;
	RCK = 0;
	
}

/**
  * @brief  点阵屏初始化
  * @param  无
  * @retval 无
  */
void MatrixLED_Init()
{
	//单片机启动默认IO口为高电平,需要初始化RCLK, SRCLK为低电平
	SRCLK = 0;
	RCK = 0;
}


/**
  * @brief  LED点阵屏显示一列数据
  * @param  Column 要显示的列,范围0~7,0在最左边
  * @param  Data 选择列显示的数据,高位在上,1为亮,0为灭
  * @retval 无
  */
void MatrixLED_ShowColumn(unsigned char Column, unsigned char Data)
{
	
	MatrixLED_WriterByte(Data);
	MATRIX_LED_PORT = ~(0x80 >> Column);
	
	//同数码管一样,LED点阵也需要消影
	Delay(1); 		//延时1ms给数据显示时间,延时时间太短的话LED亮度不够
	MATRIX_LED_PORT = 0xFF;		//清除位选
	
}

MatrixLED.h 文件

#ifndef __MATRIXLED_H__
#define __MATRIXLED_H__


void MatrixLED_WriterByte(unsigned char Byte);
void MatrixLED_Init();
void MatrixLED_ShowColumn(unsigned char Column, unsigned char Data);

#endif

显示效果

8. 关键字'code'将数组放到单片机内部Flash中

 🍎关键字'code'将数组放到单片机内部Flash中。

当没有关键字code的时候,默认 unsigned char Animation []  数组执行时会被放到 SRAM 中,因为STC89C52系列单片机的Flash一般是 4KB或者8KB,SRAM的大小是512字节。当需要显示的点阵屏数组内容是固定不点的时候,可以使用 'code' 关键字将数组的内容放到单片机的Flash中存储,而不用加载到DRAM中,节省宝贵的DRAM资源。

🍎当使用了关键字'code’之后,在程序代码中就不能修改数组中内容的值了,否则在编译的时候编译器就报报错提示程序尝试修改‘unmodified location。’

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

发那科机床采集数据

前面两篇重点介绍了理论&#xff0c;从这篇开始&#xff0c;我们开始进行实战。首先从发那科机床开始&#xff0c;为何第一个将发那科。因为发那科系统机床有三最。最广泛&#xff08;中国保有量最多&#xff09;、 最多资料&#xff08;发那科系统的开发包历史悠久&#xff0c…

【效率提升】新一代效率工具平台utools

下载地址&#xff1a;utools uTools这款软件&#xff0c;是一款功能强大且高度可定制的效率神器&#xff0c;使用快捷键alt space(空格) 随时调用&#xff0c;支持调用系统应用、用户安装应用和市场插件等。 utools可以调用系统设置和内置应用&#xff0c;这样可以方便快捷的…

Python计算n的阶乘的多种方法

1 问题 在课上&#xff0c;我们学习了用递归函数去计算一个自然数n的阶乘。但计算一个自然数n的阶乘是否就这一种方法呢&#xff1f; 2 方法 关于计算一个自然数n的阶乘&#xff0c;通过搜索&#xff0c;我们寻找到了除运用递归函数外的其他三种方法&#xff1a; 方法一 通过导…

CSS-实例-div 水平居中 垂直靠上

1 需求 2 语法 3 示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>表格水平居中、垂直靠上示例…

解决Install/Remove of the Service Denied报错

1、问题概述&#xff1f; 在Windows系统中安装MySQL5.7.43的时候&#xff0c;运行mysqld install命令提示报错&#xff1a;Install/Remove of the Service Denied 意思是&#xff1a;安装/删除服务被拒绝 问题原因所在&#xff1a;就是你当前的权限不够&#xff0c;以管理员…

人工智能的目标分类

欢迎来到 Papicatch的博客 目录 &#x1f349;引言 &#x1f349;目标分类的概述 &#x1f348;背景 &#x1f348;分类的重要性 &#x1f34d;明确研究重点 &#x1f34d;促进应用推广 &#x1f34d;便于评估和比较 &#x1f348;分类的原则 &#x1f34d;基于应用领…

密钥库jks文件加载格式错误IOException:Invalid keystore format--已经解决

一、报错 java.lang.RuntimeException: java.io.IOException: Invalid keystore format Caused by: java.io.IOException: Invalid keystore format二、原因 原因&#xff1a;Java的密钥库jks文件放在/src/main/resources目录下,编译后jks文件被修改,导致keyStore.load读取…

支付宝支付之收款码支付

文章目录 收款码支付接入流程安全设计系统交互流程交易状态统一收单交易支付接口请求参数测试结果查询支付撤销支付退款支付退款结果退款说明 收款码支付 继&#xff1a;支付宝支付之入门支付 接入流程 安全设计 支付宝为了保证交易安全采取了一系列安全手段以保证交易安全。…

计网之IP

IP IP基本认识 不使用NAT时&#xff0c;源IP地址和目的IP地址不变&#xff0c;只要源MAC和目的MAC地址在变化 IP地址 D类是组播地址&#xff0c;E类是保留地址 无分类地址CIDR 解决直接分类的B类65536太多&#xff0c;C类256太少a.b.c.d/x的前x位属于网路号&#xff0c;剩…

kafka的工作原理与常见问题

定义 kafka是一个分布式的基于发布/订阅模式的消息队列&#xff08;message queue&#xff09;&#xff0c;主要应用于大数据的实时处理领域 消息队列工作原理 kafka的组成结构 kafka的基础架构主要有broker、生产者、消费者组构成&#xff0c;还包括zookeeper. 生产者负责发送…

高并发场景下的热点key问题探析与应对策略

目录 一、问题描述 二、发现机制 三、解决策略分析 &#xff08;一&#xff09;解决策略一&#xff1a;多级缓存策略 客户端本地缓存 代理节点本地缓存 &#xff08;二&#xff09;解决策略二&#xff1a;多副本策略 &#xff08;三&#xff09;解决策略三&#xff1a;热点…

计算机组成原理——锁存器和触发器

文章目录 1. SR锁存器 1.1 电路结构 1.2 电路解析 2. 带en输入的SR锁存器 2.1 ​​​​​​​电路结构 2.2 工作原理 3. ​​​​​​​带En输入的D锁存器 3.1 电路结构 3.2 工作原理 4. ​​​​​​​边沿触发的D触发器 4.1 电路结构 4.2 工作原理 1. SR锁存器 …

Python | Leetcode Python题解之第207题课程表

题目&#xff1a; 题解&#xff1a; class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:edges collections.defaultdict(list)indeg [0] * numCoursesfor info in prerequisites:edges[info[1]].append(info[0])indeg[info[…

C语言 | Leetcode C语言题解之第207题课程表

题目&#xff1a; 题解&#xff1a; bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize) {int** edges (int**)malloc(sizeof(int*) * numCourses);for (int i 0; i < numCourses; i) {edges[i] (int*)malloc(0);…

AD PCB板子裁剪与泪滴设置

在剪裁板子时。首先&#xff0c;选择选择板子的机械层&#xff0c;之后选择画线。在原来的板子上画上自己想要裁剪的图形。如下下图 之后&#xff0c;选择按照所画的线裁剪板子即可&#xff0c;如下 在焊接PCB时&#xff0c;为了防止多次焊接导至焊盘脱落可以加大焊点的接触面积…

leetcode-19-回溯-组合问题(剪枝、去重)

引自代码随想录 一、[77]组合 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4]] 1、大致逻辑 k为树的深度&#xff0c;到叶子节点的路径即为一个结果 开始索引保证不…

[C++][设计模式][备忘录模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受 1.动机 在软件构建过程中&#xff0c;某些对象的状态转换过程中&#xff0c;可能由于某中需要&#xff0c;要求程序能够回溯到对象之前处于某个点的状态。 如果使用一些公开接口来让其他对象得到对象的状态&#xff0c;便会暴露对象…

3D在线展览馆的独特魅力,技术如何重塑展览业的未来?

在数字化和虚拟现实技术迅猛发展的今天&#xff0c;3D在线展览馆已经成为一种颇具前景的创新形式。搭建3D在线展览馆不仅能够突破传统展览的时空限制&#xff0c;还能为参观者提供身临其境的体验&#xff0c;极大地提升展示效果和用户互动。 一、3D在线展览馆的意义 1、突破时空…

《Windows API每日一练》7.3 计时器时钟

知道如何使用Windows计时器之后&#xff0c;可以看看一些有用的计时器应用程序了。时钟是计时器最明显的应用&#xff0c;我们来看两个例子&#xff1a;一个是数字时钟&#xff0c;另一个是模拟时钟。 本节必须掌握的知识点&#xff1a; 第45练&#xff1a;7段数码管数字时钟 …

KV260视觉AI套件--PYNQ-DPU

目录 1. 简介 2. DPU 原理介绍 2.1 基本原理 2.2 增强型用法 3. DPU 开发流程 3.1 添加 DPU IP 3.2 在 BD 中调用 3.3 配置 DPU 参数 3.4 DPU 与 Zynq MPSoC互联 3.5 分配地址 3.6 生成 Bitstream 3.7 生成 BOOT.BIN 4. 总结 1. 简介 在《Vitis AI 环境搭建 &…