;********************************************************************************
;* *
;* File : wl012.asm *
;* Date : 2004-1-5 *
;* Version : 1.0 *
;* *
;* Author : Freeman myb33695@163.com *
;* Company : Willar http://shop35991384.taobao.com *
*
;* *
;********************************************************************************
;* Descriptoon: *
;* 计数器实验 *
;* 定时器1工作于16位计数模式,记录外部脉冲的个数; *
;* 定时器0工作于定时模式,用于进行动态扫描显示 *
;* *
;* 此程序可用按键AN4来演示,但是由于按键有抖动现象,所以每按一次*
;* 有可能产生多次计数脉冲 *
;* *
;********************************************************************************
;* 计数值单位,寄存器与数码管对应关系: *
;* *
;* --- 单位 ---------- 数码管端口 ---- 缓冲区 --------- *
;* X P20 DIS_BUF+7 *
;* X P21 DIS_BUF+6 *
;* X P22 DIS_BUF+5 *
;* 万位 P23 DIS_BUF+4 *
;* 千位 P24 DIS_BUF+3 *
;* 百位 P25 DIS_BUF+2 *
;* 十位 P26 DIS_BUF+1 *
;* 个位 P27 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 8
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+07H,#0FFH ; 最数小于65536, 所以前三个数码不显示
MOV DIS_BUF+06H,#0FFH
MOV DIS_BUF+05H,#0FFH
MOV DIS_BUF+04H,#0C0H ; 0xc0是'0'的显示代码
MOV DIS_BUF+03H,#0C0H
MOV DIS_BUF+02H,#0C0H
MOV DIS_BUF+01H,#0C0H
MOV DIS_BUF,#0C0H
MOV DIS_DIGIT,#07FH ; 初始显示P27口数码管
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 ; 位选通值右移, 下次中断时选通下一位数码管
RR A
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中断时显示下一位
ANL DIS_INDEX,#0x07 ; 当DIS_INDEX等于8(0000 1000)时, 清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,R5
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+4, A
MOV A,R4
RR A
RR A
RR A
RR A
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+3,A
MOV A,R4
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+2,A
MOV A,R3
RR A
RR A
RR A
RR A
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF+1,A
MOV A,R3
ANL A,#0FH
MOVC A,@A+DPTR
MOV DIS_BUF,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
* 专业无线总汇
QQ:1002421875 无线技术交流群(群号81069762(满)65332649)
MSN:yunjiakeji@hotmail.com Skype:yunjiakeji EMAIL:myb33695@163.com
PHONE:13430970167 http://shop35991384.taobao.com
文章评论(0条评论)
登录后参与讨论