⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 up51s010.asm

📁 UP51C开发板所有源代码
💻 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 + -