STC89C52单片机 启动!!!(一)

跑马灯实现

直接上代码

#include<regx52.h>
sbit D1=P2^0;
sbit D2=P2^1;
sbit D3=P2^2;
sbit D4=P2^3;
sbit D5=P2^4;
sbit D6=P2^5;
sbit D7=P2^6;
sbit D8=P2^7;
void delay(int num){
	while(num--){
	}
}
void led_running(){
	//从第1盏灯到第8盏灯依次点亮
	D1=0;
	delay(40000);
	D2=0;
	delay(40000);
	D3=0;
	delay(40000);
	D4=0;
	delay(40000);
	D5=0;
	delay(40000);
	D6=0;
	delay(40000);
	D7=0;
	delay(40000);
	D8=0;
	delay(40000);
	
	//从第1盏灯到第8盏灯依次熄灭
	D1=1;
	delay(40000);
	D2=1;
	delay(40000);
	D3=1;
	delay(40000);
	D4=1;
	delay(40000);
	D5=1;
	delay(40000);
	D6=1;
	delay(40000);
	D7=1;
	delay(40000);
	D8=1;
	delay(40000);
	//从第1盏灯到第8盏灯依次点亮
	D1=0;
	delay(40000);
	D2=0;
	delay(40000);
	D3=0;
	delay(40000);
	D4=0;
	delay(40000);
	D5=0;
	delay(40000);
	D6=0;
	delay(40000);
	D7=0;
	delay(40000);
	D8=0;
	delay(40000);
	//从第8盏灯到第一盏灯依次熄灭
	D8=1;
	delay(40000);
	D7=1;
	delay(40000);
	D6=1;
	delay(40000);
	D5=1;
	delay(40000);
	D4=1;
	delay(40000);
	D3=1;
	delay(40000);
	D2=1;
	delay(40000);
	D1=1;
	delay(40000);
}
void main(){
	while(1){
		int i=3;
		while(i--){
		P2=0x00;
		delay(40000);
		P2=0xFF;
		delay(40000);
		}
		led_running();
	}
}

STC89C52单片机LED结构以及原理

由图中,我们可以看出每个led灯的正极都接高电平,所有的负极都接在端口上,1-8LED分别对应P20-P27引脚,当我们给这些引脚一个低电平的时候二极管就会导通,发光。

两种方式控制LED点亮

P2=0x00;一次性控制8个引脚从而一次性控制8个LED,转化为二进制为0000000,此时8个led均点亮。P2=0xFF;此时8个led均熄灭。格外注意:这里的P是大写。

用sbit来控制每个LED的亮灭。

sbit关键字

在单片机编程中,sbit 是特定于 Keil C 编译器的关键字,用于定义特定位的名称。通过 sbit 关键字,可以将某个特定的位与一个变量相关联,方便编程时对位进行操作。

例如,在 8051 单片机的 Keil C 编程中,可以使用 sbit 来定义位,示例代码如下:

sbit LED = P1^0; // 将 P1 端口的第 0 位与 LED 变量关联

代码

#include <reg51.h>

sbit LED1 = P2^0; // 将 P2 端口的第 0 位与 LED 变量关联

void main() {
    LED1 = 1; // 设置 LED 为高电平,相当于 P2.0 = 1;
//此时第一个LED灯就点亮了
    

}

数码管实现

数码管结构图(上面是共阴数码管,下面是共阳数码管)

  1. 共阳数码管: 共阳数码管的基本结构是由多个发光二极管(LED)组成,每个 LED 的阳极连接在一起,而各个 LED 的阴极分别独立控制。在共阳数码管中,当给定阳极一个高电平时,对应的 LED 会被激活,发光显示。因此,通过控制各个阴极的低电平来实现对数码管上不同位置的 LED 的显示和关闭。

  2. 共阴数码管: 共阴数码管的基本结构与共阳数码管类似,也由多个发光二极管(LED)组成,但是每个 LED 的阴极连接在一起,而各个 LED 的阳极分别独立控制。在共阴数码管中,当给定阴极一个低电平时,对应的 LED 会被激活,发光显示。因此,通过控制各个阳极的高电平来实现对数码管上不同位置的 LED 的显示和关闭。

总结:

  •   共阳数码管:阳极共连接,通过控制阴极的低电平来点亮对应的 LED。
  •   共阴数码管:阴极共连接,通过控制阳极的高电平来点亮对应的 LED。

数码管的段码值表

我们可以看到上面的图片中,A-G再加上一个小数点dp正好是8个,对应8个二极管。

这个表定义的是无小数点dot的段码值表

共阴带小数点的段码为:{0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7};

共阳带小数点的断码为:{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

这篇文章里面有详细断码表:

共阳和共阴数码管详细段码(带图)_共阳极数码管显示0~f对应的段码-CSDN博客

共阴带小数点的可以由共阴不带小数点的段码加0x80

共阳带小数点的可以由共阳不带小数点的段码减0x80

以6为例

注意:a对应的是最低位

a b c d e f g dp(共阴数码管)手动定义二极管阳极,让一个二极管点亮给这个端口赋值1

1 0 1 1 1 1 1 0=0x7D,这里要注意a对应的是最低位所以01111101=0x7D

a b c d e f g dp(共阳数码管)手动定义二极管阴极,让一个二极管点亮给这个端口赋值0

0 1 0 0 0 0 0 1=0x82,这里要注意a对应的是最低位所以10000010=0x82

实现让数码管显示数字4

#include<reg52.h>
unsigned char SMGnodot[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main(){
	
	while(1){
		P0=SMGnodot[5];
	}
}

这里我首先有两个疑惑

1.这里明显是要存储数字类型的数据,但是为什么这里使用的是unsigned char字符类型呢?

 在单片机中,char数组中的数据也是以字节(byte)的方式存储的。char类型表示一个字节的数据,即8位(8 bits)。在C语言中,char类型是用来表示字符的,但是它也可以用来存储其他8位的数据。在单片机中内存紧张,为了尽量减少内存消耗,我们选择使用char,并且在这里存储的数字正好是8位,char正好可以满足需求。换句话来说在c语言当中我们char是用来存放字符的,输出char类型变量出来的是字符,但是char在这里完全可以当成一个内存更小的数字存储单元

2.由下面的一张图片,我们可以看到8个引脚要控制8个晶体管,但是现在一个1晶体管就将8个引脚用光掉了,51单片机的共有40个引脚,每一个引脚通常有1位存储空间,用于表示引脚的状态(高电平或低电平)。这让我不得不猜想可能会在短时间内将仅用8个引脚来对8个晶体管状态进行遍历,利用我们的视觉暂留效果来看起来8个晶体管同时亮起来。当然,这只是我目前的猜想,让我们继续学习下去。

单个数码管静态显示(数码管实现遍历0-9)

#include<reg52.h>
unsigned char SMGnodot[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(int num){
	while(num--){
	}
}
void main(){
	unsigned char i;
	while(1){
		
		for(i=0;i<10;i++){
			
		    P0=SMGnodot[i];
			  delay(40000);
		}
	}
}

代码注意:这里不能写成for(unsigned char i=0;i<10;i++),在早期版本的C语言标准中,循环变量的定义只能放在函数的开头,而不能在循环内部进行定义。然而,随着C语言标准的演进,C99标准引入了块作用域规则,允许在循环内部定义循环变量。对于8051单片机编程,因为它使用的是较早的C语言标准,所以循环变量的定义通常放在循环外部,这样可以保证与旧版本C语言兼容。因此,你可以将循环变量i的定义放在main函数的开头,以符合8051单片机编程的惯例。

数码管中的段选和位选

数码管的段选是用来控制每一位数码管的8段的,一位需要8个端口,数码管的位选是控制数码管的这位是否可以显示。

数码管的位选控制的就是每个数码管的共阳端或者共阴端。就是公共端COM对于共阳数码管,当位选信号为高电平时,对应的数码管会被选中并显示;而对于共阴数码管,当位选信号为低电平时,对应的数码管会被选中并显示。对于一组四个共阴数码管,给其中一个的共阴端为低电平,其他三个数码管的共阴端为高电平,此时只有一个数码管被选中来能接受传输过来的数据。这就是动态显示选择其中一个数码管作为当前要显示的数码管的原理。

这里的位的意思可以看图片理解

数码管的两种显示方式(静态显示和动态显示)

静态显示

静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优点是占用CPU时间少,显示便于检测可控制。缺点是硬件电路比较复杂,成本较高。 如果对于一个四位数码管我们采用静态显示方式,仅仅段选加起来就需要32个接口一共需要33个端口,显然不太现实,使用动态显示的话只用12个端口就够了(8+4),所以对于多位数码管,我们常常使用动态显示的方式。

动态显示

看来和我想的一样(狗头)

数码管的动态显示原理是通过快速地切换多个数码管的显示,使人眼产生视觉上的同时显示效果。这种技术通常被称为多路复用显示。

实现数码管动态显示的基本步骤如下:

  1. 设置位选信号:首先选择其中一个数码管作为当前要显示的数码管,通过位选信号(即控制数码管的某一位)来选中该数码管。

  2. 发送段选数据:在选择了要显示的数码管之后,发送对应该数码管要显示的段选数据,包括要显示的数字、字母或其他符号的编码信息。

  3. 等待一小段时间:在当前数码管显示数据的瞬间,需要给予足够的时间让数码管完成显示,这样可以确保人眼能够清晰地看到显示的内容。

  4. 重复上述步骤:然后,迅速切换到下一个数码管,重复上述步骤1~3,直到所有的数码管都完成显示。

通过不断地重复以上步骤,每个数码管都会以很高的频率被选中并显示对应的内容,由于人眼的视觉暂留效应,就会给人一种所有数码管同时显示的错觉。这样就实现了数码管的动态显示效果。

对于上面的解释:【(即控制数码管的某一位)来选中该数码管。】为什么是只能控制某一位呢?按理来说使用12个端口控制的话,虽然不能让这四个数码管同时显示不同内容,但肯定能让这几个数码管同时更新相同的内容,同时接收,同时控制。其实是因为在我们这个单片机上并没有使用12个接口来控制,而是使用了一种其他芯片(74HC138),下面对其介绍。

74HC138

配合我们的动态数码管的结构来看

我们可以看到74HC138模块与图中动态数码管的8个公共端相连,功能

它具有多个输入线(A, B, C)和多个输出线(Y0-Y7),可以根据输入线的状态选择其中一个输出线。

具体来说,74HC138 可以将 3 个输入线的组合转换成 1 个输出线,实现将 8 个输入信号(2^3=8)映射到 1 个输出线上的功能。通过控制输入线的状态,可以选择激活其中一个输出线,从而实现解码器或者多路复用器的功能。

其实就是对应的三位二进制的真值表(原理图中C对应高位

结构图中的左下角功能是上电开关,电路图中已经接好了,表示这个芯片可以直接使用。

74HC245

它和动态数码管是直接相连的,在动态数码管图中的左侧部分,这是一个双向数据缓冲器。直观地理解它的功能就是:原封不动地将左边的数据传输到右边或者将右边的数据传输到左边。就像下面这个图中所示。值得注意的是左上角的接口DIR,对应英语中的direction(方向),作用是决定将右边的数据传输到左边还是将左边的数据传输到右边,DIR如果是高电平,就将左边的数据传输到右边,如果低电平,就将右边的数据传输到左边。

DIR与LE相连(图中黄色的装置,可用跳线棒连接)

采用74HC245这样接的话好处:缓冲器可以提高驱动能力,直接单片机接上数码管的话就相当于这个单片机的电位直接驱动数码管,但是单片机中高电位不会很高,这样驱动能力弱,导致数码管发光暗一点,但是现在有了这个芯片,就相当于是单片机中高电位起到一个控制信号,控制信号可以很微弱,然后接收到信号,这个芯片可以从它本身相连的vcc中汲取能量,这样的话就会使得数码管更亮。

由于单片机的输出端无法提供足够的电流来驱动数码管,可能会导致数码管亮度较低或者亮度不均匀。而使用 74HC245 缓冲器后,单片机的输出信号可以作为控制信号输入到缓冲器中,缓冲器会根据这个控制信号来控制数码管的数据输入输出,同时从自身的 VCC 中获取能量来驱动数码管,从而提高了驱动能力,并且可以改善数码管的发光效果。

多个数码管的动态显示

直接上代码

#include<regx52.h>
sbit A1=P2^2;
sbit B1=P2^3;
sbit C1=P2^4;
unsigned char SMGNOdt[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80};
void delay(int num){
	while(num--){
	}
}
void show(unsigned char pos,unsigned char num){
	switch(pos)
	{
		case 1:C1=0;B1=0;A1=0;break;
		case 2:C1=0;B1=0;A1=1;break;
		case 3:C1=0;B1=1;A1=0;break;
		case 4:C1=0;B1=1;A1=1;break;
		case 5:C1=1;B1=0;A1=0;break;
		case 6:C1=1;B1=0;A1=1;break;
		case 7:C1=1;B1=1;A1=0;break;
		case 8:C1=1;B1=1;A1=1;break;
	}
	P0=SMGNOdt[num];
}
void main(){
	while(1){
		show(8,5);
		delay(50);
		show(7,2);
		delay(50);
		show(6,0);
		delay(50);
		show(5,10);
		delay(50);
		show(4,1);
		delay(50);
		show(3,3);
		delay(50);
		show(2,1);
		delay(50);
		show(1,4);
		delay(50);
	}
}

这个代码中我主要强调几点: 

1.引脚的顺序赋值问题,让我们再看前面的这张图,这里可以看到74HC138芯片中A对应于P22,C对应于P24,在这款单片机中的P0,P1.P2.P3这四组引脚都是P0^0,P1^0,P2^0,P3^0对应8位二进制数字的最低位,所以看我们代码中这里是依次赋值给C1,B1,A1然后对应让哪个数码管可以接收数据,比如110对应Y6就是让第7个数码管接收数据。

2.注意结合我们的板子电路原理图来看对应顺序,其实也是在强调对应顺序。

可以看到从左到右分是数码管的8-1,并不是我们想的1-8,所以,在我们想显示5201314的时候第一位想显示5,其实是要让LED8显示5,让LED8接收数据。如下所示,所以我们一定要通过板子的原理图看清楚对应关系。

对江协科技老师的代码做一个解释

这里的代码相当于是和我的反过来了他主要是想函数内部反一下,外部我们自己写代码比较顺畅,这样的话我们外面想让第一个数码管显示数字5,就调用函数show(1,5);第1个灯显示了5,实际上还是让LED8显示的5,这样的话虽然方便,但是我觉得没有遵循原理图中的对应关系,看大家爱好喜欢,来选择书写方式。

欢迎大家指正!

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

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

相关文章

unity2D生成9*9格子

1.创建一个空对象和格子 2将格子做成预制体&#xff08;直接将格子拖到这里即可&#xff0c;拖了过后删掉原来的格子&#xff09; 3.创建脚本并将脚本拖到空对象上 using System.Collections; using System.Collections.Generic; using UnityEngine;public class CreateMap : M…

2024年雪糕线上市场未来发展趋势分析(2024京东淘宝天猫雪糕数据分析报告)

据相关媒体报道&#xff0c;北京多位雪糕批发商称钟薛高停产了&#xff0c;从年前开始就已经不供货了。还有记者实探钟薛高的北京总部&#xff0c;发现有不少人离职&#xff0c;办公区内仅剩零星几人。 从60元到2.5元&#xff0c;钟薛高在这两年经历了不少风波&#xff0c;终究…

鸿蒙不再适合JS语言开发

ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;对TS的动态类型特性施加更严格的约束&#xff0c;引入静态类型。同时&#xff0c;提供了声明式UI、状态管理等相应的能力&#xff0c;让开发者可以以更简洁、…

mysql事务(MVCC机制:undo日志)(mysql执行过程:redo日志,Buffer Pool缓存池)

事务 目的&#xff1a;保证数据的最终一致性## 事务的目的 事务的4大特性&#xff08;ACID&#xff09; 1.原子性(Atomicity):由undo log日志来保证 2.一致性(Consistency):使用事务的最终目的&#xff0c;由业务代码正确逻辑保证,比如错误的try-catch 3.隔离性(Isolation):…

在任意一个文件下,进入cmd

直接在界面上输入cmd&#xff0c;回车就出来了

安卓六大布局

LinearLayout&#xff08;线性布局&#xff09; 1.简介 线性布局在开发中使用最多&#xff0c;具有垂直方向与水平方向的布局方式。LinearLayout 默认是垂直排列的&#xff0c;但是可以通过设置 android:orientation 属性来改变为水平排列。 2.常用属性 orientation&#xf…

Windows系统下载安装Emby结合内网穿透实现公网访问本地影音网站

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

3.2 RK3399项目开发实录-初次使用的环境搭建(物联技术666)

通过百度网盘分享的文件&#xff1a;嵌入式物联网单片… 链接:https://pan.baidu.com/s/1Zi9hj41p_dSskPOhIUnu9Q?pwd8qo1 提取码:8qo1 复制这段内容打开「百度网盘APP 即可获取」 1. 用户和密码 1.1. Ubuntu Desktop 系统 Ubuntu Desktop 系统开机启动后&#xff0c;自动登录…

权限管理和操作指令

文章目录 前言一、文件的权限分类二、操作时无相应权限解决办法1.使用sudo指令2.修改文档权限 总结 前言 &#x1f4a6; Linux操作系统中&#xff0c;主要都是对文件进行操作&#xff0c;完成读写或者执行功能。Ubuntu 下我们会常跟用户权限打交道&#xff0c;权限就是用户对于…

python操作dataframe--打乱df的顺序

在Python中&#xff0c;可以使用Pandas库来操作DataFrame。要打乱DataFrame的顺序&#xff0c;可以使用sample方法来实现。以下是一个示例代码&#xff1a; import pandas as pd# 创建一个示例DataFrame data {A: [1, 2, 3, 4, 5],B: [10, 20, 30, 40, 50]} df pd.DataFrame…

为什么ERP与MES集成那么难搞?怎么有效解决这一难题

在现代企业信息化进程中&#xff0c;ERP&#xff08;企业资源规划&#xff09;和MES&#xff08;制造执行系统&#xff09;作为企业管理的核心信息系统&#xff0c;它们之间的深度集成是提升生产效率、实现精益管理和智能决策的关键环节。然而&#xff0c;ERP与MES集成并非易事…

【Python】成功解决NameError: name ‘sns‘ is not defined

【Python】成功解决NameError: name ‘sns’ is not defined &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您…

1个二维码能包含多个视频吗?制作视频二维码的方法

二维码在生活中现在随处可见&#xff0c;除了用于支付之外&#xff0c;展示内容也可以通过二维码来展现&#xff0c;比如常见的视频、图片、文件、音频等内容都可以通过二维码来展现。那么当我们需要将多个视频存入一个二维码中展示时&#xff0c;该如何利用二维码生成器的工具…

开发知识点-python-Tornado框架

介绍 Tornado是一个基于Python语言的高性能Web框架和异步网络库&#xff0c;它专注于提供快速、可扩展和易于使用的网络服务。由于其出色的性能和灵活的设计&#xff0c;Tornado被广泛用于构建高性能的Web应用程序、实时Web服务、长连接的实时通信以及网络爬虫等领域。 Torna…

jmeter接口自动化测试通过csv文件读取用例并执行测试

最近在公司测试中经常使用jmeter这个工具进行接口自动化&#xff0c;简单记录下~ 一、在csv文件中编写好用例 首先在csv文件首行填写相关参数&#xff08;可根据具体情况而定&#xff09;并编写测试用例。脚本可通过优先级参数控制执行哪些接口&#xff0c;通过端口参数同时执…

leetcode110.平衡二叉树

之前没有通过的样例 return语句只写了一个 return abs(l-r)<1缺少了 isBalanced(root->left)&&isBalanced(root->right);补上就好了 class Solution { public:bool isBalanced(TreeNode* root) {if(!root){return true;}int lgetHeight(root->left);i…

第三百九十一回

文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何混合选择多个图片和视频文件"相关的内容&#xff0c;本章回中将介绍如何通过相机获取视频文件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. …

很多人不懂这个伦敦金短线操作的心法

很多投资者进入伦敦金市场&#xff0c;是看中了它很适合短线操作的这个特点。确实&#xff0c;伦敦金不光可以实现双向T0的交易&#xff0c;而且还有24小时交易和保证金交易的特点&#xff0c;这些特点令伦敦金成为一个十分适合短线交易的品种。但是投资者如何在伦敦金短线交易…

提高转换效率的利器NCP13992ACDR2G 高性能电流模式LLC谐振变换器控制芯片

NCP13992ACDR2G产品概述&#xff1a; NCP13992ACDR2G是一款用于半桥谐振变换器的高性能电流模式控制器。该控制器实现了600 V栅极驱动器&#xff0c;简化了布局并减少了外部组件数量。内置的Brown−Out输入功能简化了控制器在所有应用程序中的实现。在需要PFC前级的应用中&…

RUST 每日一省:rust logo收集

rust的logo集合&#xff0c;看看有没有你喜欢的&#xff0c;挑一个吧&#xff1b; GitHub - XuHugo/rust-logo: Collection of logo images for all rust languages 下边只是挑选了几个&#xff0c;更多的还是看github吧。
最新文章