51单片机8位数码管计时器(汇编语言)

这篇具有很好参考价值的文章主要介绍了51单片机8位数码管计时器(汇编语言)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

51单片机8位数码管时钟(汇编语言)

作业要求

51单片机8位数码管计时器(汇编语言)
使用8位数码管实现时间的显示,进位等操作
使用汇编语言完成作业

最终效果

51单片机8位数码管计时器(汇编语言)

理论基础

寻址

汇编语言的一些基本寻址操作

MOV A,#20H
MOV R1,20H
MOV @R1,#20H
MOV A,@R1

需要理解用法和含义

中断

实现计时器需要使用中断来完成延时
如果使用循环延迟的话,在计时过程中处理器不能进行其他操作

位码

设置具体的显示位,如 00H 是数码管的第一位
本例中使用 P2 引脚输出位码

段码

输出图形的控制
本例中使用 P1 引脚
如 40H 为 -

显示

一个数字的显示需要位码和段码同时起作用
如 P1 输入 #00H, P2 输入 #40H
在数码管的第一位会显示 “-”

这里显示需要不连续的进行显示
(数字和"-"需要分开)
所以只用一个地址位去缓存位码是不够的
(如果是连续显示,不断修改buffer为位码就行了)
这里采用了6个地址空间去对位码进行缓存

MOV index,#00H
MOV cDisplayBit,#00H
MOV cDisplayBit+1,#01H
MOV cDisplayBit+2,#03H
MOV cDisplayBit+3,#04H
MOV cDisplayBit+4,#06H
MOV cDisplayBit+5,#07H

其中 02H 和 05H需要显示为"-",我使用另外一个子程序去进行显示

显示缓冲区

本例中使用 cDisplayBuffer 表示 20H,并将 20-25H 这六位作为显示缓冲区

存储需要显示的数字的原值,如1,2,3

从指定地址中取值然后转换为段码再配合位码即可实现显示

cDisplayBuffer 作为 位码的缓存位
难点
中间需要显示"-",所以位码缓存位只使用1位是不够的,详细参见下列代码拆分

结构

内存设置

ORG 0000H
SJMP MAIN
ORG 000BH
LJMP SER0
cDisplayBuffer 	EQU 20H ;
cDisplayBit 	EQU 40H	;当前显示的位 40-45;47 46固定显示-
index		EQU 50H	;作为遍历index使用

设置初值

需要写到MAIN函数中

MAIN:
   MOV index,#00H
   MOV cDisplayBit,#00H
   MOV cDisplayBit+1,#01H
   MOV cDisplayBit+2,#03H
   MOV cDisplayBit+3,#04H
   MOV cDisplayBit+4,#06H
   MOV cDisplayBit+5,#07H

中断延迟程序

MOV SP,#70H			;设置堆栈SP
CLR EA			;关中断
MOV 30H,#23H			;设置初始时间值
MOV 31H,#59H
MOV 32H,#56H
MOV TMOD,#01H		;使用定时器0,软件控制,定时模式,方式1
MOV TH0,000H			;定时初值
MOV TL0,0D8H
MOV R6,#28			;设定计数次数50,作为中断次数计数的全局变量
SETB EA			;开中断
SETB ET0			;允许T0中断
SETB TR0			;启动定时器0

此部分也需要放到MAIN函数中

显示程序

SHOW:
   LCALL LOOSE			;调用子程序拆分BCD码并存入显示缓冲区
   LCALL DISP			;调用显示子程序进行显示
   LJMP SHOW

DISP

有6位数需要显示,所以需要循环六次,故把 R3 置 6 然后使用 DJNZ 循环

我们不需要 2,5 两位数码管显示数字

所以循环中使用index去取得位码,位码的值已经在 40-45H 单元中设置好了

这里为了同时显示数字和"-"所以把它们两个分开了

使用index也是因为这个原因,不然的话位码缓存位只需要一个地址位就够了

这里调用了一下 Delay 是为了防止抖动,不调用的话会显示错误,

但是放到中断循环中又太快了,所以出此下策

DISP:				; 显示子程序
   MOV R3,#6H			; 总共6个位
   MOV index,#00H		; index置0
M1:
   LCALL Delay
   MOV	A,#40H
   ADD	A,index
   MOV	R0,A
   MOV	A,@R0
   MOV	P2,A
      
   MOV	DPTR,#DispTabLe
   MOV	A,#20H 			;A地址指向缓存
   ADD	A,index 		;位码的值加到A上
   MOV	R0,A
   MOV	A,@R0
   MOVC	A,@A+DPTR		;取段码
   MOV	P1,A
   INC	index	 		;index 加一

   DJNZ	R3,M1

M2:				;显示两个"-"的子程序

   LCALL Delay
   MOV P2,#02H 			; 02和05
   MOV P1,#40H 			; "-"的段码为 #40H
   LCALL Delay	
   MOV P2,#05H
   MOV P1,#40H
      
   RET

BCD转换

这里为了实现60进制所以把 30-32H 作为 十进制数 的缓存地址

取出十进制数后分别取高低位然后送入20-25H 的6位时间缓冲区

LOOSE:				;拆分子程序,压缩BCD码->hex
   MOV R5,#03H			;总共3个字节,需要循环3次
   MOV R0,#30H			;时间序列存储首地址
   MOV R1,#20H			;6位缓冲区
LOOP1:
   MOV A,@R0
   ANL A,#0F0H			;取高位
   SWAP A
   MOV @R1,A
   INC R1
   MOV A,@R0			;存高位
   ANL A,#0FH			;取低位
   MOV @R1,A			;存低位
   INC R0
   INC R1
   DJNZ R5,LOOP1
   RET

秒数自增

BCD转换完成后可以使用 CJNE 命令来实现进位

看注释即可明白,不过多叙述

NUMINC:				;时间序列加一秒子程序
   MOV R1,#32H			;时间序列末地址(秒)
   MOV A,@R1
   ADD A,#01H			;加1
   DA A				;转BCD码
   MOV @R1,A			;保存
   CPL P3.0
   CJNE @R1,#60H,TORET 		;若未到60秒,直接返回,否则执行下面程序
   MOV @R1,#00H			;秒数清零
   DEC R1			;进行分钟位的操作
   MOV A,@R1
   ADD A,#01H
   DA A
   MOV @R1,A
   CJNE @R1,#60H,TORET		;若未到60分,直接返回,否则执行下面程序
   MOV @R1,#00H			;分钟数清零
   DEC R1			;进行时数的操作
   MOV A,@R1
   ADD A,#01H
   DA A
   MOV @R1,A
   CJNE @R1,#24H,TORET		;若未到24时,直接返回,否则执行下面程序
   MOV @R1,#00H			;小时数清零

完整源代码

汇编源码

ORG 0000H
SJMP MAIN
ORG 000BH
LJMP SER0

cDisplayBuffer 	EQU 20H  	;6位段码实际值的缓冲区
cDisplayBit 	EQU 40H		;6位位码的缓冲区 40-45;47 46固定显示"-"
index		EQU 50H


MAIN:
   MOV index,#00H
   MOV cDisplayBit,#00H
   MOV cDisplayBit+1,#01H
   MOV cDisplayBit+2,#03H
   MOV cDisplayBit+3,#04H
   MOV cDisplayBit+4,#06H
   MOV cDisplayBit+5,#07H
   ; 存在2 5两位需要显示为 - 所以选用六个内存空间作为位码缓存


	
   MOV SP,#70H			
   CLR EA			
   MOV 30H,#22H			;设置初始时间值
   MOV 31H,#59H
   MOV 32H,#55H
   MOV TMOD,#01H		
   MOV TH0,000H			
   MOV TL0,0D8H
   MOV R6,#28			
   SETB EA			
   SETB ET0			
   SETB TR0			
SHOW:
   LCALL LOOSE			
   LCALL DISP			
   LJMP SHOW
SER0:				
   MOV TH0,#000H		
   MOV TL0,#0D8H
   DJNZ R6,EXIT			
   MOV R6,#28			
   LCALL NUMINC			

EXIT:
   RETI

LOOSE:				
   MOV R5,#03H			;总共3个字节,需要循环3次
   MOV R0,#30H			;时间序列存储首地址
   MOV R1,#20H			;6位缓冲区
LOOP1:
   MOV A,@R0
   ANL A,#0F0H			;取高位
   SWAP A
   MOV @R1,A
   INC R1
   MOV A,@R0			;存高位
   ANL A,#0FH			;取低位
   MOV @R1,A			;存低位
   INC R0
   INC R1
   DJNZ R5,LOOP1
   RET

DISP:				; 显示子程序
   MOV R3,#6H			; 总共6个位
   MOV index,#00H		; index置0
M1:
   LCALL Delay
   MOV	A,#40H
   ADD	A,index
   MOV	R0,A
   MOV	A,@R0
   MOV	P2,A
      
   MOV	DPTR,#DispTabLe
   MOV	A,#20H 			;A地址指向缓存
   ADD	A,index 		;位码的值加到A上
   MOV	R0,A
   MOV	A,@R0
   MOVC	A,@A+DPTR		;取段码
   MOV	P1,A
   INC	index	 		;index 加一

   DJNZ	R3,M1

M2:				;显示两个"-"的子程序

   LCALL Delay
   MOV P2,#02H 			; 02和05
   MOV P1,#40H 			; "-"的段码为 #40H
   LCALL Delay	
   MOV P2,#05H
   MOV P1,#40H
      
   RET

NUMINC:				
   MOV R1,#32H			;时间序列末地址(秒)
   MOV A,@R1
   ADD A,#01H			;加1
   DA A				;转BCD码
   MOV @R1,A			;保存
   CPL P3.0
   CJNE @R1,#60H,TORET 		
   MOV @R1,#00H			
   DEC R1			
   MOV A,@R1
   ADD A,#01H
   DA A
   MOV @R1,A
   CJNE @R1,#60H,TORET		
   MOV @R1,#00H			
   DEC R1			
   MOV A,@R1
   ADD A,#01H
   DA A
   MOV @R1,A
   CJNE @R1,#24H,TORET		
   MOV @R1,#00H			
	
TORET:
   RET
	
DispTable: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
			

Delay:
   MOV	R0,#10
   MOV	R1,#10
   DJNZ	R1,$
   DJNZ	R0,$-4
   RET
   
END

原理图

51单片机8位数码管计时器(汇编语言)

这里注意区分一下自己单片机的段码位码输出IO,前面已经说过了

后记

后面使用示波器抓波然后对循环和中断部分进行微调可以实现微秒级别的误差
51单片机8位数码管计时器(汇编语言)
这里我使用了CPL输出所以T=2s
“-” 的显示上还有其他方案,望读者自行思考
同学有的使用不判断进位来实现 “-” 的显示,这样displaybuffer仅需1位
不必像本文这样冗杂
希望读者能够有所收获!

参考了这篇文章
基于MCS-51单片机使用定时器编写时钟程序(汇编)
数码管显示部分在我的另一篇文章中有更详细的讲解
51单片机出租车计价器(汇编语言)
仿真文件下载 传送门
文章允许规范转载文章来源地址https://www.toymoban.com/news/detail-403250.html

到了这里,关于51单片机8位数码管计时器(汇编语言)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机静态数码管显示

    51单片机静态数码管显示 数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件。   数码管从上右下左中有ABCDEFGDP,共10个引脚,其中3、8号引脚是连接到所有二极管的阴极,A二级管对应7号和38号引脚,B二极管对应6号和38号引脚。所有阴极

    2024年02月08日
    浏览(51)
  • 51单片机数码管显示(三)

    目录 一、静态数码管显示 1、一位数码管 (1)LED数码管各段名称 (2)数码管引脚定义 (3) 共阴极(89C52RC单片机LED数码管采用共阴极方式) (4)共阳极 2、四位一体数码管 (1)四位一体数码管引脚定义 (2)上面共阴极和下面共阳极  3、数码管模块原理图详解 4、编写

    2024年02月08日
    浏览(30)
  • 二、51单片机控制数码管

    (1)数码管的外观: 数码管可分为单个的,联排的(2位、4位、8位) (2)数码管的作用: 数码管是显示器件,是用来显示数字的。 (1)数码管的亮灭是由内部的照明LED的亮灭实现的。 (2)一位数码管内部有八颗LED灯,利用内部的LED灯的亮和灭让数码管显示不同的数字。 (1)驱动方法的

    2023年04月09日
    浏览(31)
  • 51单片机入门————数码管显示

    我们在马路上看到的红绿灯,就是由数码管来实现的,就是其中可能加入了一些延时和转换 数码管是通过控制138译码器与74HC245来控制数码管的亮灭与数字的显示 我们先讨论一个数码管 数码管有共阳极和共阴极,我们现在使用的STC89C52是共阴极的,说明数码管共用阴极 上面是

    2024年02月13日
    浏览(27)
  • 51单片机矩阵键盘——数码管显示

    当我们熟悉了数码管的位选与段选,并了解的矩阵键盘的扫描之后就可以编写程序了。 按下矩阵键盘S1并松开,数码管第一位(LED8)显示0;按下矩阵键盘S2并松开,数码管第一位显示1;...按下矩阵键盘S16并松开,数码管第一位显示F; 矩阵键盘扫描(输入扫描)     原理:

    2024年02月11日
    浏览(39)
  • 51单片机控制数码管动态显示

    首先打开proteus,导入8位数码管和89c51。 然后如图连线,分清断码和位码, 断码就是一个数码管的7个LED灯。 位码:就是第几位显示,由于是共阴极,所以哪位接地就显示哪位。 下面通过改变位码的接线就可以看出不同的效果 下面就编写程序,从第1位到第8位显示从0到7的八

    2023年04月21日
    浏览(31)
  • 51单片机数码管显示0-9

    初级代码:使用延时函数,延时; 进阶代码:使用定时器,延时:51单片机定时器控制数码管显示_学习笔记吧的博客-CSDN博客 初级代码: 电路接线图:  

    2024年02月12日
    浏览(26)
  • 51单片机:数码管和矩阵按键

    目录 一:动态数码管模块 1:介绍  2:共阴极和共阳极 A:共阴极 B:共阳极 C:转化表  3:74HC138译码器 4:74HC138译码器控制动态数码管(位选) 5:数码管显示完整代码 6:74HC573锁存器 A:基本点 B:原理图介绍 c:74HC573控制数码管代码 二:矩阵按键模块 1:介绍 2:原理图  3:矩阵按键代码       

    2024年02月15日
    浏览(37)
  • 【51单片机-数码管】:用51单片机写一个八个数码管中选用任意相邻两个数码管,用来循环显示0-99之间的数据,数据显示间隔为0.5s

             用普中51单片机写一个八个数码管中选用任意相邻两个数码管,用来循环显示0-99之间的数据,数据显示间隔为0.5s。         随机数码管 00-99  循环0.5s  显示。        数码管是一种数字显示器件,它由多个发光二极管(LED)组成,可以显示数字、字母、符号等

    2024年02月07日
    浏览(36)
  • 51单片机静态数码管原理及代码

    单个数码管有 8个LED灯 ,通过输入电平点 亮a~g可显示数字 ,以下为原理图:   数码管原理图分为共阴极与共阳极两种 : ① 共阴极 :a~dp位于发光二极管的阳极(即高电平的一端)部分,左接GND端 ② 共阳极 :a~dp位于发光二极管的阴极(即低电平的一端)部分,右接VCC电源

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包