51单片机实验04 -数码管的动态显示实验

目录

一、实验目的

二、实验内容

三、实验原理

四、实验方法

五,实验效果及代码

1,效果

2,代码

六,课后习题

1,使用定时器T0的中断函数1 从999999~0计时

 1)效果

2)代码

2,使用定时器T1的中断函数3 从999999~0计时

1)效果 

2)代码


一、实验目的


1、熟悉掌握数码管动态显示的基本方法。
2、根据已知电路和设计要求在实验板上实现数码管动态显示。
3、掌握利用定时器T0中断的使用方法。


二、实验内容

在KST-51开发板上,选择任意左右相连的4位数码管,利用定时器T0中断实现动态显示0123→1234→2345→3456→4567→5678→6789→7890→8901→9012→0123→不断反复,每隔2s切换显示内容


三、实验原理


实验要求“4位数码管上实现动态显示

0123→1234→2345→3456→4567→5678→6789→7890→8901→9012→0123→不断反复,每隔2s切换显示内容”。动态扫描可以实现该要求。

简单地说,动态扫描就是选通一位,送一位数据。原理图中的LEDS0-LEDS5是相应数码管的位选信号,即选择哪个数码管显示数字;P0.0-P0.7是段码,即要显示的数字。可以通过依次选通某一位7段数码管并通过P0端口送出显示数据。由于人眼的视觉残留原理,如果这种依次唯一选通每一位7段数码管的动作在10ms内完成,就会造成多位数码管同时点亮显示各自数字的假象。
本实验使用定时器T0中断,实现每2s更新一次数字。

定时器有关代码请看前面文章:

51单片机实验03-单片机定时/计数器实验-CSDN博客


四、实验方法


1、根据电路图,分析和掌握数码管动态显示的原理,选择4位数码管。使用定时器T0中断实现每2秒更新一次数字的设计思路。
本次实验使用Timer0中断,由于其定时时间最大为65536us,不能实现2s的长延时,那么可以使用多次中断来实现,并且在中断到来时,不断地死循环显示数字,即根据动态显示原理“选通一位,来一位数据”。设x表示千位的数字,由于最大的数字为9,则(x%10)、(x+1)%10、(x+2)%10、(x+3)%10分别是千位、百位、十位、个位上的数字。在编写代码时,设置Timer0定时时间为2ms,可以用一个参数cnt计算中断的次数;当中断的次数达到1000次时,说明已经达到了2s,此时更新数字,即将数字x自增1。
2、针对要求,画出程序流程图,根据流程图进行代码编写。
3、编译调试生成HEX文件,进行代码烧写,完成数码管动态显示功能。


五,实验效果及代码

我选择的是中间四个数码管,如果想要选择其它数码管的,可以修改这几行代码:

addr2,addr1,addr0分别控制了138译码器的输出y0~y6,因为y6已经用来控制发光二极管 ,因此,y0~y5就是用来控制数码管的。例如,y0控制最右边的数码管leds0,对应的138译码器输入:

addr2=0;addr1=0;addr0=0;

如果想要控制最左边的数码管,就需要y5输出低电平。即addr2=1;addr1=0;addr0=1;

1,效果

0123-1234等数字的循环显示

2,代码

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;  // 使能端					  
	unsigned  char  code ledChar[]={	 // 晶体管0~9真值表
   0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90
//,0x88,0x83,0xC6,0xA1,0x86,0x8E
};

				  

	unsigned char ledBuff[]={    // 晶体管全灭
	0xFF,0xFF,0xFF,0xFF
	};		 
	unsigned int outflow=0;  // 记录定时器溢出次数
	unsigned char  ind=0;  // 动态扫描的索引
	unsigned char flags=0;  // 2s定时标志
void  main(){
	unsigned long sectransistor=0;  // 记录数码管显示的秒数

    enled=0;
	addr3=1;
	TMOD=0x01;  // 定时器T0选择模式1(16位定时器)
	TH0=0xFC;   // 定时器的初始值
	TL0=0x67; 

	EA=1;   //总中断打开
	ET0=1;  // 定时器0使能中断打开

	TR0=1;      // 定时器T0运行
	while(1){  	 // 写好定时器中断服务后再使用while循环
		if(flags==2){	 // flags是2s定时
		 flags=0;   // 重新计时,直到flags再次等于1(时间再次为2s)
		ledBuff[0]=ledChar[(sectransistor+3)%10];	 
		ledBuff[1]=ledChar[(sectransistor+2)%10];
		ledBuff[2]=ledChar[(sectransistor+1)%10];  // 0+1对10取余为1 ,10对10取余为0
		ledBuff[3]=ledChar[sectransistor%10]; // 最左边的晶体管数值最小0
		sectransistor++;  // 秒数自增
		
		}
	
	}
	
		}

	void  InterruptTimer0() interrupt 1{	  // 定时器T0中断服务函数1
	TH0=0xFC;   // 定时器初始值
	TL0=0x67; 
	outflow++;	// 溢出自增
	if(outflow==2000){		 //每隔2s切换显示内容
	   outflow=0;
	   flags=2;  // 2s到了之后,flags立起来
	
	}
		P0=0xFF;  // 关闭段
	 switch(ind){   // 控制指定晶体管亮起
	  case 0:addr2=0;addr1=0;addr0=1;ind++;P0=ledBuff[0];break;
	  case 1:addr2=0;addr1=1;addr0=0;ind++;P0=ledBuff[1];break;
	  case 2:addr2=0;addr1=1;addr0=1;ind++;P0=ledBuff[2];break;
	  case 3:addr2=1;addr1=0;addr0=0;ind=0;P0=ledBuff[3];break;
	  default: break;
	  }
	}



六,课后习题

 需要知道的是,使用不同的定时器,所对应的中断函数也是不一样的,如下表中所示👇

 可以看到,定时器T0的中断函数编号是1 ,而定时器T1的中断函数3,因此在写程序的时候需要正确更改interrupt后面的编号。

1,使用定时器T0的中断函数1 从999999~0计时

 1)效果

效果同T1定时器👇:

定时器T1使用中断函数从999999~0计时

2)代码

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;  // 使能端					  
//	unsigned  char  code ledChar[]={	 // 晶体管真值表
//0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
//0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
//};

				   //倒计时	    0x8E,0x86,0xA1,0xC6,0x83,0x88,  
    unsigned char  code ledChar[]={	  // 从数值9开始		  
	0x90,0x80,0xF8,0x82,0x92,0x99,0xB0,0xA4,0xF9,0xC0
	
	
	};
	unsigned char ledBuff[]={    // 晶体管全灭
	0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF
	};		 
	unsigned int outflow=0;  // 记录定时器溢出次数
	unsigned char  ind=0;  // 动态扫描的索引
	unsigned char flags=0;  // 1s定时标志
void  main(){
	unsigned long sectransistor=0;  // 记录数码管显示的秒数
//  0~999999
    enled=0;
	addr3=1;
	TMOD=0x01;  // 定时器T0选择模式1
	TH0=0xFC;   // 定时器的初始值
	TL0=0x67; 

	EA=1;   //总中断打开
	ET0=1;  // 定时器0使能中断打开

	TR0=1;      // 定时器T0运行
	while(1){  	 // 写好定时器中断服务后再使用while循环
		if(flags==1){	 // flags是1s定时
		 flags=0;   // 重新及时,直到flags再次等于1
		ledBuff[0]=ledChar[sectransistor%10];	 // 开启指定晶体管	
		ledBuff[1]=ledChar[sectransistor/10%10];
		ledBuff[2]=ledChar[sectransistor/100%10];
		ledBuff[3]=ledChar[sectransistor/1000%10];
		ledBuff[4]=ledChar[sectransistor/10000%10];
		ledBuff[5]=ledChar[sectransistor/100000%10];
		
		sectransistor++;  // 数码管在之前的基础上+1s
		
		}
	
	}
	
		}

	void  InterruptTimer0() interrupt 1{	  // 定时器T0中断服务函数1
	TH0=0xFC;   // 定时器初始值
	TL0=0x67; 
	outflow++;	// 溢出自增
	if(outflow==1000){		 //1s
	   outflow=0;
	   flags=1;  // 1s到了之后,flags立起来
	
	}
		P0=0xFF;  // 关闭段
	 switch(ind){   // 控制指定晶体管亮起
	  case 0:addr2=0;addr1=0;addr0=0;ind++;P0=ledBuff[0];break;
	  case 1:addr2=0;addr1=0;addr0=1;ind++;P0=ledBuff[1];break;
	  case 2:addr2=0;addr1=1;addr0=0;ind++;P0=ledBuff[2];break;
	  case 3:addr2=0;addr1=1;addr0=1;ind++;P0=ledBuff[3];break;
	  case 4:addr2=1;addr1=0;addr0=0;ind++;P0=ledBuff[4];break;	
	  case 5:addr2=1;addr1=0;addr0=1;ind=0;P0=ledBuff[5];break;
	  default: break;
	  }
	
	}



2,使用定时器T1的中断函数3 从999999~0计时

1)效果 

定时器T1使用中断函数从999999~0计时

2)代码

#include<reg52.h>
sbit enled=P1^4;   // 138译码器使能  
sbit addr3=P1^3;
sbit addr2=P1^2;
sbit addr1=P1^1;
sbit addr0=P1^0;  // 使能端					  
//	unsigned  char  code ledChar[]={	 // 晶体管真值表
//0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
//0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
//};

				   //倒计时	    0x8E,0x86,0xA1,0xC6,0x83,0x88,
    unsigned char  code ledChar[]={
	 0x90,0x80,0xF8,0x82,0x92,0x99,0xB0,0xA4,0xF9,0xC0
	
	
	};
	unsigned char ledBuff[]={    // 晶体管全灭
	0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF
	};		 
	unsigned int outflow=0;  // 记录定时器溢出次数
	unsigned char  ind=0;  // 动态扫描的索引
	unsigned char flags=0;  // 1s定时标志
void  main(){
	unsigned long sectransistor=0;  // 记录数码管显示的秒数
//  0~999999
    enled=0;
	addr3=1;
	TMOD=0x10;  // 定时器T1选择模式1
	TH1=0xFC;   // 定时器初始值
	TL1=0x67; 

	EA=1;   //总中断打开
	ET1=1;  // 定时器1使能中断打开

	TR1=1;      // 定时器运行
	while(1){  	 // 写好定时器中断服务后再使用while循环
		if(flags==1){	 // flags是1s定时
		 flags=0;   // 重新及时,直到flags再次等于1
		ledBuff[0]=ledChar[sectransistor%10];	 // 开启指定晶体管	
		ledBuff[1]=ledChar[sectransistor/10%10];
		ledBuff[2]=ledChar[sectransistor/100%10];
		ledBuff[3]=ledChar[sectransistor/1000%10];
		ledBuff[4]=ledChar[sectransistor/10000%10];
		ledBuff[5]=ledChar[sectransistor/100000%10];
		
		sectransistor++;  // 数码管在之前的基础上+1s
		
		}
	
	}
	
		}

	void  InterruptTimer1() interrupt 3{	  // 定时器0中断服务函数
	TH1=0xFC;   // 定时器初始值
	TL1=0x67; 
	outflow++;	// 溢出自增
	if(outflow==1000){		 //1s
	   outflow=0;
	   flags=1;  // 1s到了之后,flags立起来
	
	}
		P0=0xFF;  // 关闭段
	 switch(ind){   // 控制指定晶体管亮起
	  case 0:addr2=0;addr1=0;addr0=0;ind++;P0=ledBuff[0];break;
	  case 1:addr2=0;addr1=0;addr0=1;ind++;P0=ledBuff[1];break;
	  case 2:addr2=0;addr1=1;addr0=0;ind++;P0=ledBuff[2];break;
	  case 3:addr2=0;addr1=1;addr0=1;ind++;P0=ledBuff[3];break;
	  case 4:addr2=1;addr1=0;addr0=0;ind++;P0=ledBuff[4];break;	
	  case 5:addr2=1;addr1=0;addr0=1;ind=0;P0=ledBuff[5];break;
	  default: break;
	  }
	
	}



有问题请在评论区留言,一天8h在线。

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

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

相关文章

国内低代码平台大揭秘:十大排名榜单综述

国内低代码平台有&#xff1a;Zoho Creator、腾讯云云开发、阿里云宜搭、华为云AppCube、爱速搭、白码、织信、活字格、ClickPaaS、简道云。 一、Zoho Creator Zoho Creator是一款基于云计算的低代码平台&#xff0c;旨在帮助企业和开发者快速构建和部署应用程序。该平台提供…

论AEM CV-100 K50E|K60E|NSA升级注意事项

新加坡AEM公司在中国的平台深圳维信仪器报道&#xff1a;近日有很多小伙伴过来咨询&#xff0c;CV-100如何升级&#xff1f;都是想要使用最新的测试功能&#xff0c;比如上图的TDR高精度测试&#xff0c;可以准确的判定被测线缆的故障点。 5.0.307版本不含有tdr高精度测试&…

一键下载全自动安装Office全家桶

概述 今天分享一款超级强大的工具软件&#xff0c;该软件实现了一键自动化下载、安装Office全家桶的功能。整套安装流程堪称行云流水&#xff0c;从下载到安装全自动&#xff0c;无需上手操作。只需要安装该工具软件后&#xff0c;点击安装即可。软件会自动识别不同的操作系统架…

虹科技术丨全新Linux环境PCAN驱动程序发布!CAN/CAN FD通信体验全面升级!

来源&#xff1a;虹科汽车电子 虹科技术丨全新Linux环境PCAN驱动程序发布&#xff01;CAN/CAN FD通信体验全面升级&#xff01; 原文链接&#xff1a;https://mp.weixin.qq.com/s/4RXqjUa_odEaxAhcfQOHaA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #PCAN #Linu…

《Linux运维总结:Kylin V10+ARM架构CPU基于docker-compose一键离线部署redis6.2.8之容器版哨兵集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&…

【linux】Ubuntu 修改用户名

第一次打开Ubuntu时不小心把初始用户名“siriusiot”写成“siriousiot”&#xff08;多了一个o&#xff09; 。作为技术人&#xff0c;我们要保持严谨&#xff0c;我们要纠正过来&#xff08;其实就是单词拼错了怕被笑话&#xff09;。 打开终端&#xff0c;输入&#xff1a; …

高效解决Visual Studio Code中文乱码问题

文章目录 问题解决步骤 问题 Visual Studio Code新建一个文件编码方式总是默认GBK&#xff0c;如果我不修改成默认UTF-8&#xff0c;那么每次运行&#xff0c;如果有中文需要输出就会乱码&#xff01; 解决步骤 之后我会持续更新&#xff0c;如果喜欢我的文章&#xff0c;请记…

2024的新宠儿——Mamba(3):Mamba的三大创新

mamba(其对应论文为:https://arxiv.org/abs/2312.00752,这是其对应的GitHub代码地址:GitCode - 开发者的代码家园),在语言、音频、DNA序列模态上都实现SOTA,在最受关注的语言任务上,Mamba-3B超越同等规模的Transformer,与两倍大的Transformer匹敌,并且相关代码、预训练模…

【计算机毕业设计】微信小程序:MHK自学平台的设计与实现——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

vue3【详解】 vue3 比 vue2 快的原因

使用 Proxy 实现响应式 vue3使用的 Proxy 在处理属性的读取和写入时&#xff0c;比vue2使用的defineProperty 有更好的性能&#xff08;速度加倍的同时&#xff0c;内存还能减半&#xff01;&#xff09; 更新类型标记 Patch Flag 在编译模板时&#xff08;将vue语法转换为js描…

搜维尔科技:【工业仿真】煤矿机械安全事故VR警示教育系统

产品概述 搜维尔科技 煤矿机械安全事故VR警示教育系统 系统内容&#xff1a; 系统采用虚拟现实技术模拟矿井井下机械安全技术及事故&#xff0c;展现井下常见机械伤害事故&#xff0c;表现伤害事故的隐患点&#xff0c;能够模拟事故发生和发展过程&#xff1b;营造井下灾害发…

创业之路:专注与腾挪的艺术

在创业的道路上&#xff0c;每一个创业者都面临着无数的挑战和选择。著名投资人吴世春曾言&#xff1a;“树挪死&#xff0c;人挪活&#xff1b;顺利时学会专注&#xff0c;一旦不顺时学会腾挪。”这句话道出了创业过程中专注与腾挪的重要性&#xff0c;也为创业者们指明了方向…

STL-List

前言 我们将进入到CSTL 的学习。STL在各各C的头文件中&#xff0c;以源代码的形式出现&#xff0c;不仅要会用&#xff0c;还要了解底层的实现。源码之前&#xff0c;了无秘密。 STL六大组件 Container通过Allocator取得数据储存空间&#xff0c;Algorithm通过Iterator存取Con…

C语言 选择控制结构(1) 了解选择结构 关系运算符讲解 基本逻辑判断演示

接下来 我们来说 选择控制结构 在生活中 我们也有很多需要分支结构的例子 比如: 计算两个整数的最大值 计算n个数的最大值&#xff0c;最小值 判断三角形三边能否构成三角形? 判断某年是否是闰年? 判断输入的英文字母是大写还是小写? 我们在程序开发中 需要根据某种条件 进…

Docker(二)Docker+ server部署极简前端页面

本篇文章介绍如何使用 Dockerserver 将一个极简前端页面进行部署 1.本地运行一个简单的前端页面&#xff0c;再把它部署到服务器上 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

书生·浦语大模型第二期实战营(5)笔记

大模型部署简介 难点 大模型部署的方法 LMDeploy 实践 安装 studio-conda -t lmdeploy -o pytorch-2.1.2conda activate lmdeploypip install lmdeploy[all]0.3.0模型 ls /root/share/new_models/Shanghai_AI_Laboratory/ln -s /root/share/new_models/Shanghai_AI_Laborato…

一键部署本地AI大模型,全脚本实现

一、快捷部署 #!/bin/bash ################################################################################# # 作者&#xff1a;cxytoctalkhwy 2024-04-09 # 功能&#xff1a;自动部署Ollama&#xff08;Docker方式&am…

机器学习波士顿房价

流程 数据获取导入需要的包引入文件,查看内容划分训练集和测试集调用模型查看准确率 数据获取 链接&#xff1a;https://pan.baidu.com/s/1deECYRPQFx8h28BvoZcbWw?pwdft5a 提取码&#xff1a;ft5a --来自百度网盘超级会员V1的分享导入需要的包 import pandas as pd imp…

关于Wordpress的操作问题1:如何点击菜单跳转新窗口

1.如果打开&#xff0c;外观-菜单-菜单结构内&#xff0c;没有打开新窗口属性&#xff0c;如图&#xff1a; 2.在页面的最上部&#xff0c;点开【显示选项】&#xff0c;没有这一步&#xff0c;不会出现新跳转窗口属性 3.回到菜单结构部分&#xff0c;就出现了

【嵌入式开发】SecureCRTPortable工具进行串口信息监听打印

SecureCRTPortable工具进行串口信息监听打印 一、什么是SecureCRT二、如何使用SecureCRT进行串口监听1、硬件连接2、驱动安装3、软件连接4、串口连接5、日志设置 近期发现许多小伙伴欠缺SSH工具使用基础&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;这里奉上使用教…