?? xlmb.asm
字號:
;/*******************************************************************************
;* 標題: xl系列單片機實驗儀演示程序 數(shù)碼管秒表計時 *
;* 文件: XLmb.asm *
;* 日期: 2006-1-5 *
;* 版本: 3.0 (試驗通過版)可用xl600-xl1000單片機綜合試驗儀試驗 *
;* 郵箱: sxj1974@163.com *
;* 網站: http://www.51c51.com www.8951.com *
;********************************************************************************
;* 描述: *
;* 數(shù)碼管顯示秒表, 分辨率0.01s *
;* K1---控制按鈕 *
;* 第一次按下時, 啟動開始計時 *
;* 第二次按下時, 停止 *
;* 第三次按下時, 歸零 *
;* 引用資源:數(shù)碼管數(shù)據 p0口,數(shù)碼管控制p2口 控制按鈕 p3.2口 *
;* 秒單位,寄存器與數(shù)碼管對應關系: *
;* *
;* --- 秒單位 ---------- 數(shù)碼管端口 ---- 緩沖區(qū) --------- 計時BCD碼值寄存器 *
;* 十萬位 P20 dis_buf[7] sec_bcd[7] *
;* 萬位 P21 dis_buf[6] sec_bcd[6] *
;* 千位 P22 dis_buf[5] sec_bcd[5] *
;* 百位 P23 dis_buf[4] sec_bcd[4] *
;* 十位 P24 dis_buf[3] sec_bcd[3] *
;* 個位(1.s) P25 dis_buf[2] sec_bcd[2] *
;* 十分位(0.1s) P26 dis_buf[1] sec_bcd[1] *
;* 百分位(0.01s) P27 dis_buf[0] sec_bcd[0] *
;* *
;********************************************************************************
;* 【版權】 Copyright(C)深圳市學林電子有限公司 www.51c51.com *
;* 【聲明】 此程序僅用于學習與參考,引用請注明版權和作者信息! *
;* 【技術支持】請訪問http://www.51c51.com/bbs/index.asp 官方論壇 *
;********************************************************************************/
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA
RSEG DATA_SEG
KEY_S: DS 1
KEY_V: DS 1
DIS_DIGIT: DS 1
DIS_INDEX: DS 1
SEC_BCD: DS 8 ; 秒計數(shù)值, BCD碼
KEY_TIMES: DS 1 ; K1 按下次數(shù)
DIS_BUF: DS 8 ; 顯示緩沖區(qū)
RSEG STACK_SEG
STACK: DS 20
K1 BIT P3.2
;===============================================================================
CSEG AT 0000H
LJMP MAIN
CSEG AT 0000BH
LJMP TIMER0
CSEG AT 0001BH
LJMP TIMER1
;===============================================================================
RSEG CODE_SEG
MAIN:
USING 0
MOV SP,#(STACK-1)
MOV P0,#0FFH ; 初始化端口
MOV P2,#0FFH
MOV TMOD,#011H ;
MOV TH1,#0DCH
CLR A
MOV TL1,A
MOV TH0,#0FCH
MOV TL0,#017H
LCALL CLR_TIME ; 清零計時值
MOV DIS_DIGIT,#07FH ; 上電時選通P27數(shù)碼管
CLR A
MOV DIS_INDEX,A
MOV KEY_TIMES,A
MOV KEY_V,#01H
MOV IE,#08AH ; 使能timer0, timer1中斷
SETB TR0
CLR TR1
MAIN_LP:
LCALL SCAN_KEY ; 鍵掃描
JZ MAIN_LP ; 無鍵返回
MOV R7,#10 ; 延時10ms
LCALL DELAYMS ; 延時去抖動
LCALL SCAN_KEY ; 再次掃描
JZ MAIN_LP ; 無鍵返回
MOV KEY_V,KEY_S ; 保存鍵值
LCALL PROC_KEY ; 鍵處理
SJMP MAIN_LP ; 調回主循環(huán)
;===============================================================================
CLR_TIME:
CLR A
MOV SEC_BCD,A ; 清零所有計時值
MOV SEC_BCD+01H,A
MOV SEC_BCD+02H,A
MOV SEC_BCD+03H,A
MOV SEC_BCD+04H,A
MOV SEC_BCD+05H,A
MOV SEC_BCD+06H,A
MOV SEC_BCD+07H,A
LJMP UPDATE_DISBUF ; 更新顯示緩沖區(qū)
;===============================================================================
SCAN_KEY:
CLR A
MOV KEY_S,A
MOV C,K1 ; 讀按鍵狀態(tài)
RLC A
ORL KEY_S,A
MOV A,KEY_S
XRL A,KEY_V ;
RET
;===============================================================================
PROC_KEY:
MOV A,KEY_V
JB ACC.0,END_PROC_KEY
INC KEY_TIMES
MOV A,KEY_TIMES
CJNE A,#01H,PROC_KEY1
SETB TR1 ; KEY_TIMES = 1,第一次按下K1, 啟動開始計時
RET
PROC_KEY1:
MOV A,KEY_TIMES
CJNE A,#02H,PROC_KEY2
CLR TR1 ; KEY_TIMES = 2, 第二次按下K1, 停止計時
RET
PROC_KEY2:
LCALL CLR_TIME ; 第三次按下K1, 清零計時值
CLR A
MOV KEY_TIMES,A ; 清零KEY_TIMES
END_PROC_KEY:
RET
;===============================================================================
TIMER0:
; 定時器0中斷服程序, 用于數(shù)碼管的動態(tài)掃描
; DIS_INDEX --- 顯示索引, 用于標識當前顯示的數(shù)碼管和緩沖區(qū)的偏移量
; DIS_DIGIT --- 位選通值, 傳送到P2口用于選通當前數(shù)碼管的數(shù)值, 如等于0xfe時,
; 選通P2.0口數(shù)碼管
; DIS_BUF --- 顯于緩沖區(qū)基地址
PUSH ACC
PUSH PSW
PUSH AR0
MOV TH0,#0FCH
MOV TL0,#017H
MOV P2,#0FFH ; 先關閉所有數(shù)碼管
MOV A,#DIS_BUF ; 獲得顯示緩沖區(qū)基地址
ADD A,DIS_INDEX ; 獲得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 獲得顯示代碼
MOV P0,A ; 顯示代碼傳送到P0口
MOV P2,DIS_DIGIT ;
MOV A,DIS_DIGIT ; 位選通值右移(P20<-P27), 下次中斷時選通下一位數(shù)碼管
RR A
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中斷時顯示下一位
ANL DIS_INDEX,#0x07 ; 當DIS_INDEX等于8(0000 1000)時, 清0
POP AR0
POP PSW
POP ACC
RETI
;===============================================================================
TIMER1:
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
PUSH AR7
ORL TH1,#0DCH ; 恢復定時器初值
CLR A
MOV R7,A
MOV A,#LOW (SEC_BCD)
MOV R0,A ; 計時值寄存器地址到R0
TIMER_INC: ;
INC @R0 ; 計時值加1
MOV A,@R0
CLR C
SUBB A,#10 ;
JC END_INC ; 如果低位不滿10, 則結束
MOV @R0,#00H ; 低位滿10, 清零低位
INC R0 ; 指向高位
INC R7 ;
CJNE R7,#08H,TIMER_INC ; 如果達到最高位, 則結束
END_INC:
LCALL UPDATE_DISBUF
POP AR7
POP PSW
POP DPL
POP DPH
POP B
POP ACC
RETI
;===============================================================================
UPDATE_DISBUF:
; 根據計時寄存器的值更新顯示緩沖區(qū)
MOV DPTR,#DIS_CODE ; 保存表格地址
MOV A,sec_bcd
MOV DPTR,#dis_code
MOVC A,@A+DPTR ; 獲得顯示代碼
MOV dis_buf,A ; 更新顯示緩沖區(qū)
MOV A,sec_bcd+01H
MOVC A,@A+DPTR
MOV dis_buf+01H,A
MOV A,sec_bcd+02H
MOVC A,@A+DPTR
ANL A,#07FH ; 顯示小數(shù)點
MOV dis_buf+02H,A
MOV A,sec_bcd+03H
MOVC A,@A+DPTR
MOV dis_buf+03H,A
MOV A,sec_bcd+04H
MOVC A,@A+DPTR
MOV dis_buf+04H,A
MOV A,sec_bcd+05H
MOVC A,@A+DPTR
MOV dis_buf+05H,A
MOV A,sec_bcd+06H
MOVC A,@A+DPTR
MOV dis_buf+06H,A
MOV A,sec_bcd+07H
MOVC A,@A+DPTR
MOV dis_buf+07H,A
RET
; END OF UPDATE_DISBUF
;===============================================================================
DELAYMS:
; 延時子程序
; 傳入參數(shù):R7 --- 延時值(MS)
; 返回值:無
MOV A,R7
JZ END_DLYMS
DLY_LP1:
MOV R6,#185
DLY_LP2:
NOP
NOP
NOP
DJNZ R6,DLY_LP2
DJNZ R7,DLY_LP1
END_DLYMS:
RET
;===============================================================================
DIS_CODE:
db 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h,0ffh
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -