折腾来折腾去

pikipity的blog

汇编实战之LED数码管

之前已经讲述了如何用汇编来实现加减乘除的实现方法,但是只是做运算是远远不够的,还需要将运算后的数字显示出来,那么如何显示呢,这篇讲述如何用时钟中断以尽量少的I/O口的数量来实现LED数码管的显示。

算法

说是算法,很不准确啊,但是没有想出更好的题目了,主要是介绍一下我的想法,这种想法还是非常常见和好用的。主要为两点:

  1. 不是所有数码管同时亮,而是一个一个的亮,利用人眼的视觉误差,让人感觉是一起亮就可以了。由于人眼的视觉停留大约为0.1s,也就是说要在0.1s内将全部数码管显示一遍,这里我们放置了5个,显示一个的时间大约是0.02s,这里使用12MHz的晶振,时钟周期位$\frac{1}{12}$us,机械周期为1us,那么计时器设定为计时20000就可以了。

  2. 由于十进制数字只有$0\sim 9$十个数字,数量少且固定,所以可以通过查表法来控制数码管。

电路图

数码管显示电路图

主要原件如下:

  1. 8051系列单片机使用 AT89C51。
  2. 数码管选择7段共阴数码管。
  3. 用来选择数码管的38译码器 74HC138,这样就可以只用三个引脚就可以最多从8个数码管中选择一个了。74HC138的真值表如下

    74HC138真值表

程序

这个程序是让电路图中的五个数码管从左到右显示数字 1,2,3,4,5

    ORG 0H
    JMP START
    ORG 0BH    ;0BH is the timer0 interrupt address
    JMP DISPLAY
    ORG 30H    ;avoid interrupt address
    MOV SP,#30H
;;;;;;;;;;;;;;;;;;;;;;;;;;
;Display five 7-seg LEDs
;note: the most left LED is number 1
;input: 5FH, 5EH, 5DH, 5CH, 5BH
;output: P2.0, P2.1, P2.2 -> choose LED
;        P1 -> display
;REG: A (has been protect), DPTR, 5AH
DISPLAY:
    PUSH Acc
    ;choose LED
    MOV A,5AH
    MOV P2,A
    ;choose number
    MOV A,5AH
    CJNE A,#0,next1
display0:
    MOV A,5FH
    MOVC A,@A+DPTR
    MOV P1,A
    JMP display_end
next1:
    CJNE A,#1,next2
display1:
    MOV A,5EH
    MOVC A,@A+DPTR
    MOV P1,A
    JMP display_end
next2:
    CJNE A,#2,next3
display2:
    MOV A,5DH
    MOVC A,@A+DPTR
    MOV P1,A
    JMP display_end
next3:
    CJNE A,#3,next4
display3:
    MOV A,5CH
    MOVC A,@A+DPTR
    MOV P1,A
    JMP display_end
next4:
    CJNE A,#4,display_end
display4:
    MOV A,5BH
    MOVC A,@A+DPTR
    MOV P1,A
    JMP display_end
display_end:
    MOV A,5AH
    CJNE A,#4,add_5AH
    JMP clear_5AH
clear_5AH:
    MOV 5AH,#0
    JMP displayend
add_5AH:
    INC 5AH
    JMP displayend
    ;
displayend:
    MOV TL0,#low (65536-20000)
    MOV TH0,#high (65536-20000)
    POP Acc
    RETI        
;table of LED
table:
    DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
START:
;;;;;;;;;;;;;;;;;;;;;;;;;;
;Display initial
    MOV P1,#0
    MOV P2,#0FFH
    MOV 5AH,#0
    MOV DPTR,#table
;;;;;;;;;;;;;;;;;;;;;;;;;;
;Timer initial
    MOV TMOD,#1;use timer 0 mode 1
    MOV TL0,#low (65536-20000)
    MOV TH0,#high (65536-20000)
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Interrupt initial
    SETB ET0;start timer0 interval
    ;
    SETB EA    ;start interrupt
    SETB TR0   ;start timing
    MOV 5FH,#1
    MOV 5EH,#2
    MOV 5DH,#3
    MOV 5CH,#4
    MOV 5BH,#5
    ;
STOP:
    JMP STOP
    END

效果

将速度放慢后的仿真效果是这样的:

仿真效果

注意:由于仿真软件只是显示仿真的计算效果,可能会由于时间调整不恰当,出现不合适的仿真结果,建议可能的话,还是用实物比较靠谱



Comments