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

📄 新建 文本文档.asm

📁 这是基于富晶单片机FS9821平台的有关电子秤的开发源程序。其中有AD判稳和温度自动补偿的子程序
💻 ASM
📖 第 1 页 / 共 5 页
字号:
            		MOVFW   R_CaliP2H       ;D3:D0=P2.2 自动关机时间,0=无自动关机, 
            		ANDLW   0FH             ;1-7对应30秒-210秒,8=10秒,9=300秒后自动关机 
           		MOVWF   R_Temp          ;P2.2->R_Temp 
            		BTFSS   STATUS,Z 
            		GOTO    L_CalcOffTime1  ;P2.2>0 转 
            		BSF     R_OffTimerH,7   ;P2.2=0(无自动关机),1->R_OffTimerH.7 
            		GOTO    L_CalcOffTimeRet 
L_CalcOffTime1: 
            		CLRF    R_OffTimerH,7   ;P2.2>0,0->R_OffTimerH 
            		MOVFW   R_WorkStatus 
            		ANDLW   70H 
            		SUBLW   30H 
            		BTFSS   STATUS,Z 
            		GOTO    L_CalcOffTime2  ;[R_WorkStatus].6:4≠3(不在标定期间) 转 
            		BSF     R_OffTimerH,0   ;[R_WorkStatus].6:4=3(标定期间) 1->R_OffTimerH.0 
            		GOTO    L_CalcOffTimeRet 
L_CalcOffTime2: 
            		DECF    R_Temp,0 
            		CALL    S_RdOffTime     ;读出自动关机时间 
            		MOVWF   R_OffTimerL     ;\ 
            		ADDWF   R_OffTimerL,1   ; | 读出的自动关机时间×2 
            		MOVLW   0               ; | ->R_OffTimerH:R_OffTimerL 
            		ADDWFC  R_OffTimerH,1   ;/ 
L_CalcOffTimeRet: 
			RETURN 
S_RdOffTime:                ;读出自动关机时间 
			ADDPCW 
			RETLW	15      ;P2.2=1 自动关机时间为30秒 
			RETLW	30      ;P2.2=2 自动关机时间为60秒 
			RETLW	45      ;P2.2=3 自动关机时间为90秒 
			RETLW	60      ;P2.2=4 自动关机时间为120秒 
			RETLW	75      ;P2.2=5 自动关机时间为150秒 
			RETLW	90      ;P2.2=6 自动关机时间为180秒 
			RETLW	105     ;P2.2=7 自动关机时间为210秒 
			RETLW	5       ;P2.2=8 自动关机时间为10秒 
			RETLW	150     ;P2.2=9 自动关机时间为300秒 
;------------------------------------------------------------------------------ 
;子程序S_DecOffTime ;自动关机时间(单位:秒)-1->R_OffTimerH:R_OffTimerL,若已减到0则准备关机 
;Input:     R_OffTimerH:R_OffTimerL 
;Output:    R_OffTimerH:R_OffTimerL 
;           R_WorkStatus 
;Use RAM:   WORK 
;==============================================================================
S_DecOffTime: 
           		BTFSC   R_OffTimerH,7 
            		GOTO    L_DecOffTimeRet ;[R_OffTimerH].7=1(不自动关机) 转 
            		MOVFW   R_OffTimerH 
            		IORWF   R_OffTimerL,0 
            		BTFSC   STATUS,Z 
            		GOTO    L_DecOffTimeOver ;[R_OffTimerH:R_OffTimerL]=0 转,准备关机 
            		MOVLW   1               ;\ 
            		SUBWF   R_OffTimerL,1   ; | [R_OffTimerH:R_OffTimerL]-1 
            		MOVLW   0               ; | ->R_OffTimerH:R_OffTimerL 
            		SUBWFC  R_OffTimerH,1   ;/ 
            		GOTO    L_DecOffTimeRet 
L_DecOffTimeOver: 
            		MOVLW   40H 
            		MOVWF   R_WorkStatus    ;40H->R_WorkStatus 准备关机 
L_DecOffTimeRet: 
			RETURN 
;------------------------------------------------------------------------------ 
;子程序S_CaliCodeProc	;[R_PubCnt1].7:4=0 处理重量标定数据 
;Input:		R_CaliMarkH:R_CaliMarkL 
;			R_CaliCode0H:R_CaliCode0L 
;			R_SteadyCodeH:R_SteadyCodeL 
;Output:	R_CaliDataH:R_CaliDataL 
;Call:		S_AddSub1,S_Mul2Sub1 
;			S_CalcABS 
;			S_Divis 
;Use RAM:	WORK,R_Count,R_PubCnt0 
;			R_PubReg1:R_PubReg0,R_PubReg3:R_PubReg2,R_PubReg5:R_PubReg4 
;================================================================================
S_CaliCodeProc: 
			MOVFW	R_CaliMarkL		;\ 
			MOVWF	R_PubReg0		; | [R_CaliMarkH:R_CaliMarkL] 
			MOVFW	R_CaliMarkH		; | ->R_PubReg1:R_PubReg0 
			MOVWF	R_PubReg1		;/ 
S_CaliCodeComm:			;标定时计算每个内码相当于重量的分度数×65536->R_CaliDataH:R_CaliDataL 
			MOVFW	R_PubReg1 
			ANDLW	0FFH 
			BTFSC	STATUS,Z 
			GOTO	L__CaliCodeP_Ret ;[R_PubReg1]=0(标定分度值<1000) 转,返回 
;下面的程序将4位BCD码[R_PubReg1:R_PubReg0]转换为二进制数->R_PubReg3:R_PubReg2 
			CLRF	R_PubReg2		;0->R_PubReg2 
			CLRF	R_PubReg3		;0->R_PubReg3 
			MOVLW	4 
			MOVWF	R_PubCnt0		;4->R_PubCnt0 
L_BCD2HexLoop: 
			CLRF	R_PubReg4		;0->R_PubReg4 
			CLRF	R_PubReg5		;0->R_PubReg5 
			MOVLW	4 
			MOVWF	R_Count			;4->R_Count 
L_BCD2HexL_1: 
			RLF	R_PubReg0,1 
			RLF	R_PubReg1,1 
			RLF	R_PubReg4,1 
			DECFSZ	R_Count,1 
			GOTO	L_BCD2HexL_1 
; 
			CALL	S_AddSub1	;[R_PubReg3:R_PubReg2]+[R_PubReg5:R_PubReg4]->R_PubReg3:R_PubReg2 
			CALL	S_Mul2Sub1	;[R_PubReg3:R_PubReg2]×2->R_PubReg3:R_PubReg2 
			MOVFW	R_PubReg2		;\ 
			MOVWF	R_PubReg4		; | [R_PubReg3:R_PubReg2] 
			MOVFW	R_PubReg3		; | ->R_PubReg5:R_PubReg4 
			MOVWF	R_PubReg5		;/ 
			CALL	S_Mul2Sub1	;[R_PubReg3:R_PubReg2]×2->R_PubReg3:R_PubReg2 
			CALL	S_Mul2Sub1	;[R_PubReg3:R_PubReg2]×2->R_PubReg3:R_PubReg2 
			CALL	S_AddSub1	;[R_PubReg3:R_PubReg2]+[R_PubReg5:R_PubReg4]->R_PubReg3:R_PubReg2 
;								以上17行相当于[R_PubReg3:R_PubReg2]×10 
L_BCD2Hex_Next:			 
			DECFSZ	R_PubCnt0,1 
			GOTO	L_BCD2HexLoop 
;上面的程序将4位BCD码[R_PubReg1:R_PubReg0]转换为二进制数->R_PubReg3:R_PubReg2 
			MOVFW	R_CaliCode0L	;\ 
			MOVWF	R_PubReg0	; | [R_CaliCode0H:R_CaliCode0L] 
			MOVFW	R_CaliCode0H	; | ->R_PubReg1:R_PubReg0 
			MOVWF	R_PubReg1	;/ 
			MOVFW	R_SteadyCodeL	;\ 
			MOVWF	R_PubReg4	; | [R_SteadyCodeH:R_SteadyCodeL] 
			MOVFW	R_SteadyCodeH	; | ->R_PubReg5:R_PubReg4 
			MOVWF	R_PubReg5	;/ 
			CALL	S_CalcABS		;计算[R_PubReg5:R_PubReg4]-[R_PubReg1:R_PubReg0]绝对值->R_PubReg5:R_PubReg4 
			MOVFW	R_PubReg4 
			SUBWF	R_PubReg2,0 
			MOVFW	R_PubReg5 
			SUBWFC	R_PubReg3,0 
			BTFSC	STATUS,C 
			GOTO	L__CaliCodeP_Ret ;[R_PubReg3:R_PubReg2]≥[R_PubReg5:R_PubReg4] 转,返回 
			CALL    S_Divis	;[R_PubReg3:R_PubReg2]×65536÷[R_PubReg5:R_PubReg4]->R_PubReg1:R_PubReg0 
			BTFSC	R_PubReg1,7 
			GOTO	L__CaliCodeP_Ret ;[R_PubReg1]≥80H(每个内码对应的重量≥0.5d) 转,返回 
			MOVFW	R_PubReg0		;\ 
			MOVWF	R_CaliDataL		; | [R_PubReg1:R_PubReg0] 
			MOVFW	R_PubReg1		; | ->R_CaliDataH:R_CaliDataL 
			MOVWF	R_CaliDataH		;/ 
			MOVLW	D_CaliMark2 
			MOVWF	R_CaliCodeFlag	;D_CaliMark2->R_CaliCodeFlag 重量标定成功 
L__CaliCodeP_Ret: 
			RETURN 

;子程序S_AddSub1	;[R_PubReg3:R_PubReg2]+[R_PubReg5:R_PubReg4]->R_PubReg3:R_PubReg2 
S_AddSub1: 
			MOVFW	R_PubReg4		;\ 
			ADDWF	R_PubReg2,1		; | [R_PubReg3:R_PubReg2]+[R_PubReg5:R_PubReg4] 
			MOVFW	R_PubReg5		; | ->R_PubReg3:R_PubReg2 
			ADDWFC	R_PubReg3,1		;/  
			RETURN 
;子程序S_Mul2Sub1	;[R_PubReg3:R_PubReg2]×2->R_PubReg3:R_PubReg2 
S_Mul2Sub1: 
			BCF	STATUS,C		;\ 
			RLF	R_PubReg2,1		; | [R_PubReg3:R_PubReg2]×2->R_PubReg3:R_PubReg2 
			RLF	R_PubReg3,1		;/ 
			RETURN 
;------------------------------------------------------------------------------ 
;子程序S_RdParaMaxV	;读出当前参数的最大值 
S_RdParaMaxV: 
			ADDPCW 
			RETLW	99H		;P0.1、P0.0的最大值 
			RETLW	29H		;P0.3、P0.2的最大值 
			RETLW	7FH		;P1.1、P1.0的最大值 
			RETLW	93H		;P1.3、P1.2的最大值 
			RETLW	97H		;P2.1、P2.0的最大值 
			RETLW	39H		;P2.3、P2.2的最大值 
;------------------------------------------------------------------------------ 
;子程序S_RR4Work		;[WORK]右移4位->WORK,0->WORK.7:4 
S_RR4Work:	
			RRF	WORK,0 
			RRF	WORK,0 
			RRF	WORK,0 
			RRF	WORK,0 
			ANDLW	0FH 
			RETURN 
;------------------------------------------------------------------------------ 
;子程序S_ReadKey		;读按键,并作简单判断处理 
;Output:	R_KeyStatus,R_KeyCode 
;Call:		S_RdKeyCode 
;Use RAM:	WORK,R_PubCnt2,R_PubCnt3 
;==============================================================================
S_ReadKey:	
			MOVFW	PT2 
			XORLW	07H 
			ANDLW	07H 
			MOVWF	R_PubCnt2		;PT.2:0取反->R_PubCnt2.2:0,R_PubCnt2:7:3=00000B 
			BTFSS	STATUS,Z 
			GOTO	L_ReadKey2		;[R_PubCnt2]≠0(有键按下) 转 
			BCF	R_PubFlag1,0	;0->R_PubFlag1.0 
			MOVFW	R_KeyStatus 
			ANDLW	0F0H 
			BTFSS	STATUS,Z 
			GOTO	L_ReadKey1		;[R_KeyStatus].7:4≠0 转 
			BSF	R_KeyCode,3		;1->R_KeyCode.3 (按键释放) 
			BSF	R_KeyStatus,7	;1->R_KeyStatus.7 
			BSF	R_KeyStatus,4	;1->R_KeyStatus.4 
			GOTO	L_ReadKeyRet 
L_ReadKey1:	 
			MOVLW	1FH 
			ANDWF	R_KeyStatus,1	;0->R_KeyStatus.7:5 
			BSF	R_KeyStatus,4	;1->R_KeyStatus.4 
			GOTO	L_ReadKeyRet 
L_ReadKey2: 
			MOVFW	R_KeyStatus 
			ANDLW	0F0H 
			XORLW	70H 
			BTFSC	STATUS,Z 
			GOTO	L_ReadKeyRet	;[R_KeyStatus].7:4=7 转 
			DECF	R_PubCnt2,0 
			CALL	S_RdKeyCode		;读键码 
			MOVWF	R_PubCnt3		;键码->R_PubCnt3 
			BTFSC	R_KeyStatus,4 
			GOTO	L_ReadKey3		;[R_KeyStatus].4=1 转 
			MOVFW	R_KeyStatus 
			ANDLW	0FH 
			XORWF	R_PubCnt2,0 
			BTFSC	STATUS,Z 
			GOTO	L_ReadKey4		;[R_PubCnt2]=[R_KeyStatus].3:0 (按键状态未变) 转 
L_ReadKey3: 
			MOVLW	0F0H 
			ANDWF	R_KeyStatus,0 
			IORWF	R_PubCnt2,0 
			MOVWF	R_KeyStatus		;[R_PubCnt2]->[R_KeyStatus].3:0 保存按键状态 
			MOVFW	R_PubCnt3 
			MOVWF	R_KeyCode		;[R_PubCnt3]->R_KeyCode 保存键码 
			MOVFW	R_KeyStatus 
			ANDLW	0F0H 
			XORLW	30H 
			BTFSS	STATUS,Z 
			BSF	R_KeyStatus,7	;[R_KeyStatus].7:4≠3,1->R_KeyStatus.7 
			BCF	R_KeyStatus,4	;0->R_KeyStatus.4 
			BCF	R_KeyStatus,6	;0->R_KeyStatus.6 
			MOVLW	10H				;10H=2秒 
			ADDWF	R_TimerCnt,0 
			MOVWF	R_KeyTimer1		;[R_TimerCnt]+10H(2秒)->R_KeyTimer1 
			MOVLW	28H				;28H=5秒 
			ADDWF	R_TimerCnt,0 
			MOVWF	R_KeyTimer2		;[R_TimerCnt]+28H(5秒)->R_KeyTimer2 
			MOVLW	05H 
			SUBWF	R_KeyCode,0 
			BTFSS	STATUS,Z 
			GOTO	L_ReadKey4		;[R_KeyCode]≠05H(不是"UNIT"键按下) 转 
			MOVLW	50H				;50H=10秒,按住"UNIT"键进入快速标定的时间为10秒 
			ADDWF	R_TimerCnt,0 
			MOVWF	R_KeyTimer2		;[R_TimerCnt]+50H(10秒)->R_KeyTimer2 
L_ReadKey4: 
			MOVFW	R_TimerCnt 
			SUBWF	R_KeyTimer1,0 
			BTFSS	STATUS,Z 
			GOTO	L_ReadKey5		;[R_KeyTimer1]≠[R_TimerCnt] 转 
			INCF	R_TimerCnt,0 
			MOVWF	R_KeyTimer1		;[R_TimerCnt]+1->R_KeyTimer1 
			BSF	R_KeyStatus,5	;1->R_KeyStatus.5 
			BSF	R_KeyStatus,7	;1->R_KeyStatus.7 
			MOVLW	0FH 
			SUBWF	R_KeyCode,0 
			BTFSC	STATUS,Z 
			GOTO	L_ReadKey5		;[R_KeyCode]=0FH 转 
			MOVLW	07H 
			ANDWF	R_KeyCode,1		;[R_KeyCode]&07H->R_KeyCode 
L_ReadKey5: 
			BTFSC	R_KeyStatus,6 
			GOTO	L_ReadKeyRet	;[R_KeyStatus].6=1 转,返回 
			MOVFW	R_TimerCnt 
			SUBWF	R_KeyTimer2,0 
			BTFSS	STATUS,Z 
			GOTO	L_ReadKeyRet	;[R_KeyTimer2]≠[R_TimerCnt] 转,返回 
			BSF	R_KeyStatus,6	;1->R_KeyStatus.6 
			BSF	R_KeyStatus,7	;1->R_KeyStatus.7 
			BSF	R_KeyCode,4		;1->R_KeyCode.4 
			MOVLW	04H 
			SUBWF	R_PubReg2,0 
			BTFSC	STATUS,Z 
			BSF		R_PubFlag1,0	;[R_PubReg2]=04H("TARE"键按下),1->R_PubFlag1.0 
L_ReadKeyRet: 
			RETURN 
S_RdKeyCode:				;读键码 
			ADDPCW 
			RETLW	4		;[R_PubCnt2]=001B,键码=100B 
			RETLW	5		;[R_PubCnt2]=010B,键码=101B 
			RETLW	7		;[R_PubCnt2]=011B,键码=111B 
			RETLW	6		;[R_PubCnt2]=100B,键码=110B 
			RETLW	7		;[R_PubCnt2]=101B,键码=111B 
			RETLW	7		;[R_PubCnt2]=110B,键码=111B 
			RETLW	7		;[R_PubCnt2]=111B,键码=111B 
;------------------------------------------------------------------------------ 
;子程序S_ReadCode	;计算最近X次的内码的平均值->R_PubReg1:R_PubReg0,X=[WORK] 
;Input:		R_CodeBuffer[0:F],R_CodePointer,WORK 
;Output:	R_PubReg1:R_PubReg0 
;Use RAM:	WORK,FSR0,IND0,R_Count,R_PubReg3:R_PubReg2,R_PubReg5:R_PubReg4 
;Goto:		S_DivisM 
;===============================================================================
S_ReadCode:	
			MOVWF	R_Count		 
			MOVWF	R_PubReg4 
			CLRF	R_PubReg5 
			CLRF	R_PubReg0 
			CLRF	R_PubReg1 
			CLRF	R_PubReg2 
			CLRF	R_PubReg3 
			DECF	R_CodePointer,0		;\ 
			ANDLW	07H			; | 
			BCF	STATUS,C		; | 计算当前内码存放的地址 
			RLF	WORK,0			; | ->FSR0 
			ADDLW	R_CodeBuffer		; | 
			MOVWF	FSR0			;/  
L_RdCodeLoop: 
			MOVFW	IND0 
			ADDWF	R_PubReg0,1 
			INCF	FSR0,1 
			MOVFW	IND0 
			ADDWFC	R_PubReg1,1 
			MOVLW	0 
			ADDWFC	R_PubReg2,1 
			INCF	FSR0,0 
			BTFSC	STATUS,Z 
			MOVLW	R_CodeBuffer 
			MOVWF	FSR0 
			DECFSZ	R_Count,1 
			GOTO	L_RdCodeLoop ;次数未到,转L_RdCodeLoop继续 
			GOTO	S_DivisM	;[R_PubReg3:R_PubReg0]÷[R_PubReg5:R_PubReg4]->R_PubReg1:R_PubReg0 
;------------------------------------------------------------------------------ 
;子程序S_CalcABS		;计算[R_PubReg5:R_PubReg4]-[R_PubReg1:R_PubReg0]绝对值->R_PubReg5:R_PubReg4 
;Input:		R_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -