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++;             // 计数值增加1if (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++;                   // 计数值增加1if (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 intsbit 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++;                   // 计数值增加1if (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、实验总结

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


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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg编译安装(windows环境)以及在vs2022中调用

文章目录 下载源码环境准备下载msys换源下载依赖源码位置 开始编译编译x264编译ffmpeg 在VS2022写cpp调用ffmpeg 下载源码 直接在官网下载压缩包 这个应该是目前&#xff08;2023/10/24&#xff09;最新的一个版本。下载之后是这个样子&#xff1a; 我打算添加外部依赖x264&a…

esp32-S3 + visual studio code 开发环境搭建

一、首先在下面链接网页中下载esp-idf v5.1.1离线安装包 &#xff0c;并安装到指定位置。dl.espressif.cn/dl/esp-idf/https://dl.espressif.cn/dl/esp-idf/ 安装过程中会提示需要长路径支持&#xff0c;所以windows系统需要开启长路径使能 Step 1&#xff1a; 打开运行&…

ES6~ES13新特性(一)

文章目录 一、ES6中对象的增强1.字面量的增强2.解构Destructuring3.解构的应用场景 二、手写实现apply、call、bind方法1.apply、call方法2.bind方法 三、ECMA新描述概念1.新的ECMA代码执行描述2.词法环境&#xff08;Lexical Environments&#xff09;3.词法环境和变量环境4.环…

番外8.2 --- 后续

### 01&#xff1a;dd命令&#xff1a;在新挂载点创建swap文件大小10MB&#xff1b;&#xff08;dd if/dev/zero of/swap bs1024 count10240&#xff09; 02&#xff1a;给swap建立文件系统&#xff0c;将其分属到swap文件&#xff08;mkswap /swap&#xff1b; swapon /swap &…

Python —— UI自动化用例前置处理日志封装

1、UI自动化用例增加前置 1、fixture&#xff08;夹具&#xff09;的使用 前置顾名思义是在执行测试用例之前做的一些事情&#xff0c;在自动化测试时会碰到用例执行前需要做一些前置操作&#xff0c;以及用例执行后需要做一些后置操作&#xff0c;比如登录、退出等&#xff…

中国两轮“技术派”绿源,为全球电动市场带来跨越式方案

历史越长的行业&#xff0c;遇到变革之时&#xff0c;需要经历的考验、做出的突破就越多。两轮电动车&#xff0c;这个非常本土化的赛道&#xff0c;就是如此。 中国是两轮电动车产销大国&#xff0c;自上世纪晚期开始&#xff0c;中国两轮电动车迅速发展&#xff0c;绿源等一…

Modbus转MQTT以太网网关MQT-802主要特点和典型应用

随着社会的快速发展&#xff0c;物联网已经潜移默化地深入工控行业的各个领域&#xff0c;其高效的资源整合和强大的数据采集能力&#xff0c;深受客户的喜爱。上海泗博为实现客户在云端平台接收处理世界万物的信息以及实现远程控制&#xff0c;精心打造一款全新物联网产品&…

工作小计-GPU硬编以及依赖库 nvcuvidnvidia-encode

工作小计-GPU编码以及依赖库 已经是第三篇关于编解码的记录了。项目中用到GPU编码很久了&#xff0c;因为yuv太大&#xff0c;所以编码显得很重要。这次遇到的问题是环境的搭建问题。需要把开发机上的环境放到docker中&#xff0c;以保证docker中同样可以进行GPU的编码。 1 定…

Python轮廓追踪【OpenCV形态学操作】

文章目录 概要代码运行结果 概要 一些理论知识 OpenCV形态学操作理论1 OpenCV形态学操作理论2 OpenCV轮廓操作|轮廓类似详解 代码 代码如下&#xff0c;可以直接运行 import cv2 as cv# 定义结构元素 kernel cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) # print kern…

小程序设计基本微信小程序的校园生活助手系统

项目介绍 通篇文章的撰写基础是实际的应用需要&#xff0c;然后在架构系统之前全面复习大学所修习的相关知识以及网络提供的技术应用教程&#xff0c;以校园生活助手系统的实际应用需要出发&#xff0c;架构系统来改善现校园生活助手系统工作流程繁琐等问题。不仅如此以操作者…

国产CAN总线收发芯片DP1042 兼容替换TJA1042

说明 1 简述 DP1042是一款应用于 CAN 协议控制器和物理总线之间的接口芯片&#xff0c;可应用于卡车、公交、小汽车、工业控制等领域&#xff0c;支持 5Mbps CAN FD 灵活数据速率&#xff0c;具有在总线与 CAN 协议控制器之间进行差分信号传输的能力&#xff0c;完全兼容“ISO…

Fabric.js 样式不更新怎么办?

本文简介 带尬猴&#xff0c;我嗨德育处主任 不知道你有没有遇到过在使用 Fabric.js 时无意中一些骚操作修改了元素的样式&#xff0c;但刷新画布却没更新元素样式&#xff1f; 如果你也遇到同样的问题的话&#xff0c;可以尝试使用本文的方法。 是否需要重新绘制 我先举个例…