;文件名稱:SZ03.ASM
;程序功能:帶定時鬧鈴及倒計時時鐘
;----------------------------------------------------------
;--------――― 時鐘程序部分 ---――――――――
;----- ――― 程序初始化 ――――――――――
; 定義存放計時單元地址
;....................
ALB EQU 20H.0 ;鬧鈴設置標誌
;....................
BUF EQU 30H ;30~33H 連續4字節存放顯示器數據
HOUR EQU 34H ;存放小時變量
MIN EQU 35H ;存放分鐘變量
SEC EQU 36H ;存放秒鐘變量
DEDA EQU 37H ;存放5 ms 計數值
;....................
HH EQU 38H ;鬧鈴設置小時變量
MM EQU 39H ;鬧鈴設置分鐘變量
;....................
;--------------------------------
SEC0 EQU 3AH ;存放舊的秒數
MM_D EQU 3BH ;倒數時間分鐘數
SS_D EQU 3CH ;倒數時間秒鐘數
;--------------------------------
;按鍵輸入引腳定義
K1 EQU P2.4 ;按鍵1引腳定義
K2 EQU P2.5 ;按鍵2引腳定義
K3 EQU P2.6 ;按鍵3引腳定義
K4 EQU P2.7 ;按鍵4引腳定義
;壓電喇叭和指示燈引腳定義
SPK EQU P3.4 ;壓電喇叭控制信號
WLED EQU P1.0 ;工作指示燈引腳定義
;程序開始執行地址
ORG 0H ;程序代碼由地址0開始執行
JMP MAIN
ORG 0BH ;定時器 0 中斷地址設置
JMP TO_SRV
;--------- 主 程 序 --------――
MAIN: ;開始
;...................
CLR ALB ;清除鬧鈴標誌
;...................
ACALL BZ ;壓電喇叭連續兩次鳴響壹聲
ACALL BZ
ACALL LED_BL ;LED 閃動,表示程序開始執行
ACALL INIT ;初始變化量
ACALL INIT_TIMER ;設置定時器
;加載顯示器初值數據
MOV A, #0C0H
MOV P0, A
;無窮循環
LOOP: ;無窮循環
ACALL CONV ;轉換 時時 分分 數據
;....................
ACALL TIME_PRO ;檢查鬧鈴時間
;....................
ACALL DISP ;掃描顯示
JB K1, M1 ;未按下K1鍵則繼續掃描
ACALL LED_BL ;LED閃動
ACALL SET_TIME ;設置目前時間
JMP LOOP ;繼續循環執行
;設置鬧鈴時間
M1:JB K2,M2 ;未按下K2鍵則繼續掃描
;.....................
ACALL LED_BL
ACALL SET_ATIME ;設置鬧鈴時間
;.....................
JMP LOOP ;繼續循環執行
;設置倒計時間
M2:JB K3, M3 ;未按下K3鍵則繼續掃描
;---------------------------------
ACALL LED_BL
ACALL DOWN_ATIME ;設置倒計時間
;--------------------------------
JMP LOOP ;繼續循環執行
M3:JB K4,M4 ;未按下K4鍵則繼續掃描
;...................
CPL ALB
JNB ALB,M31
;鬧鈴啟動連續3次發出響聲
ACALL BZ
ACALL BZ
ACALL BZ
;...................
JMP LOOP ;繼續循環執行
;....................
M31:
ACALL BZ ;鬧鈴停止,發出壹聲響
JMP LOOP ;繼續循環執行
;...................
M4:
JMP LOOP ;繼續循環執行
;----- 實現走時功能的子程序 ------――
;使用定時器0模式0計時
INIT_TIMER: ;初始化定時器,使用定時器0模式1計時
MOV TMOD,#00000000B ;設置定時器0工作模式為0
MOV IE, #10000010B ;啟用定時器0中斷產生
MOV TL0, #(8192-4900)MOD 32 ;加載低字節
MOV TH0, #(8192-4900)/32 ;加載高字節
SETB TR0 ;啟動定時器0開始計時
RET
;-----------―――
;中斷服務程序
TO_SRV: ;定時器0計時中斷程序每隔5ms中斷壹次
PUSH ACC ;將累加器放入堆棧
MOV TL0, #(8192-4900)MOD 32 ;加載低字節
MOV TH0, #(8192-4900)/32 ;加載高字節
INC DEDA ;5ms計數值加1
;秒輸出
MOV A, DEDA
CJNE A,#200,TT1 ;是否1s到了
MOV DEDA, #0 ;計數值清除為0
CPL WLED ;LED燈亮滅變換
INC SEC ;秒計數加1
MOV A, SEC
CJNE A, #60, TT1;是否1min到了
;分輸出
INC MIN ;分計數加1
MOV SEC, #0 ;秒計數清除為0
MOV A, MIN
CJNE A, #60, TT1 ;是否1h到了
;時輸出
INC HOUR ;小時計數加1
MOV MIN, #0 ;分計數清除為0
MOV A, HOUR
CJNE A,#24, TT1 ;是否24h到了
MOV SEC, #0 ;秒鐘變量清除為0
MOV MIN, #0 ;分鐘變量清除為0
MOV HOUR, #0 ;小時變量清除為0
TT1:
POP ACC ;將累加器由堆棧取出
RETI
;----―― 實現顯示功能的子程序 ---――――
;轉換 時時:分分 數據
CONV:
;轉換小時數據
MOV A, HOUR
MOV B, #10
DIV AB
MOV DPTR,#TABLE ;查表轉換
MOVC A, @A+DPTR
MOV BUF, A
MOV A, B
MOVC A, @A+DPTR
MOV BUF+1, A
;轉換分鐘數據
MOV A, MIN
MOV B, #10
DIV AB
MOV DPTR,#TABLE ;查表轉換
MOVC A, @A+DPTR
MOV BUF+2, A
MOV A, B
MOVC A, @A+DPTR
MOV BUF+3, A
RET
;字型數據編碼表
TABLE:
DB 0C0H,0F9H,0A4H,0B0H
DB 99H,92H,82H,0F8H
DB 80H,90H,88H,83H
DB 0C6H,0A1H,86H,8EH
;---------――――
;掃描顯示
DISP:
MOV R0, #BUF ;指向顯示器顯示緩沖區起始地址
MOV R2, #4 ;循環執行4次
MOV ACC, #11110111b;加載掃描信號初值11110111B
S1:
PUSH ACC
MOV A, @R0 ;取出顯示器數據
MOV P0, A ;由P0送出壹位顯示器數據
POP ACC
MOV P2, ACC ;由P2送出掃描輸出信號
MOV R5, #2 ;延遲壹會兒
ACALL DELAY
;改變掃描碼 EX:XXXX1011
RR A ;累加器向右移動壹位
INC R0 ;顯示器顯示緩沖區地址加1
DJNZ R2, S1 ;循環判斷是否繼續執行
RET
;---―― 實現調整時間子程序 ――――――
;設置目前時間
SET_TIME:
CLR TR0 ;定時器動作暫停
MOV SEC, #0 ;秒鐘變量清除為0
L0:
ACALL DISP ;掃描顯示
JB K2, L1 ;未按下K2鍵則繼續掃描
JNB K2, $ ;有按下則等待放開來
;K2小時調整
INC HOUR ;小時計數加1
MOV A, HOUR
CJNE A,#24, L11 ;是否24H到了
MOV HOUR, #0 ;小時變量清除為0
L11:
ACALL CONV ;轉換顯示數據
ACALL DISP ;掃描顯示
JMP L0 ;繼續程序執行
L1:JB K3, L2 ;未按下K3鍵則繼續掃描
JNB K3,$ ;有按下則等待放開來
;K3分鐘調整.
INC MIN ;分鐘計數加1
MOV A, MIN
CJNE A,#60, L21 ;是否60 min到了
MOV MIN, #0 ;分鐘變量清除為0
L21:
ACALL CONV ;轉換顯示數據
ACALL DISP ;掃描顯示
JMP L0 ;繼續程序執行
L2: JB K4,L0 ;未按下K4鍵則繼續掃描
JNB K4, $ ;有按下則等待放開來
ACALL BZ ;壓電喇叭鳴響壹聲
;K4設置完成
ACALL LED_BL ;LED閃動
SETB TR0 ;啟動定時器
RET
;----―喇叭和指示燈等其它子程序 ----――
;計時單元清零
INIT:
MOV DEDA, #0 ;5ms計數值清除為0
MOV SEC, #0 ;秒鐘變量清除為0
MOV MIN, #0 ;分鐘變量清除為0
MOV HOUR, #0 ;小時變量清除為0
RET
;―――――――――――――
;壓電喇叭
BZ: ;壓電喇叭鳴響壹聲
MOV R6, #250
B1: ACALL DEX
CPL SPK
DJNZ R6,B1
MOV R5, #50 ;#10
ACALL DELAY
RET
;----------―――
;工作指示
LED_BL: ;工作指示燈閃爍
MOV R4,#6
LE1:CPL WLED ;位反向
MOV R5,#25 ;#5
ACALL DELAY
DJNZ R4, LE1 ;延遲50ms
RET
;----------―――
;延時子程序
DELAY: ;;總延遲時間 R5* 2ms
MOV R6,#10 ;#50
D1:MOV R7,#100
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,DELAY
RET
;----------―――
; 壓電喇叭短暫延時子程序
DEX: MOV R7,#180 ;短暫延時
DE1: NOP
DJNZ R7, DE1
RET
;-------―― 增加定時鬧鈴程序部分 -------――
;―――――――― 設置鬧鈴時間 ―――――――――
;設置鬧鈴時間
SET_ATIME:
ACALL CONVA ;加載鬧鈴時間數據
N0:
ACALL DISP
;-----------
JB K2, N1 ;未按下K2鍵則繼續掃描
JNB K2, $ ;有按下則等待放開來
;K2調整小時
INC HH ;小時數加1
MOV A, HH
CJNE A, #24,N11 ;是否24h到了
MOV HH,#0 ;小時請為0
N11:
ACALL CONVA ;加載鬧鈴時間數據
ACALL DISP ;掃描顯示
JMP N0 ;繼續按鍵掃描
;------------
N1: JB K3, N2 ;未按下K3鍵則繼續掃描
JNB K3, $ ;有按下則等待放開來
;K3調整分鐘
INC MM ;調整分鐘數
MOV A,MM ;分鐘數加1
CJNE A, #60,N21 ;是否60min到了
MOV MM, #0 ;分鐘數請為0
N21:
ACALL CONVA ;加載鬧鈴時間數據
ACALL DISP ;掃描顯示
JMP N0 ;繼續按鍵掃描
;------------
N2: JB K4, N0 ;未按下K4鍵則繼續掃描
JNB K4, $ ;等K4鍵放開
;K4設置完成......
ACALL LED_BL ;LED閃動
ACALL CONV ;加載現在時間數據
RET
;―――――――― 加載鬧鈴時間數據 ―――――――
;轉換 時時:分分 數據
CONVA:
;轉換小時數據
MOV A, HH
MOV B, #10
DIV AB
;-----------
MOV DPTR,#TABLE ;查表轉換
MOVC A, @A+DPTR
MOV BUF, A
;-----------
MOV A, B
MOVC A, @A+DPTR
MOV BUF+1, A
;轉換分鐘數據
MOV A, MM
MOV B, #10
DIV AB
;-----------
MOV DPTR,#TABLE ;查表轉換
MOVC A, @A+DPTR
MOV BUF+2, A
;-----------
MOV A, B
MOVC A, @A+DPTR
MOV BUF+3, A
RET
;―――――――― 檢查鬧鈴時間處理 ――――――――
;檢查是否啟動鬧鈴
TIME_PRO:
JB ALB, TI3
RET
;――――――――――――――
;檢查鬧鈴時間是否到了
TI3:
MOV A, HOUR
MOV B,HH
CJNE A, B, BK ;檢查鬧鈴小時時間
;-----------
MOV A, MIN
MOV B,MM
CJNE A, B, BK ;檢查鬧鈴分鐘時間
;-----------
ACALL TIME_OUT ;執行檢查鬧鈴時間到了處理
BK:
RET
;-------- 執行鬧鈴時間處理 ――――――――
TIME_OUT: ;所設置的鬧鈴數據到了
X1: ACALL LED_BL ;LED閃動
ACALL BZ ;壓電喇叭發出嘩的壹聲
;按下K4鍵停止鬧鈴
JB K4, X1 ;等待是否按下K4鍵
JNB K4,$ ;若有按下鍵則等待按鍵放開來
ACALL LED_BL ;LED閃動
CLR ALB ;清除鬧鈴位
RET
;************************ 增加倒計時程序部分 *********************
;---------- 設置倒數時間 ----------
;設置倒數時間
DOWN_ATIME:
CLR TR0 ;定時器動作暫停
MOV SS_D, #1 ;秒鐘變量為1
S0:
ACALL DISP ;掃描顯示
;-----------
;按K2分鐘數增加
JB K2, S12 ;未按下K2繼續掃描
JNB K2, $ ;有按下則等待放開來
INC MM_D ;分鐘數加1
MOV A, MM_D
CJNE A, #60,S11 ;是否60min到了
MOV MM_D,#0 ;分鐘變量請除為0
S11:
ACALL DOWN_CONV ;顯示倒數的時間
ACALL DISP ;掃描顯示
JMP S0 ;繼續對按鍵掃描
;------------
;按K3分鐘數減少
S12: JB K3, S2 ;未按下K3繼續掃描
JNB K3, $ ;有按下則等待放開來
DEC MM_D ;分鐘數減少1
MOV A,MM_D
CJNE A, #0,S21 ;是否為0?
MOV MM_D, #60 ;分鐘數賦值為60
S21:
ACALL DOWN_CONV ;加載倒數時間數據
ACALL DISP ;掃描顯示
JMP S0 ;循環執行
;------------
S2: JB K4, S0 ;未按下K4繼續掃描
JNB K4, $ ;等K4鍵放開
;K4設置完成......
ACALL BZ ;響4聲
ACALL BZ
ACALL BZ
ACALL BZ
ACALL LED_BL ;LED閃動
SETB TR0 ;啟動定時器
S3:
ACALL DOWN_TIME ;檢查倒計時
ACALL DOWN_CONV ;加載倒數時間數據
ACALL DISP ;掃描顯示
JMP S3
RET
;---------------- 加載倒計時時間 -----------------------
;顯示倒數的分鐘數
DOWN_CONV:
MOV A, MM_D
MOV B,#10 ;設置被除數
DIV AB ;除法運算,結果A存商數,B存余數
MOV DPTR,#TABLE ;查表轉換
MOVC A, @A+DPTR
MOV BUF+2, A ;商數存入BUF+2
MOV A, B ;余數暫存入A
MOVC A, @A+DPTR ;查表轉換
MOV BUF+3, A ;余數存入BUF+3
RET
;---------- 檢查倒計時 ------------
;檢查倒計時
DOWN_TIME: ;檢查是否倒數終止
MOV A,SEC ;加載現在秒數
MOV B,SEC0 ;載入舊秒數
CJNE A,B,D01 ;是否過了1秒
RET
;-----------------------------------
D01:
MOV SEC0,SEC ;記錄舊的秒數
DEC SS_D ;秒數減1
MOV A,SS_D
CJNE A,#0, D11 ;秒鐘數是否為0
MOV A,MM_D
CJNE A,#0,D12 ;分鐘數是否為0
;秒鐘數=0 且 分鐘數=0 則倒數終止
ACALL TIME_OUT ;倒數終了處理程序
JMP LOOP
RET
;-----------
D12:
MOV SS_D,#59 ;秒鐘數=59
DEC MM_D ;分鐘數減1
D11:
ACALL DOWN_CONV ;顯示倒計時時間
RET
;------------------------------
END