全套資料在壓縮包里
;********************************
;單片機電子鐘匯編程序
;MCU:AT89C2051 晶振:12M
;編寫:舒新生 日期:2007.11.08
;手機:13073399262 QQ:625608148
;********************************
MIAO BIT P1.2;秒點位
HOU_S BIT P3.0 ;時十位
HOU_G BIT P3.1 ;時個位
MIN_S BIT P3.2 ;分十位
MIN_G BIT P3.3 ;分個位
H_KEY BIT P3.4 ;時調整鍵
M_KEY BIT P3.5 ;分調整鍵
SHAN BIT 0 ;秒點閃爍
LEDBUS EQU P1 ;顯示數據總線
SECOND EQU 30H ;秒寄存器
MINUTE EQU 31H ;分寄存器
HOUR EQU 32H ;時寄存器
TIM_1 EQU 33H ;定時器0中斷次數
TIM_2 EQU 34H ;定時器0中斷次數
;********************************
ORG 0000H ;程序開始
LJMP INIT
ORG 000BH ;定時器0中斷入口地址
LJMP TIMER0
ORG 0030H ;程序從30H開始
;********************************
; 單片機初始化
INIT: MOV SECOND, #0 ;秒置0
MOV MINUTE, #0 ;分置0
MOV HOUR, #0 ;開機后顯示0點
MOV TIM_1, #10 ;中斷10次為0.5秒
MOV TIM_2, #2 ;0.5*2=1秒
MOV SP, #60H ;堆棧指針指向60H
MOV TMOD, #01H ;定時器0為模式1(16位)
MOV TH0, #03CH
MOV TL0, #0B0H ;50毫秒初值(晶振12M)
SETB ET0 ;定時器0中斷允許
SETB TR0 ;啟動定時器0
SETB EA ;開總中斷
;********************************
; 主程序
MAIN: JNB H_KEY, HT ;時調整鍵按下轉到HT
JNB M_KEY, MT ;分調整鍵按下轉到MT
ACALL DISP ;調用顯示子程序
AJMP MAIN ;轉LOOP繼續檢測按鍵狀態
;********************************
; 時間調整
;----- 分調整 -----------------
MT: ACALL DISP ;調用顯示子程序
JNB M_KEY, MT ;判斷按鍵是否松開
INC MINUTE ;分加一
MOV A, MINUTE
CJNE A,#60, MAIN ;判斷分是否加到60
MOV MINUTE, #0 ;分到60變為0
MOV SECOND, #0 ;秒置0
AJMP MAIN
;----- 時調整 -----------------
HT: ACALL DISP ;調用顯示子程序
JNB H_KEY, HT ;判斷按鍵是否松開
INC HOUR ;時加1
MOV A, HOUR
CJNE A,#24, MAIN
MOV HOUR, #0 ;判斷時是否到24,時到24變0
AJMP MAIN
;********************************
; 顯示子程序
DISP: MOV DPTR, #LEDTAB ;數碼管段碼表首地址送DPTR
MOV A, MINUTE ;分放入ACC
MOV B, #10 ;B放入10
DIV AB ;A/B,商在A余數在B
MOVC A, @A+DPTR ;查表取分十位段碼
MOV LEDBUS, A ;段碼送LEDBUS口顯示
MOV C, SHAN
MOV MIAO, C ;秒點閃爍
CLR MIN_S ;打開分十位顯示
ACALL D1MS ;延時1毫秒
SETB MIN_S ;關閉分十位顯示
MOV A, B
MOVC A, @A+DPTR ;查表取分個位段碼
MOV LEDBUS, A
MOV C, SHAN
MOV MIAO, C ;秒點閃爍
CLR MIN_G ;打開分個位顯示
ACALL D1MS ;延時1毫秒
SETB MIN_G ;關閉分十位顯示
MOV A, HOUR
MOV B, #10
DIV AB ;拆分小時的十位和個位
JZ DISP0 ;十位為0不顯示十位
MOVC A, @A+DPTR
MOV LEDBUS, A
CLR HOU_S ;打開時十位顯示
DISP0: ACALL D1MS
SETB HOU_S ;關閉時十位顯示
MOV A, B
MOVC A, @A+DPTR
MOV LEDBUS, A
CLR HOU_G ;打開時個位顯示
ACALL D1MS
SETB HOU_G ;關閉時個位顯示
RET
;********************************
; 定時器0中斷服務程序
TIMER0: MOV A, #0B1H ;定時器0中斷服務子程序
ADD A, TL0 ;同步修正(參考本人的<如何是自制的單片機電子鐘走時精準>)
MOV TL0, A
MOV TH0, #03CH ;重裝定時器0初值
PUSH ACC ;入棧保護ACC和PSW
PUSH PSW
DJNZ TIM_1, RETI_1
MOV TIM_1, #10 ;中斷10次為0.5秒
CPL SHAN ;取反閃爍位
DJNZ TIM_2, RETI_1
MOV TIM_2, #2 ;1秒時間到
INC SECOND ;秒加1
MOV A, SECOND
CJNE A,#60, RETI_1
MOV SECOND, #0 ;秒到60變0
INC MINUTE ;分加1
MOV A, MINUTE
CJNE A,#60, RETI_1
MOV MINUTE, #0 ;分到60變0
INC HOUR ;時加1
MOV A, HOUR
CJNE A,#24, RETI_1
MOV HOUR, #0 ;時到24變0
RETI_1: POP PSW ;出棧
POP ACC
RETI
;********************************
; 延時子程序
D1MS: MOV R7, #2 ;延時1毫秒子程序
D_1: MOV R6, #250 ;延時時間估算250*2*2=1000微秒=1毫秒
DJNZ R6, $
DJNZ R7, D_1
RET
;********************************
; 數碼管段碼表
LEDTAB: DB 14H,0D7H,4CH,45H,87H
; 0 1 2 3 4
DB 25H,024H,57H,04H,05H
; 5 6 7 8 9
END