📄 9821h621.asm
字号:
;Project: FS9821韩国人体秤
;FileName: 9821H621.ASM
;Ver: H621
;Body: Fortune FS9821
;Author: kangguang
;Modify Date: 2004-12-02
;韩国人体秤0.9d或1.8d归零;0.4KG以下显示为0;自动关机时间为10秒。
;==============================================================================
include FS9821.inc ;FS9821特殊功能寄存器定义(00H-7FH)
;------------------------------------------------------------------------------
;常数定义
D_DayL equ 2
D_DayH equ 0
D_MonthL equ 2
D_MonthH equ 1
;
D_CaliMark equ 0A5H
;
D_OverCodeL equ 24H ;超载内码0F424H=62500d
D_OverCodeH equ 0F4H
D_DecimalDigits equ 01H ;小数位数=1
D_P11 equ 02H ;称重锁定参数:0-7,默认值为2,相当于6613H608中的101H
; =0/1/2/3/4/5/6/7分别对应锁定参数1/4d,1/2d,3/4d,1d,5/4d,3/2d,7/4d,2d
D_P12 equ 02H ;称重速度参数:0/1/2/3表示连续8/7/6/5个数据接近则锁定
; 相当于6613H608中的102H
D_P20 equ 06H ;最大分度数:0-9,默认值为“6”,相当于6613H608中的104H
; =0/1/2/3/4/5/6/7/8/9分别对应最大分度数为500/600/800/1000/1200/1360/1500/1800/2000/3000
; 对应的量程为50KG/60KG/80KG/100KG/120KG/136KG/150KG/180KG/200KG/300KG
D_P21 equ 01H ;最小显示分度数:0-9,默认值为“1”,相当于6613H608中的105H
; =0/1/2/3/4/5/6/7/8/9分别对应最小显示分度数为2/4/5/8/10/12/15/20/25/50
; 对应的重量为0.2KG/0.4KG/0.5KG/0.8KG/1KG/1.2KG/1.5KG/2KG/2.5KG/5KG
;
;LCD Character table (D7-D0=a、b、c、dp、f、g、e、d)
Lcdch0 equ 11101011B ;"0"
Lcdch1 equ 01100000B ;"1"
Lcdch2 equ 11000111B ;"2"
Lcdch3 equ 11100101B ;"3"
Lcdch4 equ 01101100B ;"4"
Lcdch5 equ 10101101B ;"5"
Lcdch6 equ 10101111B ;"6"
Lcdch7 equ 11101000B ;"7"
Lcdch8 equ 11101111B ;"8"
Lcdch9 equ 11101101B ;"9"
LcdchA equ 01110111B ;"A"
Lcdchb equ 00101111B ;"b"
LcdchC equ 10001011B ;"C"
Lcdchd equ 01100111B ;"d"
LcdchE equ 10001111B ;"E"
LcdchF equ 10001110B ;"F"
LcdNull equ 00000000B ;" "
LcdDash equ 00000100B ;"-"
LcdchL equ 00001011B ;"L"
Lcdcho equ 00100111B ;"o"
Lcdchr equ 00000110B ;"r"
LcdchH equ 01101110B ;"H"
LcdchP equ 11001110B ;"P"
Lcdequ equ 00000101B ;"="
;I/O
EEPROM equ PT2
VCC equ 6
CS equ 5
CLK equ 4
DI equ 3
DO equ 3
;------------------------------------------------------------------------------
;通用RAM定义(80H-0FFH)
R_STATUSbak equ 80H
R_WORKbak equ 81H
R_WorkStatus equ 82H ;D7-D4相当于6613中的46H,D3-D0相当于47H
R_Temp equ 83H
R_Count equ 84H ;相当于6613中的6DH
R_PubFlag0 equ 85H
; R_PubFlag0.0=1 1/16秒到
; R_PubFlag0.1=1 1/2秒到
; R_PubFlag0.2=0 1/8秒到
; R_PubFlag0.3=1 读到ADC内码
; R_PubFlag0.4=1 有效内码
; R_PubFlag0.5=1时内码数据稳定,锁定
; R_PubFlag0.6=1 零点(内码)稳定
; R_PubFlag0.7=1 已经找到稳定零点,零点内码未保存
R_PubFlag1 equ 86H
; R_PubFlag1.0=1 表示"TARE"键按下5秒
; R_PubFlag1.1=1 称重数据锁定
; R_PubFlag1.2=1
; R_PubFlag1.3=1 减法结果为负数
; R_PubFlag1.4=1 超载
; R_PubFlag1.5=0/1 计量单位=Kg/lb
; R_PubFlag1.6=1 当前零点内码<标定零点内码(计算重量时用)
; R_PubFlag1.7=1 Timer中断
R_PubReg0 equ 87H ;相当于6613中的69H:68H
R_PubReg1 equ 88H ;相当于6613中的6BH:6AH
R_PubReg2 equ 89H ;相当于6613中的61H:60H
R_PubReg3 equ 8AH ;相当于6613中的63H:62H
R_PubReg4 equ 8BH ;相当于6613中的65H:64H
R_PubReg5 equ 8CH ;相当于6613中的67H:66H
R_PubCnt0 equ 8DH ;相当于6613中的6CH
R_PubCnt1 equ 8EH ;相当于6613中的49H:48H
R_PubCnt2 equ 8FH ;相当于6613中的5FH:5EH
R_PubCnt3 equ 90H ;相当于6613中的6FH:6EH
R_TimerCnt equ 91H ;计时用(单位:1/8秒),相当于6613中的2BH:2AH
R_KeyStatus equ 92H ;按键状态,D0-D2分别对应"OFF"、"UNIT"、"TARE"键,=1时键按下
; ;R_KeyStatus.4=1 表示按键状态已保存
; ;R_KeyStatus.5=1 表示按键时间已到2秒
; ;R_KeyStatus.6=1 表示按键时间已到5秒或20秒
; ;R_KeyStatus.7==1 表示按键状态稳定
R_KeyCode equ 93H ;键码,D2:D0=100/101/110/111分别对应"OFF"/"UNIT"/"TARE"/多键
; ;D3=1 按键释放,=0按键处于按下状态
; ;D4=表示按键长时间按下或长时间按下过
R_KeyTimer1 equ 94H ;按键计时,相当于6613中的41H
R_KeyTimer2 equ 95H ;按键计时,相当于6613中的45H:44H
R_AdcSumL equ 96H ;ADC内码之和低字节(用于平均)
R_AdcSumM equ 97H ;ADC内码之和中间字节(用于平均)
R_AdcSumH equ 98H ;ADC内码之和高字节(用于平均)
R_AdcDataCnt equ 99H ;ADC输出数据计数(计到8次时平均)
R_LastAverageL equ 9AH ;最近X次的内码的平均值低字节,X=1-8,相当于6613中的0C1H:0C0H
R_LastAverageH equ 9BH ;最近X次的内码的平均值高字节,X=1-8,相当于6613中的0C3H:0C2H
R_DifferenceL equ 9CH ;锁定判断的累计差值低字节,相当于6613H618中的0F1H:0F0H
R_DifferenceH equ 9DH ;锁定判断的累计差值高字节,相当于6613H618中的0F3H:0F2H
R_ZeroCodeL equ 9EH ;零点内码低字节,相当于6613中的0CDH:0CCH
R_ZeroCodeH equ 9FH ;零点内码高字节,相当于6613中的0CFH:0CEH
R_LockWeightL equ 0A0H ;锁定的称重数据低字节,相当于6613H608中的0C5H:0C4H
R_LockWeightH equ 0A1H ;锁定的称重数据高字节,相当于6613H608中的0C7H:0C6H
R_SteadyCnt equ 0A2H ;稳定次数,判断锁定用,相当于6613H618中的5DH
R_2dWeightCnt equ 0A3H ;称重0.2KG以下计次
R_OffTimerL equ 0A4H ;自动关机时间倒计时低字节(单位:秒)
R_OffTimerH equ 0A5H ;自动关机时间倒计时高字节(单位:秒),D7=1不自动关机。
R_TmpPubReg0 equ 0A6H ;计算重量中暂存R_PubReg0的数据
R_TmpPubReg1 equ 0A7H ;计算重量中暂存R_PubReg1的数据
R_TmpPubReg2 equ 0A8H ;计算重量中暂存R_PubReg2的数据
R_TmpPubReg3 equ 0A9H ;计算重量中暂存R_PubReg3的数据
R_BattLowCnt equ 0AAH ;电池低电压计数
;
R_DispMode equ 0C9H ;显示模式:D1:D0=0-3位小数;D2=0/1不显示计量单位/显示计量单位;
; D3=0/1显示为10进制方式/显示为16进制数或提示信息
R_DispBuff0 equ 0CAH ;对应LCD上5位7段码数据的最低位
R_DispBuff1 equ 0CBH ;对应LCD上5位7段码数据的十位
R_DispBuff2 equ 0CCH ;对应LCD上5位7段码数据的百位
R_DispBuff3 equ 0CDH ;对应LCD上5位7段码数据的千位
R_DispBuff4 equ 0CEH ;对应LCD上5位7段码数据的最高位
R_DispFlag equ 0CFH ;D7-D4分别对应LCD上的电池符号、空、负号、锁符
;
R_CaliPara equ 0D0H ;标定数据起始地址
R_CaliCode0L equ 0D1H ;零点的标定内码低字节
R_CaliCode0H equ 0D2H ;零点的标定内码高字节
R_CaliCode1L equ 0D3H ;40KG的标定内码低字节
R_CaliCode1H equ 0D4H ;40KG的标定内码高字节
R_CaliCode2L equ 0D5H ;80KG的标定内码低字节
R_CaliCode2H equ 0D6H ;80KG的标定内码高字节
R_CaliData1L equ 0D7H ;40KG标定数据低字节
R_CaliData1H equ 0D8H ;40KG标定数据高字节
R_CaliData2L equ 0D9H ;80KG标定数据低字节
R_CaliData2H equ 0DAH ;80KG标定数据高字节
R_CaliData3L equ 0DBH ;120KG标定数据低字节
R_CaliData3H equ 0DCH ;120KG标定数据高字节
R_CaliFlag equ 0DDH ;已标定内码标志,=0A5H为有效
R_CaliChksumL equ 0DEH ;标定数据校验和低字节
R_CaliChksumH equ 0DFH ;标定数据校验和高字节
;
;
R_LockCodeNum equ 0E2H ;锁定所有的连续有效数据个数最大值,相当于6613H618中的0E9H
R_OffsetCode equ 0E3H ;锁定判断的内码值,相当于6613H618中的0F5H:0F4H
R_10dCodeL equ 0E4H ;10d内码的低字节,相当于6613H618中的0EDH:0ECH
R_10dCodeH equ 0E5H ;10d内码的高字节,相当于6613H618中的0EFH:0EEH
R_MaxScaleMarkL equ 0E6H ;最大分度数(+9)低字节
R_MaxScaleMarkH equ 0E7H ;最大分度数(+9)高字节
R_UnitData0 equ 0EAH ;1d对应的不同计量单位的值(有效数字)低字节
R_UnitData1 equ 0EBH ;1d对应的不同计量单位的值(有效数字)高字节
R_UnitData2 equ 0ECH ;1d对应的不同计量单位的值(浮点数)的2的指数,≥80H为负数
R_AdcDataL equ 0EDH ;暂存ADC输出数据低字节
R_AdcDataH equ 0EEH ;暂存ADC输出数据高字节
R_CodePointer equ 0EFH ;内码存储指针
R_CodeBuffer equ 0F0H ;内码缓存0F0H-0FFH共8组16字节
;==============================================================================
; Program start
;==============================================================================
org 000H
GOTO L_Start ;程序开始(RESET入口)
org 004H
; GOTO L_IntProc ;中断服务程序
L_IntProc:
MOVWF R_WORKbak ;[WORK]->R_WORKbak
MOVFW STATUS
MOVWF R_STATUSbak ;[STATUS]->R_STATUSbak
BTFSC INTF,ADIF
GOTO L_AdcInt ;ADC中断,转
BTFSS INTF,TMIF
GOTO L_IntProcEnd ;不是Timer中断,转
BCF INTF,TMIF ;清Timer中断标志
BSF R_PubFlag1,7 ;1->R_PubFlag1.7 置Timer中断标志
GOTO L_IntProcEnd
L_AdcInt:
BCF INTF,ADIF ;清ADC中断标志
MOVFW ADOL
MOVWF R_AdcDataL ;[ADOL]->R_AdcDataL
MOVFW ADOH
MOVWF R_AdcDataH ;[ADOH]->R_AdcDataH
MOVLW 09H ;\
ADDWF R_AdcDataL,1 ; | [R_AdcDataH:R_AdcDataL]+3D09H(15625)
MOVLW 3DH ; | ->R_AdcDataH:R_AdcDataL (转换为正数内码)
ADDWFC R_AdcDataH,1 ;/
BSF R_PubFlag0,3 ;读到ADC内码
L_IntProcEnd:
MOVFW R_STATUSbak
MOVWF STATUS ;[R_STATUSbak]->STATUS
MOVFW R_WORKbak ;[R_WORKbak]->WORK
RETFIE
;------------------------------------------------------------------------------
;程序开始
L_Start:
CLRF INTE ;关所有中断
MOVLW 01000100B ;CPU指令周期=MCK/2,OSC仅使用内部1MHz
MOVWF MCK
MOVLW 0C0H
MOVWF AIENB1 ;PT1.0-PT1.5 is Analog input channel(AIN0-AIN5)
MOVLW 40H
MOVWF PT1EN ;PT1.7 is input,PT1.6 is output
MOVLW 0C0H
MOVWF PT1 ;0C0H->PT1
MOVWF PT1PU ;0C0H->PT1PU
MOVLW 0
MOVWF PT2MR ;0->PT2MR
MOVWF PT2OCB ;0->PT2OCB
MOVLW 11111100b
MOVWF PT2EN ;PT2.7-PT2.2 is output,PT2.1-PT2.0 is input
MOVLW 00001011b
MOVWF PT2PU ;PT2.3-PT2.0 with pull-up resistor
MOVLW 87H
MOVWF PT2 ;87H->PT2 (1->PT2.7 点亮背光灯,1->PT2.2)
L_InitClrRAM:
MOVLW 80H ;\
MOVWF FSR0 ; \
L_InitClrR_Loop: ; | RAM [0FFH:80H]清零
CLRF IND0 ; |
INCFSZ FSR0,1 ; /
GOTO L_InitClrR_Loop ;/
L_InitSFR:
MOVLW 00011010B ;00011010B
MOVWF NETE ;ENVS,LB输入选AIN4,ENLB
MOVLW 00000011B
MOVWF NETF ;ENBAND=0,ENVDDA=0,ENAGND=1,ENVB=1
; MOVLW 01100011B
; MOVWF NETF ;ENBAND=1,ENVDDA=1,ENAGND=1,ENVB=1
MOVLW 00000001b
MOVWF PCK ;ENPUMP=0,S_CH1CK[1:0]=00,S_BEEP=0,S_PCK=1
; MOVLW 01000001b
; MOVWF PCK ;ENPUMP=1,S_CH1CK[1:0]=00,S_BEEP=0,S_PCK=1
CALL S_Delay
;
; MOVLW 11000100B
; MOVWF NETA ;INL=TEMPL,FTIN=OP1O,FTB=FTIN,INH=FTB
; MOVLW 00001110B
; MOVWF NETB ;OP1N=OP1O,VRL=VR2P,VRH=VR1P
; MOVLW 00001110B
; MOVWF NETD ;OP1EN=1,OP1P=TEMPH
;
MOVLW 01000100B
MOVWF NETA ;INL=AIN2,FTIN=OP1O,FTB=FTIN,INH=FTB
MOVLW 00100100B
MOVWF NETB ;OP1N=AIN5,VRL=AIN1,VRH=AIN0
MOVLW 00001011B
MOVWF NETD ;OP1EN=1,OP1P=AIN3
;
MOVLW 10000110B ;10000110B
MOVWF NETC ;SREFO=1,ADG=1,ADEN=1,AZ=0
MOVLW 00001100b ;00001111b ;ADM=110bADCF/8000
MOVWF ADCON ;ADRST=1,ADM=100b=ADCF/2000
;
CALL S_ClrDisp ;清LCD显示缓冲区LCD1-LCD6
MOVLW 00100111b ;00101111b 1/2bias,1/4duty
MOVWF LCDENR ;start LCD clock,1/3bias,1/4duty
MOVLW 10001011B
MOVWF TMCON ;1/16秒中断
;
BTFSS PT1,7
BSF R_PubFlag1,5 ;PT1.7=0(lb),1->R_PubFlag1.5
;
MOVLW 08H
MOVWF R_DispBuff0 ;8->R_DispBuff0
MOVWF R_DispBuff1 ;8->R_DispBuff1
MOVWF R_DispBuff2 ;8->R_DispBuff2
MOVWF R_DispBuff3 ;8->R_DispBuff3
MOVLW 04H
MOVWF R_DispMode ;04H->R_DispMode(显示计量单位)
CALL S_Display ;显示“8888”
;
L_InitCaliData:
CALL S_RdCaliData ;读93LC46中00H-07H的标定数据送至RAM R_CaliPara-R_CaliChksumH
CALL S_CalcChksum ;计算标定数据之和->R_PubReg3:R_PubReg2
MOVFW R_PubReg2
IORWF R_PubReg3,0
BTFSS STATUS,Z
GOTO L_InitCaliErr ;[R_PubReg3:R_PubReg2]≠0 (93LC46中00H-07H的值错误) 转
MOVLW D_CaliMark
SUBWF R_CaliFlag,0
BTFSS STATUS,Z
GOTO L_InitCaliErr ;[R_CaliFlag]≠D_CaliMark (未标定内码) 转
L_InitScaleMark:
MOVLW D_P20 ;最大分度数参数:0-9
CALL S_RdScaleMark ;读分度数->WORK
MOVWF R_PubReg2 ;[WORK]->R_PubReg2
CLRF R_PubReg3 ;0->R_PubReg3
MOVLW 20
MOVWF R_PubReg4 ;100->R_PubReg4
CLRF R_PubReg5 ;0->R_PubReg5
CALL S_Multi ;[R_PubReg3:R_PubReg2]×[R_PubReg5:R_PubReg4]->R_PubReg3:R_PubReg0
MOVLW 9
ADDWF R_PubReg0,0
MOVWF R_MaxScaleMarkL ;计算出的最大分度数(+9)低字节->R_MaxScaleMarkL
MOVLW 0
ADDWFC R_PubReg1,0
MOVWF R_MaxScaleMarkH ;计算出的最大分度数(+9)高字节->R_MaxScaleMarkH
GOTO L_InitOther
L_InitCaliErr:
MOVLW 0A0H
MOVWF R_PubCnt1 ;0A0H->R_PubCnt1,定时10秒
; MOVLW 30H
; MOVWF R_WorkStatus ;30H->R_WorkStatus,临时修改,用于显示内码
MOVLW 0C0H
MOVWF R_WorkStatus ;0C0H->R_WorkStatus,10秒后关机。
CALL S_Disp9346 ;LCD显示" 9346"
L_InitOther:
CALL S_CalcUnitData ;计算1d对应的KG/LB的值(浮点数),
; 结果->R_UnitData2(2的指数)、R_UnitData1:R_UnitData0(有效数字)
CALL S_CalcLockCode ;计算锁定判断的内码值->R_OffsetCode
CALL S_CalcOffTime ;计算自动关机时间(单位:秒)->R_OffTimerH:R_OffTimerL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -