《微机实验》报告
实验名称 LED数码管显示实验
指导教师
专业班级 姓名 学号 序号
联系方式
一、任务要求
基本要求:
利用末位数码管循环显示数字0-9,显示切换频率为1Hz。
提高要求:
在4位数码管显示器上依次显示当天日期和时间,显示格式如下:
yyyy (年份)
mm.dd(月份.日)
hh.mm(小时.分钟)
相关输出接口和控制接口如下:
二、设计思路
1.基本部分设计思路:
首先依次计算得出共阴极LED数码管对应0~9的段码数据,依次分别为:FCH,60H,DAH,F2H,66H,B6H,BEH,E0H,FEH,F6H;并将上述段码以字符的形式分别存于存储区域的50H~59H。以备取用。
然后以1HZ的频率分别将上述段码分别依次循环输出至P1端口,每次输出时均使P0.7和P0.6均为低电平,即选择末位数码管显示相应数据:
使用计数器T0,并选择定时方式1,即16位定时器,由初始化代码可知指令周期为16us,计算可得计数器初值为0BDCH时(即TH0为0BH,TL0为DCH),计时时间即为1s。每次计时1s时,使用查表指令MOVC A,@A+DPTR从段码存储区域依次取出段码数据,并输出给P1端口,同时选择末位数码管进行显示。每次查表输出持续1s后,对存储地址R0进行加一操作,然后循环查表取下一个相应段码数据。直到R0=59H时,最
后一个段码已取出并输出,重新赋值R0←50H,然后从第一个段码开始查表取出数据,再依次查表取出段码数据并选择末位数码管输出,如此无限循环下去。
2.提高部分设计思路:
首先依次计算得出共阴极LED数码管对应“2012”“11.07”“23.45”的段码数据,且由于每次输出时从末位开始刷新,需要按“2→1→0→2”“7→0→1.→1”“5→4→3.→2”的顺序输出给P1端口,其段码数据分别为:DAH,60H,FCH,DAH,E0H,FCH,61H,60H,B6H,66H,F3H,DAH;并将上述段码以字符的形式分别存于存储区域的50H~5BH。以备取用。
同样使用T0计数器的定时方式1,其初值为0BDC时,计时时间为1s,每次显示时间持续设定为3s,即可用循环指令DJNZ使计数器定时3次,循环结束后恢复循环次数为3,以备下一次显示时间仍持续为3s。
开始显示“2012”,首先使用查表指令MOVC A,@A+DPTR从段码存储区域取出第一个段码数据“DAH”输出给P1端口,并且令P0=00H(P0.7,P0.6均为低电平)选择末位数码管进行显示;然后2ms时间后,对存储地址R3进行加一操作,并且用查表指令取出下一个段码数据“60H”输出给P1端口,并且使数码管选择寄存器R2加40H,即使P0=40H(P0.7为低电平,P0.6为高电平)选择倒数第二个数码管进行显示;再过2ms时间后,对存储地址R3进行加一操作,并且用查表指令取出下一个段码数据“FCH”输出给P1端口,并且使数码管选择寄存器R2加40H,即使P0=80H(P0.7为高电平,P0.6为低电平)选择第二个数码管进行显示;继续2ms时间后,对存储地址R3进行加一操作,并且用查表指令取出下一个段码数据“DAH”输出给P1端口,并且使数码管选择寄存器R2加40H,即使P0=C0H(P0.7和P0.6均为高电平)选择首位数码管进行显示;如此
循环,每隔2ms刷新一次数码管显示数据,在实验板用肉眼无法察觉此刷新过程,速度够快的话即可看出“2012”为同时显示,速度慢可能有闪烁。此动态刷新显示过程持续3s。
刷新显示“2012”持续3s后,更改显示首地址,使首地址改为54H,然后使用查表指令取出54H中的段码,即“E0H”输出给P1端口,并选择末位数码管显示,每隔2ms时间依次取段码“FCH”→“61H”→“60H”输出给P1端口,并且从后向前依次选择相应的数码管进行显示。在实验板上用肉眼即可看出同时显示“11.07”,此动态刷新显示过程仍持续3s。显示3s后继续更改显示首地址为58H,然后使用查表指令取出58H中的段码,即“B6H”输出给P1端口,并选择末位数码管显示,每隔2ms时间依次取段码“66H”→“F3H”→“DAH”输出给P1端口,并且从后向前依次选择相应的数码管进行显示。在实验板上用肉眼即可看出同时显示“23.45”,此动态刷新显示过程持续3s。3s后更改显示地址为8CH,此时进行条件转移并重新赋显示首地址为50H。开始下一个循环显示,如此即可实现要求的功能。
三、资源分配
1.基本部分资源分配:
P1:数码管的段码输出端口
P0.7,P0.6:选择不同数码管显示的控制位
SP:堆栈指针存放子程序
TH0,TL0:存放计数器初值
DPTR:作为查表指令的变址寻址的基址
R0:查表指令寻址的间接地址,存放相应段码数据。
2.提高部分资源分配:
P1:数码管的段码并行输出端口
P0.7,P0.6:选择不同数码管显示的控制位
SP:堆栈指针存放子程序
TH0,TL0:存放计数器的初值
DPTR:作为查表指令的变址寻址的基址
R0,R1:存放刷新频率的循环次数
R2:控制选择不同数码管的寄存器
R3:查表指令寻址的间接地址,存放相应的段码数据
R4:显示时间存放处,使显示时间为3s
R5:存放显示的首地址
BOOT,BOOT1:循环结束或者条件转移的判断条件
四、流程图
1.基本部分流程图:
2.提高部分流程图:
五、源代码 (含文件头说明、资源使用说明、语句行注释)
1.基本部分
$include (C8051F310.inc)
ORG 0000H
LJMP MAIN
ORG 000BH ;T0中断入口
LJMP IRQ_0
ORG 00FFH
MAIN: LCALL Init_Device ;初始化
MOV SP,#30H
MOV TMOD,#01H
MOV TH0,#0BH ;1s是计数器发生溢出
MOV TL0,#0DCH
SETB ET0 ;开中断
SETB EA
SETB TR0 ;开启计数器T0
MOV DPTR,#0 ;赋值数据指针
MOV R0,#50H
MOV A,R0
MOVC A,@A+DPTR ;查表取段码数据
LOOP: MOV P1,A ;输出给P1端口
CLR P0.7 ;选择数码管为末端数码管
CLR P0.6
AJMP LOOP ;循环
ORG 0010H
IRQ_0: MOV TH0,#0BH ;1s时计数器发生溢出
MOV TL0,#0DCH
CJNE R0,#59H,MARK1 ;当查表没到最后一个段码时,转到MARK1
MOV R0,#50H ;当查表到最后一个段码是重新赋值第一个段码
MOV A,R0
MOVC A,@A+DPTR ;查表取段码数据
AJMP MARK2
MARK1: INC R0 ;段码存储区加一
MOV A,R0 ;取下一个段码
MOVC A,@A+DPTR
MARK2: RETI
ORG 0050H ;显示0,1,2,3,4,5,6,7,8,9
DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H,0FEH,0F6H
PCA_Init: ;初始化部分
anl PCA0MD, #0BFh
mov PCA0MD, #000h
ret
Timer_Init:
mov TMOD, #001h
mov CKCON, #002h
ret
Port_IO_Init:
mov P0MDOUT, #0FDh
mov P3MDOUT, #002h
mov XBR1, #040h
ret
Init_Device:
lcall PCA_Init
lcall Timer_Init
lcall Port_IO_Init
ret
END
2.提高部分
$include (C8051F310.inc)
ORG 0000H
AJMP START
ORG 000BH
AJMP IRQ_0 BOOT EQU 40H BOOT1 EQU 41H
;T0中断程序入口
;定义两个变量,作为判断条件
ORG 0100H
START: LCALL Init_Device
MOV SP,#30H
MOV TL0,#0DCH MOV TH0,#0BH
MOV DPTR,#0H
MOV R2,#00H MOV R3,#50H
MOV R4,#3 MOV R5,#50H MOV BOOT,#54H
MOV BOOT1,#54H
SETB ET0 ;1秒发生一次溢出
;数码管选择寄存器
;每段显示3S
;储存显示起始地址,决定显示内容
;开启中断
SETB EA
SETB TR0 ;开启计数器T0
LOOP1: MOV P1,#00H;
MOV A,R3 MOVC A,@A+DPTR
ACALL SWITCH MOV P1,A; ACALL DELAY_TIME INC R3
MOV A,R3
CJNE A,BOOT1,LOOP1; MOV A,R5
MOV R3,A ;查表取段码数据
;共四个数码管,分别显示
;输出给P1端口
;调用延时刷新时间
;段码数据没到54H时循环至LOOP1
;更新显示首地址
MOV BOOT1,BOOT ;和判断条件
AJMP LOOP1;
AJMP $
IRQ_0: PUSH ACC MOV TL0,#0DCH MOV TH0,#0BH
DJNZ R4,MARK0 MOV R4,#3
MOV R5,BOOT MOV A,R5
CJNE A,#5CH,BRANCH MOV R5,#50H
MOV BOOT,#54H
;保持现场
;1s时计数器溢出
; 判断是否到第3S
;改变显示首地址
;在没有取到最后一个段码时改变判断条件
AJMP MARK0
BRANCH: MOV A,#4 ;每四个数据输出一段时间
ADD A,BOOT
MOV BOOT,A MARK0: POP ACC RETI
SWITCH: PUSH ACC MOV P0,R2
MOV A,R2
ADD A,#40H MOV R2,A;
POP ACC RET
;改变循环判断条件
;恢复现场
;本函数用于循环选择数码管
;数码管选择下一个
DELAY_TIME:
MOV R0,#30 ;此处为刷新频率
MARK2: MOV R1,#100 ;调整刷新频率能获得更好的效果
MARK1: DJNZ R1,MARK1;
DJNZ R0,MARK2;
RET
;显示2012 11.07 23.45
ORG 0050H
DB 0DAH,60H,0FCH,0DAH,0E0H,0FCH,61H,60H,0B6H,66H,0F3H,0DAH
PCA_Init: ;初始化部分
anl PCA0MD, #0BFh
mov PCA0MD, #000h
ret
Timer_Init:
mov TMOD, #001h
mov CKCON, #002h
ret
Port_IO_Init:
mov P0MDOUT, #0FDh
mov P3MDOUT, #002h
mov XBR1, #040h
ret
Init_Device:
lcall PCA_Init
lcall Timer_Init
lcall Port_IO_Init
ret
END
六、程序测试方法与结果、软件性能分析
1.基本部分软件测试:
运行程序,在每次查表取段码数据的指令处设置断点,观察P1端口的变化及其持续时间,且看到P0端口的P0.7和P0.6端始终均为低电平,即末位数码管亮。
⑴P1端口输出FCH,数码管显示0,持续时间0.98s,约为1s。
⑵P1端口输出60H,数码管显示1,一共用时约为2s
⑶P1端口输出DAH,数码管显示2,一共用时约3s
⑷P1端口输出F2H,数码管显示3,一共用时约4s
⑸P1端口输出66H,数码管显示4,一共用时约5s
⑹P1端口输出B6H,数码管显示5,一共用时约6s
⑺P1端口输出BEH,数码管显示6,一共用时约7s
⑻P1端口输出E0H,数码管显示7,一共用时约8s
⑼P1端口输出FEH,数码管显示8,一共用时约9s
⑽P1端口输出F6H,数码管显示9,一共用时约10s
⑾P1端口循环输出FCH,数码管显示0,一共用时约11s
⑿P1端口循环输出60H,数码管显示1,一共用时约13s,以后将一直按规律持续循环下去。
将程序用硬件调试,点击run运行程序之后,高三位数码管均熄灭,只有末位数码管亮,且末位数码管从0开始显示0,1,2,3,4,5,6,7,8,9。每个数字持续时间约为1s,显示9之后又循环显示至0,并将无限循环显示0~9。符合实验要求。
2.提高部分软件测试:
运行程序,在每次更新P1端输出的指令处,和每次更新显示首地址的指令处分别设置断点.观察相应的P1端口输出的段码以及相应的P0.7和P0.6端口的高低电平情况,即可对应显示数码管和显示数据的关系。
⑴在前3秒时间内,P1端口以0.2ms左右的刷新频率不断按照DAH,60H,FCH,DAH的顺序循环刷新,一直持续3s时间。
①2ms时开始刷新第一个数码管的显示数据。P0.7和P0.6均为低电平,末位数码管亮,P1端口输出DAH,即末位数码管显示2。
②2ms时间后刷新下一个数码管。P0.7为低电平,P0.6为高电平,倒数第二位数码管亮,P1端口输出60H,即倒数第二位数码管显示1。
③2ms时间后刷新下一个数码管。P0.7为高电平,P0.6为低电平,第二位数码管亮,P1端口输出FCH,即第二位数码管显示0.
④2ms时间后刷新下一个数码管。P0.7和P0.6均为高电平,首位数码管亮,P1端口输出DAH,即首位数码管显示2。
⑤前3s内,一直按照上述顺序不断以2ms的刷新频率进行刷新,数码管从首位到末位一直依次显示“2012”。直到2.95s(约3s)刷新最后一次:首位数码管显示2。
⑵在第3秒至第6秒的时间内,P1端口以0.2ms左右的刷新频率不断按照E0H,FCH,61H,60H的顺序循环刷新,一直持续3s时间。
①3s后开始刷新第一个数码管的显示数据。P0.7和P0.6均为低电平,末位数码管亮,P1端口输出E0H,即末位数码管显示7。
②2ms时间后刷新下一个数码管。P0.7为低电平,P0.6为高电平,倒数第二位数码管亮,P1端口输出FCH,即倒数第二位数码管显示0。
③2ms时间后刷新下一个数码管。P0.7为高电平,P0.6为低电平,第二位数码管亮,P1端口输出61H,即第二位数码管显示\"1.\"。
④2ms时间后刷新下一个数码管。P0.7和P0.6均为高电平,首位数码管亮,P1端口输出60H,即首位数码管显示1。
⑤第二个3s之内,一直按照上述顺序不断以2ms的刷新频率进行刷新,数码管从首位到末位一直依次显示“11.07”。直到5.88s(约6s)刷新最后一次:首位数码管显示1。
⑶在第6秒至第9秒的时间内,P1端口以0.2ms左右的刷新频率不断按照B6H,66H,F3H,DAH的顺序循环刷新,一直持续3s时间。
①6s后开始刷新第一个数码管的显示数据。P0.7和P0.6均为低电平,末位数码管亮,P1端口输出B6H,即末位数码管显示5。
②2ms时间后刷新下一个数码管。P0.7为低电平,P0.6为高电平,倒数第二位数码管亮,P1端口输出66H,即倒数第二位数码管显示4。
③2ms时间后刷新下一个数码管。P0.7为高电平,P0.6为低电平,第二位数码管亮,P1端口输出61H,即第二位数码管显示\"3.\"。
④2ms时间后刷新下一个数码管。P0.7和P0.6均为高电平,首位数码管亮,P1端口输出DAH,即首位数码管显示2。
⑤第三个3s之内,一直按照上述顺序不断以2ms的刷新频率进行刷新,数码管从首位到末位一直依次显示“23.45”。直到8.82s(约9s)刷新最后一次:首位数码管显示2。
2
⑷在第9秒至第12秒的时间内,P1端口以0.2ms左右的刷新频率不断按照DAH,60H,FCH,DAH的顺序循环刷新,一直持续3s时间。即在下一个3s时间内一直显示“2012”,如此循环下去,每隔3s变换一次显示数据,每个3s内按2ms频率一直刷新。结果数码管应该按照“2012”→“11.07”→“23.45”的顺序,每次显示3s,无限循环下去.
①下一个循环开始时,刷新第一个数码管的显示数据。P0.7和P0.6均为低电平,末位数码管亮,P1端口输出DAH,即末位数码管显示2。
然后进行下一个循环……
软件调试结束之后,用硬件进行调试。点击run开始运行程序,观察到数码管从首位至末位依次显示“2012”。显示时间持续3s左右之后,数码管从首位至末位开始依次显示“11.07”。显示持续3s左右之后,数码管从首位至末位开始依次显示“23.45”。显示过程中,数码管的亮度没能达到最亮,略微有点暗。显示“23.45”持续约3s之后开始不断循环显示上述数据。结果符合实验要求。
思考题:
1. 数码管采用动态驱动方式时刷新频率应如何选择?为什么?
答:数码管采用动态驱动方式时,刷新时间在理论上应该尽可能要小,即刷新频率要尽可能快。如果刷新时间太长,可能会明显得观察到数码管显示状态下会有一定的抖动,且亮度较暗。刷新时间越长,数码管显示的抖动情况越厉害,亮度也会越暗。尽可能减小刷新时间,增大刷新频率,即可减小数码管显示的抖动,用肉眼观察会呈现长亮的状态,亮度也会随着刷新时间的减小而增大。但是若刷新时间太短,亮度会过大,有可能损坏LED数码管,而且可能来不及显示,用肉眼观察会发现所有数码管的每一段LED灯都处于长亮的状态,即永远显示为“8”。
一般来说,刷新时间应选择10^-3s,即ms的数量级。本实验选择了2ms的刷新频率。亮度合适,而且肉眼观察没有明显的抖动现象。
因篇幅问题不能全部显示,请点此查看更多更全内容