?? up51s010.asm
字號:
;/*******************************************************************************
;* *
;* File : uP51s010.c *
;* Date : 2004-9-5 *
;* Version : 1.0 *
;* *
;* Author : kevin kevin@dz51.com *
;* Company : Http://www.dz51.com *
;* *
;********************************************************************************
;* Descriptoon: *
;* 計數器實驗 *
;* 定時器1工作于16位計數模式,記錄外部脈沖的個數; *
;* 定時器0工作于定時模式,用于進行動態掃描顯示 *
;* *
;* 此程序可用按鍵AN4來演示,但是由于按鍵有抖動現象,所以每按一次*
;* 有可能產生多次計數脈沖 *
;* *
;* 程序運行后按下AN4,則數碼管記數增加! *
;* *
;********************************************************************************
;* 計數值單位,寄存器與數碼管對應關系: *
;* *
;* --- 單位 ---------- 數碼管端口 ---- 緩沖區 --------- *
;* 千位 P23 DIS_BUF+3 *
;* 百位 P22 DIS_BUF+2 *
;* 十位 P21 DIS_BUF+1 *
;* 個位 P20 DIS_BUF+0 *
;* *
;********************************************************************************
NAME WL012
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA
RSEG DATA_SEG
DIS_DIGIT: DS 1
DIS_INDEX: DS 1
DIS_BUF: DS 4
TMP: DS 1
RSEG STACK_SEG
STACK: DS 20
;===============================================================================
CSEG AT 00000H
LJMP MAIN
CSEG AT 0000BH
LJMP TIMER0
;===============================================================================
RSEG CODE_SEG
MAIN:
MOV SP,#(STACK-1);
MOV P0,#0FFH
MOV P2,#0FFH
MOV TMOD,#051H ; 定時器0工作模式1, 16位定時方式
; 定時器1工作模式1, 16位計數方式
CLR A
MOV TH1,A
MOV TL1,A
MOV TH0,#0FCH
MOV TL0,#017H
; 初始化顯示緩沖區
MOV DIS_BUF+03H,#0C0H ; 0xc0是'0'的顯示代碼
MOV DIS_BUF+02H,#0C0H
MOV DIS_BUF+01H,#0C0H
MOV DIS_BUF,#0C0H
MOV DIS_DIGIT,#0FEH ; 初始顯示P20口數碼管
MOV DIS_INDEX,A
MOV IE,#082H ; 使能TIMER0中斷
SETB TR0
SETB TR1
SJMP $
; END OF MAIN
;===============================================================================
USING 1
TIMER0:
; 定時器0中斷服程序, 用于數碼管的動態掃描
; DIS_INDEX --- 顯示索引, 用于標識當前顯示的數碼管和緩沖區的偏移量
; DIS_DIGIT --- 位選通值, 傳送到P2口用于選通當前數碼管的數值, 如等于0xfe時,
; 選通P2.0口數碼管
; DIS_BUF --- 顯于緩沖區基地址
PUSH ACC
PUSH PSW
PUSH DPL
PUSH DPH
MOV PSW, #08H ; WORK 1
USING 1
MOV TH0,#0FCH
MOV TL0,#017H
MOV P2,#0FFH ; 先關閉所有數碼管
MOV A,#DIS_BUF ; 獲得顯示緩沖區基地址
ADD A,DIS_INDEX ; 獲得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 獲得顯示代碼
MOV P0,A ; 顯示代碼傳送到P0口
MOV P2,DIS_DIGIT ;
MOV A,DIS_DIGIT ; 位選通值右移, 下次中斷時選通下一位數碼管
RL A
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中斷時顯示下一位
ANL DIS_INDEX,#0x03 ; 當DIS_INDEX等于4(0000 0100)時, 清0
MOV A,DIS_INDEX
JNZ END_TIMER0
LCALL UPDATE_DISBUF
END_TIMER0:
POP DPH
POP DPL
POP PSW
POP ACC
RETI
; END OF timer0
;===============================================================================
UPDATE_DISBUF:
USING 1
MOV R7,TH1
MOV R6,TL1
LCALL BIN16BCD
MOV DPTR, #DIS_CODE
MOV A,R4
RR A
RR A
RR A
RR A
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF,A
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+1,A
MOV A,R3
RR A
RR A
RR A
RR A
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+2,A
MOV A,R3
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+3,A
RET
; END OF UPDATE_DISBUF
;===============================================================================
BIN16BCD:
; 將16位二進制數轉化為5位壓縮的BCD碼
; 傳入參數: R7:R6 --- 16位二進數; R7 --- MSB; R6 --- LSB
; 返回參數: R5:R4:R3 --- 5位壓縮的BCD碼; R5 --- MSB; R3 --- LSB
;
CLR A
MOV R3,A ;
MOV R4,A
MOV R5,A
MOV R0,#16 ; 共需左移16次
BIN16BCD_LP:
MOV A,R6 ; 將R6左移一位到R7
RLC A
MOV R6,A
MOV A,R7 ; 將R6的高位移入到R7
RLC A ; 將R7的高位移出到C
MOV R7,A
;-------------------------------
MOV A,R3 ; 將C移入到目標數(BCD)的最低位
ADDC A,R3 ; 這里用ADDC進行移位,而沒有使用RLC,
; 是為下面能正確的使用十進制調整指令DA
DA A ; 十進制調整
MOV R3,A ; 存回
MOV A,R4 ; 將R3的高位移入
ADDC A,R4 ;
DA A ; 十進制調整
MOV R4,A ; 存回
MOV A,R5 ; 將R4的高位移入
ADDC A,R5
DA A ; 十進制調整
MOV R5,A ; 存回
DJNZ R0,BIN16BCD_LP
RET
DIS_CODE:
DB 0C0H
DB 0F9H
DB 0A4H
DB 0B0H
DB 099H
DB 092H
DB 082H
DB 0F8H
DB 080H
DB 090H
DB 0FFH
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -