答案:一个月前作的。忘的差不多了。不过绝对是自己做的。
;51时钟程序,2012-7-5 AM
;采用T0中断,方式1,每50ms响应一次
;共阴极数码管阴极接P1,阳极接P0,P1.0~P1.6分别接a~f,P1.7接小数点,数码管从右向左依次接P0.0~P0.5
;晶振为11.0592MHz
SEC EQU 30H ;second
MIN EQU 31H ;minute
HOUR EQU 32H ;hour
TICK equ 33H ;timer
BUF EQU 34H ;
ORG 0000H
RESET:
AJMP MAIN ;jmp to function main
ORG 000BH ;intrace of interrupt T0
AJMP INT_T0 ;jmp to interrupt T0
ORG 0100H ;function main
MAIN:
MOV SP,#60H
ORL TMOD,#01H ;set T0 as mode 1
;初始化时分秒为0
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
ACALL PT0M0 ;call function PT0M0
MOV TICK,#20 ;每响应20次中断刷新一次时间
;MOV A,#0
;MOV DPTR,#NUM
;MOVC A,@A + DPTR
;XCH A,P1
;MOV P0,#0
MOV P1,#0FFH
MOV P0,#0FFH
HERE:
ACALL PRINT ;显示数字
AJMP HERE ;LOOP
PT0M0:
;初始化计数器T0=4BFD
MOV TL0,#0FDH
MOV TH0,#4BH
SETB TR0
SETB ET0
SETB EA
RET
INT_T0:
;初始化计数器T0=4BFD
MOV TL0,#0FDH
MOV TH0,#4BH
DJNZ TICK,END_T0
;CPL P1.0
MOV TICK,#20
INC SEC ;ADD SEC,#1
;MOV A,SEC
;CJNE A,#60,END_T0
;上面两条语句可以替换掉下面三条语句
MOV A,#60
XRL A,SEC ;将60与SEC中的内容进行异或,如果相同则A中的数据变为0
JNZ END_T0 ;如果未到达60秒则结束中断,否则清0SEC,并将一MIN加1
MOV SEC,#0 ;XRL SEC,SEC
INC MIN ;ADD MIN,#1
MOV A,#60
XRL A,MIN
JNZ END_T0
MOV MIN,#0 ;XRL MIN,MIN
INC HOUR ;ADD HOUR,#1
MOV A,#24
XRL A,HOUR
JNZ END_T0
MOV HOUR,#0 ;XRL HOUR,HOUR
END_T0:
RETI
DELAY:
PUSH PSW ;延时子程序,R0保存延时时间
PUSH Acc
LOOP_1:
MOV A,#255
LOOP_2:
DEC A
CJNE A,#0,LOOP_2
DJNZ R0,LOOP_1
POP Acc
POP PSW
RET
PRINT: ;显示时间子程序
PUSH PSW
PUSH Acc
PUSH B
PUSH DPH
PUSH DPL
MOV A,R0 ;因为不能直接PUSH R0,所以借助累加器A
PUSH Acc
;显示秒
MOV A,SEC
MOV B,#0AH
DIV AB
XCH A,B
MOV DPTR,#NUM ;表NUM中保存的是数字0~9的七段码
MOVC A,@A + DPTR ;MOV P1,@A + DPTR ;用基址加变址寻址获取对应数字的七段码,累加器A保存的是该数字
XCH A,P1 ;因为不能使用MOV P1,A所以借助XCH直接交换A和P1的内容
ORL P0,#3FH ;熄灭所有数码管
CPL P0.0 ;点亮秒的个位数码管
MOV R0,#2 ;延时两个单位
ACALL DELAY
MOV A,B
;MOV R0,#P1
MOVC A,@A + DPTR ;MOVC A,@A + DPTR
XCH A,P1 ;MOV P1,B
ORL P0,#3FH
CPL P0.1
MOV R0,#2
ACALL DELAY
;显示'分'
MOV A,MIN
MOV B,#0AH
DIV AB
XCH A,B
MOV DPTR,#NUM
MOVC A,@A + DPTR ;MOV P1,@A + DPTR
XCH A,P1
ORL P0,#3FH
CPL P0.2
CPL P1.7 ;点亮小数点与秒分开
MOV R0,#2
ACALL DELAY
MOV A,B
;MOV R0,#P1
MOVC A,@A + DPTR ;MOVC A,@A + DPTR
XCH A,P1 ;MOV P1,B
ORL P0,#3FH
CPL P0.3
MOV R0,#2
ACALL DELAY
;显示小时
MOV A,HOUR
MOV B,#0AH
DIV AB
XCH A,B
MOV DPTR,#NUM
MOVC A,@A + DPTR ;MOV P1,@A + DPTR
XCH A,P1
CPL P1.7 ;点亮小数点与分隔开
ORL P0,#3FH
CPL P0.4
MOV R0,#2
ACALL DELAY
MOV A,B
;MOV R0,#P1
MOVC A,@A + DPTR ;MOVC A,@A + DPTR
XCH A,P1 ;MOV P1,B
ORL P0,#3FH
CPL P0.5
MOV R0,#2
ACALL DELAY
POP Acc
XCH A,R0 ;MOV R0,A
POP DPL
POP DPH
POP B
POP Acc
POP PSW
RET
NUM: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;0C0H,0F9H,A4H,0B0H,99H,92H,82H,0F8H,80H,90H
;OFFSET_NUM: DB $ ; $ - #10 ;$ - #0 - #10
END
其他:给你做个最简单的吧;
LED EQU 30H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H ;T0工作模式1,16位定时器
MOV TH0,#3CH
MOV TL0,#0B0H ;50毫秒定时
SETB TR0
SETB ET0
SETB EA
MOV LED,#0FEH ;LED初值
SJMP $
T0ISR:
CLR TR0
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
MOV A,LED ;取当前LED
MOV P0,A ;点亮LED
RL A ;左移一位
MOV LED,A ;保存
RETI
END ;下面的程序最简单,功能也最强,已经通过了实验,符合题目的流水灯闪烁要求.
;------------------------------------------
ORG 0000H
LJMP START
ORG 000BH
MOV TH0, #4CH ;50ms@11.0592MHz
CPL F0
JNB F0, EXIT_T0 ;不到100ms就退出.
XRL P0, A ;每100ms,有一个LED亮/灭一次.
DJNZ R6, EXIT_T0
MOV R6, #20
RL A
EXIT_T0:
RETI
;------------------------------------------
START:
MOV TMOD, #01H ;T0定时方式1
MOV TH0, #4CH ;50ms@11.0592MHz
MOV IE, #82H ;开T0中断.
MOV R6, #20
MOV A, #1
SETB TR0
SJMP $
;------------------------------------------
END
电路图,在我的百度空间。
搜:
做而论道 51单片机闪烁流水灯
百度一下,即可找到。
上一个:求解答汇编问题
下一个:怎么用E语言做一个自动结束进程的软件,最好做个源码给我 进程我自己来就行了