数码管显示(89C51 Proteus仿真)
数码管
数码管分为共阴数码管和共阳数码管。数码管极性不同所对应的程序也不同,现实中多通过三极管驱动数码管,因此常用共阳极数码管。
单位数码管
Proteus原理图:
代码:
我们可以按照右键原理图让对应的段导通,以显示数字。
对于共阳数码管,若显示数字0,可以让标号为A,B,C,D,E,F的段导通,标号为G,H的段不导通,然后将阳极通入高电压,即显示数字0。
具体如下图:
段选:P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0
H G F E D C B A
1 1 0 0 0 0 0 0 ==> 0xC0
位选:P3.0
1
段选,位选是描述数码管的专有名词,需理解记忆!
注意:P2的顺序是自右向左的!!!
;一位数码管显示数字 0
ORG 00H
AJMP START
ORG 40H
START:
MOV P2, #0C0H ;段选
SETB P3.0 ;位选
AJMP $
END
效果:
多位数码管
了解完单位数码管如何显示,我们来看看多位数码管,相较于单位数码管,多位数码管更加复杂,驱动函数有很大区别。
多位数码管原理图:
可以看出多位数码管使用同一组段选,不同的位选,因此我们就不能够一对一得固定显示,这时我们就需要动态扫描。
动态扫描:利用人眼视觉暂留,四位数码管每次只显示一位数字,但是切换频率大于200HZ(50 × 4),这样就能让人产生同时显示四个数字的错觉。
但是一个完整的驱动程序不只这些,一个完整的数码管驱动有6部分:
- 码表(ROM):存储段码(一般放在ROM中,节省RAM空间),例如数字0的段码就是0xC0,码表则包含0-9的段码
- 显存(RAM):保存要显示的数字,取连续地址(便于查表)
- 段选赋值:通过查表(码表)操作,将显存映射到段码
- 位选切换:切换显示的位置
- 延时:显示的数字短暂保持,提升亮度
- 消影:消除切换时不同位置互相影响而产生的残影
;四位数码管显示数字 1234
ORG 00H
AJMP START
;码表-------------------------------------------------------------
ORG 1000H
DB 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90
ORG 40H
START:
;显存-------------------------------------------------------------
MOV 30H, #1
MOV 31H, #2
MOV 32H, #3
MOV 33H, #4
;主循环-----------------------------------------------------------
MAINLOOP:
ACALL DISPLAY ;调用显示函数
AJMP MAINLOOP ;循环
;显示函数---------------------------------------------------------
;段选:P2.0->P2.7
;位选:P3.0->P3.3
DISPLAY:
MOV DPTR, #1000H ;码表起始地址
MOV R0, #30H ;显存起始地址
MOV R1, #01H ;位选码 P3.7->0 0 0 0 0 0 0 1->P3.0
;四位循环
DISPLAYLOOP:
MOV P2, #0FFH ;消影
;查表操作
MOV A, @R0 ;间接寻址,获取显存
MOVC A, @A+DPTR ;将显存中的数字映射到段码
MOV P2, A ;段选赋值
MOV P3, R1 ;位选赋值
ACALL DELAY ;延时
INC R0 ;显存地址自加,切换到下一位数字的显存
;位选左移,切换到下一位显示
MOV A, R1
RL A
MOV R1, A
CJNE R1, #10H, DISPLAYLOOP ;根据位选码,判断是否完成四位切换
RET
;延时函数----------------------------------------------------------
DELAY:
MOV R7, #2
DELAYLOOP1:
MOV R6, #2
DELAYLOOP2:
MOV R5, #10
DELAYLOOP3:
NOP
DJNZ R5, DELAYLOOP3
DJNZ R6, DELAYLOOP2
DJNZ R7, DELAYLOOP1
RET
END
效果: