51单片机实验:数码管动态显示00-99

1、实验要求

        利用STC89C52RC单片机开发板实现:使用2位数码管循环显示00-99,每次间隔1s,并且当计数到20时,则蜂鸣器鸣响1次。

2、实验分析

程序实现分析:        

        1、定义数码管位选引脚(P2.4、P2.5、P2.6、P2.7)

        2、定义个位、十位显示函数(用来未选第1、2位显示个位、十位上的数字)

        3、定义延时函数(使用for循环嵌套实现空语句执行,从而达到延时的效果)

        4、定义计数变量,分别计算出个位、十位的数,将其传入到个位、十位显示的函数

        5、结合延时函数,实现数字的显示

        6、判断计数变量大于99,则重新赋值为0

3、代码实现

(1)导入头文件及引脚定义

#include <reg52.h>

sbit pos1 = P2^4;   // 第1为数码管位选控制位
sbit pos2 = P2^5;   // 第2为数码管位选控制位
sbit pos3 = P2^6;   // 第3为数码管位选控制位
sbit pos4 = P2^7;   // 第4为数码管位选控制位
sbit fmq = P2^3;    // 蜂鸣器控制位

(2)定义个位、十位显示函数

// 分别对应:0/1/2/3/4/5/6/7/8/9
int code_sz[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};

// 宏定义:简写 unsigned int
#define uint unsigned int

// 函数声明
void show_ge(uint x);
void show_shi(uint y);


// 显示个位数字:左起第2位数码管
void show_ge(uint x)   // x:计算的个位数的值,对应数组中的索引,从而取到对应的值
{
	P0 = 0x00;     // P0(段选位)复位
	pos1 = 0;
	pos2 = 1;      // 选择第2位数码管
	pos3 = 0;
	pos4 = 0;
	P0 = code_sz[x];   // 数组索引取到对应的数字值赋值给P0
}

void show_shi(uint y)  // y:计算的十位数的值,对应数组中的索引,从而取到对应的值
{
	P0 = 0x00;     // P0(段选位)复位
	pos1 = 1;      // 选择第1位数码管
	pos2 = 0;
	pos3 = 0;
	pos4 = 0;
	P0 = code_sz[y];    // 数组索引取到对应的数字值赋值给P0
}

(3)定义延时函数

void delay(uint ms);   // 延时函数声明

void delay(uint ms)   // 延时指定的毫秒(错略延时)
{
	uint i, j;
	for(i=ms; i>0; i--)
	{
		for(j=112; j>0; j--);
	}
}

(4)编写主函数逻辑

uint val = 0;
uint ge, shi;

void main()
{
	while (1)
	{
		ge = val % 10;     // 计算个位的值
		shi = val / 10;    // 计算十位的值
		show_shi(shi);     // 调用显示十位的函数
		delay(100);        // 延时100ms,让十位数显示保持
		show_ge(ge);       // 调用显示个位的函数
		delay(900);        // 延时900ms,让十位数显示保持
		fmq = 1;           // 关闭蜂鸣器鸣叫
		pos1 = 0;          // 位选复位(避免出现位选错乱,产生乱码)
		pos2 = 0;
		pos3 = 0;
		pos4 = 0;
		val++;             // 计数值增加1
        if (val > 99) val =0;    // 如果计数值大于99,则重新从0开始
		if (val == 20) fmq=0;    // 如果计数值等于20,则蜂鸣器鸣叫
	}
}

【单片机显示问题】数码管显示不同的值需要考虑2个问题:

(1)十位、个位显示不同值:由于P0段选共用,则需要实现位选调整才能实现。

(2)要保证个位、十位的数同时显示。

【单片机显示现象】十位数字很暗,基本无法显示,个位可以正常,但会出现闪烁情况,无法看到00--99的数字。

【单片机显示分析】十位(第1位数码管)显示由于延时时间过短(100ms),造成还未显示,程序就执行到了显示个位的代码,从而位选就切换至第2位数(个位)码管,则P0对应的取值则会显示到第1位数码管,此时添加的900ms延时,也只能显示个位上的数字。

【单片机显示调整】

A、个位、十位显示的时间间隔不能过大这样(10s),由于代码执行较快(us),这样就能因为视觉停留现象则就会感觉数字是一直显示,同时也不会出现闪烁情况。

B、个位、十位数值变化时间要保证1s:则计数变量则1s内需要计数50次再增加1(1000 / (10 + 10) = 50), 这样就能让个位十位数码管1s内更新50次后显示下一个数。


uint times = 0;

void main()
{
	while (1)
	{
        times++;
		if(times == 50)    // 每50次,计数增加1
		{ 
			times = 0;     // 次数50次后复位
			val++;                   // 计数值增加1
			if (val > 99) val =0;    // 如果计数值大于99,则重新从0开始
		}

		ge = val % 10;     // 计算个位的值
		shi = val / 10;    // 计算十位的值
		show_shi(shi);     // 调用显示十位的函数
		delay(10);         // 延时10ms,让十位数显示保持
		show_ge(ge);       // 调用显示个位的函数
		delay(10);         // 延时10ms,让十位数显示保持
		fmq = 1;           // 关闭蜂鸣器鸣叫
		pos1 = 0;          // 位选复位(避免出现位选错乱,产生乱码)
		pos2 = 0;
		pos3 = 0;
		pos4 = 0;

		if (val == 20) fmq=0;    // 如果计数值等于20,则蜂鸣器鸣叫
	}
}

4、完整代码

#include <reg52.h>

// 宏定义:简写 unsigned int
#define uint unsigned int

sbit pos1 = P2^4;   // 第1为数码管位选控制位
sbit pos2 = P2^5;   // 第2为数码管位选控制位
sbit pos3 = P2^6;   // 第3为数码管位选控制位
sbit pos4 = P2^7;   // 第4为数码管位选控制位
sbit fmq = P2^3;    // 蜂鸣器控制位

// 分别对应:0/1/2/3/4/5/6/7/8/9
int code_sz[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};

// 函数声明
void show_ge(uint x);
void show_shi(uint y);
void delay(uint xms);   

uint times = 0;
uint val = 0;
uint ge, shi;

void main()
{
	while (1)
	{
        times++;
		if(times == 50)    // 每50次,计数增加1
		{ 
			times = 0;     // 次数50次后复位
			val++;                   // 计数值增加1
			if (val > 99) val =0;    // 如果计数值大于99,则重新从0开始
		}

		ge = val % 10;     // 计算个位的值
		shi = val / 10;    // 计算十位的值
		show_shi(shi);     // 调用显示十位的函数
		delay(10);         // 延时10ms,让十位数显示保持
		show_ge(ge);       // 调用显示个位的函数
		delay(10);         // 延时10ms,让十位数显示保持
		fmq = 1;           // 关闭蜂鸣器鸣叫
		pos1 = 0;          // 位选复位(避免出现位选错乱,产生乱码)
		pos2 = 0;
		pos3 = 0;
		pos4 = 0;

		if (val == 20) fmq=0;    // 如果计数值等于20,则蜂鸣器鸣叫
	}
}


// 显示个位数字:左起第2位数码管
void show_ge(uint x)   // x:计算的个位数的值,对应数组中的索引,从而取到对应的值
{
	P0 = 0x00;     // P0(段选位)复位
	pos1 = 0;
	pos2 = 1;      // 选择第2位数码管
	pos3 = 0;
	pos4 = 0;
	P0 = code_sz[x];   // 数组索引取到对应的数字值赋值给P0
}

void show_shi(uint y)  // y:计算的十位数的值,对应数组中的索引,从而取到对应的值
{
	P0 = 0x00;     // P0(段选位)复位
	pos1 = 1;      // 选择第1位数码管
	pos2 = 0;
	pos3 = 0;
	pos4 = 0;
	P0 = code_sz[y];    // 数组索引取到对应的数字值赋值给P0
}

void delay(uint ms)   // 延时指定的毫秒(错略延时)
{
	uint i, j;
	for(i=ms; i>0; i--)
	{
		for(j=112; j>0; j--);
	}
}

5、实验总结

        要明确数码管的显示要解决的问题(显示不同的值的数据保持、不同位的数据同时显示),着重问题的本身出发,设计对应的程序:通过多次判断实现对计数的修改,同时要明确程序执行的速度较快,人有视觉暂停现象, 结合这些因素实现对应逻辑分步操作。


结语以上整个程序的实现逻辑,还存在很多不全面的地方,欢迎各位大佬指点;如果觉得笔者不易,欢迎关注和点赞,给予我记录更多文章的动力!!

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

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

相关文章

ES6初步了解迭代器

迭代器是什么&#xff1f; 迭代器(iterator)是一种接口&#xff0c;为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 iterator 接口&#xff0c;就可以完成遍历操作 ES6创造了一种新的遍历方法for…of循环&#xff0c;iterator 接口主要供 for…of 使用 原生中具…

Android12之#pragma clang diagnostic ignored总结(一百六十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

pip 更换源

方案1 在C盘用户名录下新建pip文件夹&#xff0c;里面包含pip.ini文件 方案2 在C盘用户名目录的AppData的Roaming下新建pip文件夹&#xff0c;里面包含pip.ini文件。 内容为 [global] index-url https://pypi.tuna.tsinghua.edu.cn/simple

Git(四)底层命令:git对象、树对象、提交对象

目录 一、知识回顾1.1 Linux 基础命令1.2 .git 文件夹解析 二、git 对象&#xff08;数据对象&#xff09;2.1 hash-object 存储对象2.2 cat-file 查看对象 三、树对象3.1 ls-files 查看暂存区3.2 update-index 创建暂存区3.3 write-tree 生成树对象3.4 更新暂存区&#xff0c;…

ffmpeg的下载和编译(vs2022)

感谢大佬的二创,直接提供了sln编译 ffmpeg二创地址 创建如下目录 build存放代码(build最好改成source,因为作者这么建议,编译完才发现) msvc存放第三方依赖的头文件,这里固定叫msvc,因为大佬的sln里查找的路径是这个,不嫌麻烦也可以自己改 下载代码和编译器 下载源码…

[论文阅读]Point Density-Aware Voxels for LiDAR 3D Object Detection(PDV)

PDV Point Density-Aware Voxels for LiDAR 3D Object Detection 论文网址&#xff1a;PDV 论文代码&#xff1a;PDV 简读论文 摘要 LiDAR 已成为自动驾驶中主要的 3D 目标检测传感器之一。然而&#xff0c;激光雷达的发散点模式随着距离的增加而导致采样点云不均匀&#x…

层次式架构的设计理论与实践

层次式架构的设计理论与实践 层次式架构概述 层次式架构的定义和特性 定义 特性 层次式架构的一般组成(表现层、中间层、数据访问层和数据层) 表现层框架设计 设计模式 MVC MVP MVVM XML技术 UIP设计思想 表现层动态生成设计思想(基于XML界面管理技术) 中间层架构设计 业务…

Vue+ElementUI项目打包部署到Ubuntu服务器中

1、修改config/index.js中的assetsPublicPath: /,修改为assetsPublicPath: ./ assetsPublicPath: ./2、在build/utils.js中增加publicPath: ../../ publicPath: ../../3、打开终端&#xff0c;在根目录下执行npm run build进行打包&#xff0c;打包成功后会生成dist npm run…

cmake练习一

需求&#xff1a; 1、利用CGAL库Boost库&#xff0c;写一个关于CGAL的程序 2、使用cmake构建 1、创建目录结构 src中有一个main.cpp&#xff0c;放的是我们的主程序代码 2、安装CGAL和Boost库 略 3、编写cmakelist.txt cmake_minimum_required(VERSION 3.1.0) project(cg…

规则推理桌游

目录 Eleusis Express 1&#xff0c;规则 2&#xff0c;出牌规则示例 3&#xff0c;中文规则 Eleusis Express 原文&#xff1a;Eleusis Express 1&#xff0c;规则 简单来说就是需要一个主持人想一个出牌规则&#xff0c;其他人通过出牌试探过程推理出这个出牌规则。 …

甘特图组件DHTMLX Gantt用例 - 如何自定义任务、月标记和网格新外观

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 本文将为大家揭示DHTMLX Gantt自定义的典型用例&#xff0c;包括自定义任务、网格的新外观等&#xff0c;来展示其功能的强大性&…

电力物联网关智能通讯管理机-安科瑞黄安南

众所周知&#xff0c;网关应用于各种行业的终端设备的数据采集与数据分析&#xff0c;然后去实现设备的监测、控制、计算&#xff0c;为系统与设备之间建立通讯联系&#xff0c;达到双向的数据通讯。 网关可以实时监测并及时发现异常数据&#xff0c;同时自身根据用户规则进行…

[AutoSar NVM] 存储服务层(Service)详解

专栏 《深入浅出AutoSAR》。全文 3400 字&#xff0c; 依AutoSAR及公开知识辛苦整理&#xff0c;禁止转载。 接上一讲 [AutoSar NVM] 存储架构 "数据是新时代的石油" -- 克莱门特•M•杜森堡&#xff08;Clement M. Dusenbury&#xff09; 我们深入了解下存储服务层 …

国际腾讯云自主拼装直播 URL教程!!!

注意事项 创建转码模板 并与播放域名进行 绑定 后&#xff0c;转码配置后的直播流&#xff0c;需将播放地址的 StreamName 拼接为 StreamName_转码模板名称&#xff0c;更多详情请参见 播放配置。 前提条件 已注册腾讯云账号&#xff0c;并开通 腾讯云直播服务。 已在 域名…

python二次开发Solidworks:方程式驱动曲线

1、渐开线 import win32com.client as win32 import pythoncomswApp win32.Dispatch(sldworks.application) swApp.Visible True Nothing win32.VARIANT(pythoncom.VT_DISPATCH, None) swModel swApp.ActiveDoc swExt swModel.Extension swSelMgr swModel.SelectionManag…

竞赛 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

Mysql在ubuntu22.04上安装配置

更新并下载Mysql sudo apt update sudo apt install mysql-server启动Mysql服务 sudo systemctl start mysql安全配置 包括设置密码、删除匿名用户、禁止远程root登录等&#xff0c;按提示进行即可。 sudo mysql_secure_installation是否设置密码&#xff1a;是 三种强度密…

Node.js中的单线程服务器

为了解决多线程服务器在高并发的I/O密集型应用中的不足&#xff0c;同时避免早期简单单线程服务器的性能障碍&#xff0c;Node.js采用了基于"事件循环"的非阻塞式单线程模型&#xff0c;实现了如下两个目标&#xff1a; &#xff08;1&#xff09;保证每个请求都可以…

DAY35 435. 无重叠区间 + 763.划分字母区间 + 56. 合并区间

435. 无重叠区间 题目要求&#xff1a;给定一个区间的集合&#xff0c;找到需要移除区间的最小数量&#xff0c;使剩余区间互不重叠。 注意: 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”&#xff0c;但没有相互重叠。 示例 1: 输入: [ […

Babylonjs学习笔记(六)——贴图的使用

书接上回&#xff0c;这里讨论贴图的运用&#xff01;&#xff01;&#xff01; // 创建球网格const ball MeshBuilder.CreateSphere(ball,{diameter:1},scene)ball.position new Vector3(0,1,0)// 创建PRB材质const ballMat new PBRMaterial(pbr,scene)// albedoTexture 反…