📄 源程序.asm
字号:
LIST P=16F873
Include "P16F873.INC"
GLXSFLAG EQU 20h;0=洗手设备为电(流)阀;1=洗手设备为脉冲阀
GLXZFLAG EQU 21h;0=洗澡设备为电(流)阀;1=洗澡设备为脉冲阀
XSFLAG EQU 22h;非0=洗手处有人,0=洗手处无人
ADTEMP EQU 23h;AD转换数据结果和低八位,已经处理为温度值
ADTEMPH EQU 46H
CSFLAG EQU 24H;非0=厕所有人,0=厕所无人
XSSTATE EQU 25H;非0=洗手设备已打开或曾使用,0=洗手设备还未打开或未曾使用
XZSTATE EQU 26h;非0=洗澡设备已打开或曾使用,0=洗澡设备还未打开或未曾使用
CSSTATE EQU 27H;非0,已打开,记录人在此呆的时间的低8位
XZMAX EQU 28H;洗澡热水温度值
XSMAX EQU 29H;洗手热水温度值
XZTEMP EQU 2AH;洗澡温度值
XSTEMP EQU 2BH;洗手温度值
XZMIN EQU 2CH;洗澡冷水温度值
XSMIN EQU 2DH;洗手冷水温度值
TIMETEP EQU 2EH;TIMER1中断次数
GTEMP EQU 2FH;全局数据缓存
SENDDATA EQU 30H;待向电阀发送的数据
CONTEMP EQU 31H;定义温度值转发送数据缓存
CONMAX EQU 32H;转换上限温度
CONMIN EQU 33H;转换下限温度
XZEEROR EQU 34H;洗澡冷热电阀接反
XSEEROR EQU 35H;洗手冷热电阀接反
CONDATA EQU 36H;转换后的数据暂存
CARRYH EQU 37H;数据处理中为提高精度而设置的进位位高8位
CARRYL EQU 38H;数据处理中为提高精度而设置的进位位地8位
RECDATA EQU 39H;红外接收中断接收的脉冲信号个数
IFTIME EQU 3AH;红外发送次数,IFTIME个脉冲
IFVALUE EQU 3BH;1=有真的接收到信号,0=未接收到信号,或非有效信号
XSISCS EQU 3CH;1=该红外由厕所发出,0=该红外由洗手池发出
RECTEMP EQU 3DH;红外接收总次数
YLFLAG EQU 3FH;压力信号的低8位
CSSTATEH EQU 40H;厕所信号的高8位
SDFLAG EQU 41H;手动冲水标志
YLFLAGH EQU 42H;压力信号的高8位
DELAYH EQU 43H;延时循环次数1
DELAYL EQU 44H;延时循环次数2
USEFLAG EQU 45H;0=厕所使用,非0=厕所未用
KEEPW EQU 46H;中断保护W
KEEPF EQU 47H;中断保护STATUS
KEEPPC EQU 48H;中断保护PCLATH
KEEPG EQU 49H;次数
SUBT EQU 4AH;乘数
TIMEW EQU 4BH;专用于TIME1中断保护现场W
TIMEF EQU 4CH;专用于TIME1中断保护现场STATUS
TIMEPC EQU 4DH;专用于TIME1中断保护现场PCLATH
;*****************************************
;***^_^***********程序开始*********^_^***
;*****************************************
ORG 0000H
GOTO MAIN
ORG 0004H
BTFSC INTCON,RBIF
GOTO KEYSTATE;按键中断入口
BTFSC INTCON,INTF
GOTO IFREC;红外接收中断入口
BTFSC PIR1,TMR1IF
GOTO TIMEOUT;定时计数器1中断
BTFSC PIR1,ADIF
GOTO ADDILL;AD转换完毕中断
RETFIE;外部干扰中断(EMI...)或程序毛刺
;*****************************************
;***^_^**********主程序开始********^_^***
;*****************************************
MAIN
BCF STATUS,RP1
BCF STATUS,RP0
CLRF TMR0
BSF STATUS,RP0
MOVLW 4FH;使能RC内部弱上拉
MOVWF OPTION_REG;预分频器给看门狗
BCF STATUS,RP0;固定程序段
CLRWDT
;**********设备识别及初始化**************
;洗手,洗澡更换脉冲阀必须使WK经一个电阻接DF
BCF ADCON0,ADON;关AD
BCF INTCON,ADIE
MOVLW 06H;RA设置为:DDDDDDDD,VDD,VSS;
BSF STATUS,RP0
MOVWF ADCON1
CLRF TRISA;RA0~RA7输出
MOVLW 0FH
MOVWF TRISC;RC7~RC4输出,RC3~RC0输入
BCF STATUS,RP0;BANK0
BCF INTCON,RBIE;暂时关闭温度调节开关使能
BCF INTCON,GIE
CLRF GLXSFLAG
BSF PORTA,2;XSWK=1
BTFSS PORTC,1;XSDF
GOTO DFXS
BCF PORTA,2;XSWK=0,防止误判,清零再次判断
BTFSS PORTC,1;XSDF
INCF GLXSFLAG,1
DFXS;已判知洗手阀为电阀
CLRF GLXZFLAG
BSF PORTA,3;XZWK=1
BTFSS PORTC,0;XZDF
GOTO DFXZ
BCF PORTA,3;XZWK=0,防止误判,清零再次判断
BTFSS PORTC,0;XZDF
INCF GLXZFLAG,1
DFXZ;已判知洗澡阀为电阀
BSF STATUS,RP0
MOVLW 0CH;RC2,RC3输入,RC1~RC0,RC4~RC7输出
MOVWF TRISC
BCF STATUS,RP0
MOVF GLXSFLAG,1
BTFSS STATUS,Z
GOTO GLXZ
MOVF GLXZFLAG,1
BTFSS STATUS,Z
GOTO GL1
BSF STATUS,RP0
MOVLW 0F3H
MOVWF TRISB;电阀洗手,电阀洗澡;RB中断有效
BCF STATUS,RP0
BCF PORTC,0
BCF PORTC,1;初始化电阀
BSF PORTC,4
BSF PORTC,5
BSF PORTC,6
BSF PORTC,7
GOTO TRISEND
GL1
BSF STATUS,RP0
MOVLW 0C3H;电阀洗手,脉冲洗澡;RB中断无效
MOVWF TRISB
BCF STATUS,RP0
BCF PORTC,1;洗手初始化电阀
BCF PORTB,4;洗澡初始化脉冲阀
BCF PORTB,5
BSF PORTB,4
CALL DELAY10MS;延时10ms,负脉冲
BCF PORTB,4;一个脉冲关动作
BSF PORTB,6
BSF PORTB,7
GOTO TRISEND
GLXZ
MOVF GLXZFLAG,1
BTFSS STATUS,Z
GOTO GL2
BSF STATUS,RP0
MOVLW 33H;脉冲洗手,电阀洗澡;RB中断无效
MOVWF TRISB
BCF STATUS,RP0
BCF PORTC,0;洗澡电阀初始化
BCF PORTB,6;洗手脉冲初始化
BCF PORTB,7
BSF PORTB,6
CALL DELAY10MS;延时10ms,负脉冲
BCF PORTB,6;一个脉冲关动作
BSF PORTB,5
BSF PORTB,4
GOTO TRISEND
GL2
BSF STATUS,RP0
MOVLW 03H;脉冲洗澡,脉冲洗手
MOVWF TRISB
BCF STATUS,RP0
BCF PORTB,7
BCF PORTB,6;脉冲洗手初始化
BCF PORTB,5
BCF PORTB,4;脉冲洗澡初始化
BSF PORTB,6
BSF PORTB,4
CALL DELAY10MS;延时10ms,负脉冲
BCF PORTB,6;洗手关脉冲
BCF PORTB,4;洗澡关脉冲
TRISEND
;********初始引脚数据值*****************
BCF PORTB,3
BCF PORTB,2
BSF PORTB,1
BSF PORTB,0
CLRF PORTC
BSF PORTC,2
BSF PORTC,3
CALL CSSHUT;关闭厕所脉冲阀
CLRF PORTA
BSF PORTA,0
;**********中断初始化******************
CLRWDT
CLRF INTCON;关闭所有中断使能1,清所有中断标志1
MOVLW 0BH
MOVWF TMR1H
MOVLW 0DEH
MOVWF TMR1L;TIMR1预置数
BSF STATUS,RP0
CLRF PIE1;关闭所有中断使能2
BCF STATUS,RP0
CLRF PIR1;清所有中断标志2
;*********初始化各标志位***************
MOVLW 01H
MOVWF USEFLAG;0=厕所有人,已预冲
CLRF XSFLAG;非0=有人在浴室
CLRF CSFLAG;非0=有人在厕所
CLRF XSSTATE;非0=洗手阀已打开
CLRF XZSTATE;非0=洗澡阀已打开
CLRF CSSTATE;非0有人在厕所
CLRF CSSTATEH
CLRF YLFLAG
CLRF YLFLAGH
CLRF XSEEROR;1=洗手电阀冷热接反
CLRF XZEEROR;1=洗澡电阀冷热接反
CLRF XSISCS;0=红外线由洗手处发出
CLRF TIMETEP;定时次数:n*1us*8*(65536-pre)
CLRF SDFLAG;手动冲水标志位,1=已打开脉冲阀
MOVLW 50
MOVWF XZMAX;最高温度定义
MOVWF XSMAX
MOVLW 20
MOVWF XZMIN;最低温度定义
MOVWF XSMIN
MOVLW 37
MOVWF XZTEMP;默认值定义
MOVWF XSTEMP
BSF INTCON,PEIE;开外设中断
BSF INTCON,RBIE;允许RB中断
;*******循环查询开始********************
START
;洗手查询
CLRWDT
CLRF XSISCS
MOVLW 08H
MOVWF IFTIME
BSF INTCON,INTE;允许INT中断
BSF PORTC,6;XSRE=1
CALL IFSEND;洗手红外发射
CLRWDT
SLEEP;等待INTF中断唤醒,或者WDT唤醒
BCF INTCON,INTE;关闭INT中断
MOVF IFVALUE,1
BTFSC STATUS,Z
GOTO XSNO
;洗手池有人时
INCF XSFLAG,1;有人标志非0
MOVF XSSTATE,1
BTFSS STATUS,Z
GOTO XSCEND;洗手电阀已经打开
;洗手电阀未打开
MOVF GLXSFLAG,1
BTFSS STATUS,Z
GOTO MCXSC
;电阀控制,开
CALL XSCHANG;调用洗手电阀调节
INCF XSSTATE,1
GOTO XSCEND
MCXSC;脉冲控制,开
BCF PORTB,7
BCF PORTB,6
BSF PORTB,7
CALL DELAY10MS;延时10ms,正脉冲
BCF PORTB,7
INCF XSSTATE,1
GOTO XSCEND
XSNO;洗手池无人时
CLRF XSFLAG;无人标志位
MOVF XSSTATE,1
BTFSC STATUS,Z
GOTO XSCEND;电阀未曾打开
;人离开后,电阀曾打开尚未关闭
MOVF GLXSFLAG,1
BTFSC STATUS,Z
GOTO DFSHUT;关洗手电阀
;关洗手脉冲阀
BCF PORTB,6
BCF PORTB,7
BSF PORTB,6
CALL DELAY10MS;延时10ms,负脉冲
BCF PORTB,6
CLRF XSSTATE;清除使用标志
GOTO XSCEND
DFSHUT
BCF PORTC,1
CLRF XSSTATE;清除使用标志
XSCEND
MOVF XSFLAG,1
BTFSC STATUS,Z
GOTO XZCHECK
BTFSS PORTB,7;XSIC,是否升温
GOTO SFDC
INCF XSTEMP
CALL XSCHANG;改变洗手水温
SFDC
BTFSS PORTB,6;XSDC,是否降温
GOTO XZCHECK
DECF XSTEMP
CALL XSCHANG;改变洗手水温
;洗澡查询
XZCHECK
CLRWDT
BTFSS PORTB,1;XZSW,洗澡开关
GOTO XZNO
CALL DELAY10MS;延时10ms,防抖
BTFSS PORTB,1
GOTO XZNO;无人
;浴室有人
MOVF XZSTATE,1
BTFSC STATUS,Z
GOTO XZCEND;使用中
;未使用
INCF XZSTATE,1
MOVF GLXZFLAG,1
BTFSS STATUS,Z
GOTO MCXZ
CALL XZCHANG;开启洗澡电阀
INCF XZSTATE,1
GOTO XZCEND
MCXZ
BCF PORTB,5;开脉冲阀
BCF PORTB,4
BSF PORTB,5
CALL DELAY10MS;延时10ms,正脉冲
BCF PORTB,5
INCF XZSTATE,1
XZNO;浴室无人
MOVF XZSTATE,1
BTFSC STATUS,Z
GOTO XZCEND;未曾使用
;使用过,未曾关闭
MOVF GLXZFLAG,1
BTFSS STATUS,Z
GOTO MCSHUT
BCF PORTC,0;关电阀
CLRF XZSTATE
GOTO XZCEND
MCSHUT;关脉冲阀
BCF PORTB,4
BCF PORTB,5
BSF PORTB,4
CALL DELAY10MS;延时10ms,负脉冲
BCF PORTB,4
CLRF XZSTATE
XZCEND
BTFSS PORTB,1;XZSW
GOTO CSCHECK;无人
BTFSS PORTB,5;XZIC,是否升温
GOTO FDC
INCF XZTEMP,1
CALL XZCHANG;手动升温,改变温度
FDC
BTFSS PORTB,4;XZDC,是否降温
GOTO CSCHECK
DECF XZTEMP,1
CALL XZCHANG;手动降温,改变温度
;厕所查询,洗澡时禁止
CSCHECK
; CSSTATEH:CSSTATE用于TIMR1红外监测厕所是否有人的信号数
; YLFLAGH:YLFLAG用于TIMR1压力监测的信号数
CLRWDT
MOVF XZSTATE,1
BTFSS STATUS,Z
GOTO CSNO;洗澡中,厕所禁止使用
INCF XSISCS;红外由厕所发出
MOVLW 09H
MOVWF IFTIME
BSF INTCON,INTE
CALL IFSEND;厕所红外发送
CLRWDT
SLEEP
BCF INTCON,INTE
MOVF IFVALUE,1
BTFSC STATUS,Z
GOTO CSNO;厕所无人
;厕所有人
MOVF CSFLAG,1
BTFSS STATUS,Z
GOTO SDWATER
;预冲
INCF CSFLAG,1
CALL CSOPEN;厕所开始冲水
MOVLW 04H;冲水2秒
MOVWF TIMETEP
MOVLW 0BH
MOVWF TMR1H
MOVLW 0DEH
MOVWF TMR1L
MOVLW 30H
MOVWF T1CON;8分频,0BDEh后为0.5s
BCF PIR1,TMR1IF
BSF STATUS,RP0
BSF PIE1,TMR1IE; 开定时器1
BCF STATUS,RP0
BSF T1CON,TMR1ON
PRESLEP
CLRWDT
SLEEP
MOVF TIMETEP,1
BTFSS STATUS,Z;等待预冲水时间到
GOTO PRESLEP
CALL CSSHUT;关闭厕所脉冲阀
CLRF USEFLAG;0=计数标志FLAG
CLRF CSSTATE;COUNT =0
CLRF CSSTATEH
CLRF YLFLAG;压力测算计数
CLRF YLFLAGH
GOTO CSCEND
SDWATER;手动冲水
BTFSS PORTC,3
GOTO SDSHUT
CALL DELAY10MS;延时10ms,防抖
BTFSS PORTC,3
GOTO SDSHUT
MOVF SDFLAG,1
BTFSS STATUS,Z
GOTO CSCEND
CALL CSOPEN;手动冲水开启
INCF SDFLAG,1
GOTO CSCEND
SDSHUT
MOVF SDFLAG,1
BTFSC STATUS,Z
GOTO CSCEND
CALL CSSHUT;手动冲水关闭
CLRF SDFLAG
GOTO CSCEND
CSNO;无人
INCF USEFLAG,1
MOVF CSFLAG,1
BTFSC STATUS,Z
GOTO CSCEND
CLRF CSFLAG;切换到无人
BCF T1CON,TMR1ON;关定时器
BSF STATUS,RP0
BCF PIE1,TMR1IE;关定时计数器1使能
BCF STATUS,RP0
;YLFLAGH:YLFLAG和CSSTATEH:CSSTATE比较大小
;较大的保存在CSSTATEH:CSSTATE中
MOVF YLFLAGH,0
MOVWF CARRYH
MOVF YLFLAG,0
MOVWF CARRYL
CALL COMCSSTATE;比较大小,GTEMP=0表示CSSTATEH:CSSTATE<CARRYH:CARRYL
MOVF CARRYH,1
BTFSS STATUS,Z
GOTO SEGMENT
MOVF YLFLAG,0
SUBWF CSSTATE,0
ADDWF YLFLAG,1
SUBWF CSSTATE,1;交换低8位
MOVF YLFLAGH,0
SUBWF CSSTATEH,0
ADDWF YLFLAGH,1
SUBWF CSSTATEH,1;交换高8位
SEGMENT
CLRF TIMETEP
MOVF YLFLAGH,1
BTFSS STATUS,Z
GOTO NOTMALE
MOVF YLFLAG,1
BTFSC STATUS,Z
GOTO MALE
NOTMALE
;>5min
MOVLW 58H
MOVWF CARRYL
MOVLW 02H
MOVWF CARRYH
CALL COMCSSTATE;比较大小,GTEMP=0表示CSSTATEH:CSSTATE<CARRYH:CARRYL
MOVF CARRYH,1
BTFSS STATUS,Z
GOTO DY10
;大于3.5min
MOVLW 0A4H
MOVWF CARRYL
MOVLW 01H
MOVWF CARRYH
CALL COMCSSTATE;比较大小,GTEMP=0表示CSSTATEH:CSSTATE<CARRYH:CARRYL
BTFSS STATUS,Z
GOTO DY7
;大于2min
MOVLW 0F0H
MOVWF CARRYL
CLRF CARRYH
CALL COMCSSTATE;比较大小,GTEMP=0表示CSSTATEH:CSSTATE<CARRYH:CARRYL
BTFSS STATUS,Z
GOTO DY4
GOTO MALE;<2min
DY10
MOVLW 02H
MOVWF TIMETEP;冲水6.5秒
DY7
MOVLW 02H
ADDWF TIMETEP;冲水5.5秒
DY4
MOVLW 02H
ADDWF TIMETEP;冲水4.5秒
MALE;小便模式
MOVLW 07H
ADDWF TIMETEP;冲水3.5秒
WATER
CALL CSOPEN;比较大小,GTEMP=0表示CSSTATEH:CSSTATE<CARRYH:CARRYL
;设置TIMR1
MOVLW 0BH
MOVWF TMR1H
MOVLW 0DEH
MOVWF TMR1L
BCF PIR1,TMR1IF;清TIME1中断标志
BSF STATUS,RP0
BSF PIE1,TMR1IE;中断使能
BCF STATUS,RP0
MOVLW 30H
MOVWF T1CON
BSF T1CON,TMR1ON;开启定时计数器1
;人离开后冲水时间
AFTER
CLRWDT
SLEEP
MOVF TIMETEP,1
BTFSS STATUS,Z
GOTO AFTER;等待冲水时间到
BSF STATUS,RP0
BCF PIE1,TMR1IE;关闭计时中断
BCF STATUS,RP0
BCF T1CON,TMR1ON;关闭计时器
CALL CSSHUT;关脉冲阀
CLRF CSSTATE
CLRF CSSTATEH
CLRF YLFLAG
CLRF YLFLAGH
CSCEND
MOVF XSSTATE,1
BTFSS STATUS,Z
GOTO START
MOVF XZSTATE,1
BTFSS STATUS,Z
GOTO START
MOVF CSFLAG,1
BTFSS STATUS,Z
GOTO START
;均未检测到有人使用卫生间,0.5s之后再检测
MOVLW 10H
MOVWF DELAYL
OVERSLEP
CLRWDT
SLEEP;由看门狗唤醒
DECFSZ DELAYL,1
GOTO START;主程序结束
;*****************************************
;***^_^***CSSTATE大小比较子程序***^_^***
;*************10uS~15uS*****************
COMCSSTATE;0=CSSTATE<CARRY;
MOVF CARRYH,0
SUBWF CSSTATEH,0
BTFSS STATUS,C
GOTO XYU
BTFSS STATUS,Z
GOTO DYU
MOVF CARRYL,0
SUBWF CSSTATE,0
BTFSS STATUS,C
GOTO XYU
DYU
MOVLW 01H
MOVWF CARRYH
GOTO COMEND
XYU
CLRF CARRYH
COMEND
RETURN
;*****************************************
;***^_^*****厕所脉冲阀打开子程序*****^_^***
;**************10008uS****************
CSOPEN
BCF PORTA,4
BCF PORTA,5
BSF PORTA,4
CALL DELAY10MS;延时10ms,形成正脉冲
BCF PORTA,4
RETURN
;*****************************************
;***^_^*****厕所脉冲阀关闭子程序*****^_^***
;***************10008uS*****************
CSSHUT
BCF PORTA,5
BCF PORTA,4
BSF PORTA,5
CALL DELAY10MS;延时10ms,形成负脉冲
BCF PORTA,5
RETURN
;*****************************************
;***^_^********红外接收子程序******^_^***
;*****************148US*****************
;结果在RECDATA中
IFANSWER;
CLRWDT;
MOVLW 06H
MOVWF RECTEMP
CLRF RECDATA
RECLOOP1
BTFSC PORTB,0
INCF RECDATA,1
MOVLW 04H
MOVWF DELAYH
RECLOOP2
NOP
DECFSZ DELAYH,1
GOTO RECLOOP2
DECFSZ RECTEMP,1
GOTO RECLOOP1
BCF PORTC,6;XSRE
BCF PORTC,5;XZRE
RETURN
;*****************************************
;***^_^********红外发送子程序******^_^***
;*****************************************
;入口:IFTIME发送次数
IFSEND;225US(8),252US(9)
CLRWDT
MOVF XSISCS,1
BTFSS STATUS,Z
GOTO CSSEND
XSSEND;红外由洗手发出
BSF PORTC,6;XSRE=1
NOP
XS38
BSF PORTB,3;XSIF=1;10US
MOVLW 02H
MOVWF DELAYH
XSLOOP
NOP
DECFSZ DELAYH,1
GOTO XSLOOP
BCF PORTB,3;XSIF=0;16US
NOP
NOP
MOVLW 02H
MOVWF DELAYH
XSLOOP1
NOP
DECFSZ DELAYH,1
GOTO XSLOOP1
DECFSZ IFTIME,1
GOTO XS38
GOTO SENDEND;26US=>38kHZ
CSSEND;红外由厕所发出
BSF PORTC,5;CSRE
NOP
CS38
BSF PORTB,2;CSIF;10US
MOVLW 02H
MOVWF DELAYH
CSLOOP
NOP
DECFSZ DELAYH,1
GOTO CSLOOP
BCF PORTB,2;CSIF;16US
NOP
NOP
MOVLW 02H
MOVWF DELAYH
CSLOOP1
NOP
DECFSZ DELAYH,1
GOTO CSLOOP1
DECFSZ IFTIME,1
GOTO CS38
SENDEND
RETURN
;*****************************************
;***^_^*****洗澡初始及变化程序*****^_^***
;*****************************************
XZCHANG
CLRWDT
MOVF XZSTATE,1
BTFSS STATUS,Z
GOTO XZON
;第一次调用
INCF XZSTATE,1
BSF PORTA,3;XZWK,开洗澡温控
BSF PORTC,0;XZDF,开洗澡电阀
MOVLW 2AH;42;开冷水
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -