基于单片机的IC卡智能水表源代码.docx
《基于单片机的IC卡智能水表源代码.docx》由会员分享,可在线阅读,更多相关《基于单片机的IC卡智能水表源代码.docx(20页珍藏版)》请在冰豆网上搜索。
基于单片机的IC卡智能水表源代码
基于单片机的IC卡智能水表源代码
作者:
清华大学杨家沛
;**************************************************************************
;本系统所用CPU:
PIC16F84
;
;采用外接RC经济阻容振荡方式:
R=100KC=100P
;时钟频率约72KHz
;机器周期约56us
;**************************************************************************
INCLUDE“PIC84.H”;PIC84头文件
;**************************************************************************
;液晶显示命令字定义
;**************************************************************************
SYSDISEQUB'00000000';关闭液晶系统振荡和偏振命令字
SYSENEQUB'00000001';打开液晶系统振荡
LCDONEQUB'00000011';打开液晶偏振发生器
BIAS1EQUB'00100000';液晶显示方式命令字
;**************************************************************************
;PICI/O口线输入输出方式定义字
;**************************************************************************
ORBEQUB'01000110';RB口输出状态定义字
;输出状态:
RB0,RB3,RB4,RB5,RB7均为输出,RB1,RB2,RB6为输入
;
IRBEQUB'01100110';RB口输入状态定义字
;输入状态:
RB0,RB3,RB4,RB7为输出,RB1,RB2,RB5,RB6为输入
;
0RAEQUB'11110000';RA口定义字
;RA4为输入,低4位均为输出
;**************************************************************************
;各口线作用定义
;**************************************************************************
SWCH1EQURA2;开阀控制,低电平有效
SWCH2EQURB0;关阀控制,低电平有效
SVOLTEQURB7;IC卡电源地控制(即控制IC卡座电源),低电平有效
SDAEQURA4;IC卡串行数据线(双向)
SCLEQURB4;IC卡时钟线
STEQURB6;IC卡插卡检测线.=1表明IC卡已插入
SPKEQURB3;蜂鸣器控制,高电平蜂鸣
V_MONIEQURB2;电池电压检测线.=1,说明电池电压正常,否则说明过低
WREQURA1;液晶显示时钟输出,正跳变有效
DATAEQURA0;液晶串行数据输出,=1,为0;=0,为1
CSEQURA3;液晶片选控制,高电平有效(同时控制水脉冲,和IC卡)
WINEQURB1;0.1m3脉冲输入线(负跳变有效)
FKEYEQURB5;作为防拆表输入线
;**************************************************************************
;IC84通用寄存器定义(共有68个):
地址为0CH—4FH
;**************************************************************************
XDATAEQU0CH;通用数据暂存单元
CON1EQU0DH;循环条件暂存单元
CON2EQU0EH;循环条件暂存单元
CON3EQU0FH;循环条件暂存单元
CON4EQU10H;循环条件暂存单元
FLAGEQU11H;通用标志字节(各位意义见后)
DFLGEQU12H;液晶显示标志字节(各位意义见后)
DA1DSPEQU13H;液晶显示高2位(BCD码)
DA2DSPEQU14H;液晶显示低2位(BCD码)
LCONEQU15H;循环控制,如果=10则读卡
SWDLEQU16H;关阀延时数
TCONEQU17H;FUNCTIONKEYTESTCOUNT(NOUSE)
STFLGEQU18H;WCRCEQU18H
S0EQU2FH;十六进制->十进制(BCD)中十六进制数暂存
S1EQU2EH;
R0EQU13H;转换后的BCD(4位)暂存
R1EQU14H
XDATA1EQU1AH
XDATA2EQU1BH
CON5EQU19H
XDATEQU1CH
FST1EQU35H;机器开始标志单元(正确的开始标志值为55H
FST2EQU36H;以及0AAH)
RANDHIEQU4AH;加密用随机数高字节
RANDL0EQU4BH;加密用随机数低字节
;**************************************************************************
;下列文件寄存器用来比较用户码及M1码
;**************************************************************************
FVALEQU37H;电磁阀开关标志
WQTHEQU27H;以下3单元为用水总量存储单元,此为高字节
WQTMEQU38H;中字节
WQTLEQU39H;低字节
CRDEQU3AH;读卡条件
WHIEQU3BH;以下2单元是剩水总量存储单元,此为高字节
WLOWEQU3CH;低字节
EFLGEQU3DH;写片内EEPROM剩水单元选择标志.0选EEQ1,
;否则选EEQ2
;**************************************************************************
;读IC卡标志
;**************************************************************************
READFEQU3EH;如不等于0,则说明IC卡未被读过
;**************************************************************************
;下列各信息读自IC卡
;**************************************************************************
USER1EQU3FH;用户码3字节,高
USER2EQU40H;中
USER3EQU41H;低
M1HEQU42H;M1码3字节高
M1MEQU43H;中
M1LEQU44H;低
CRD0EQU45H;原读卡条件
YEAREQU46H;年
MONEQU47H;月
DAYEQU48H;日
HOUREQU49H;时
M2HEQU4AH;M2码3字节
M2MEQU4BH;
M2LEQU4CH;
WQHEQU4DH;购水总量,高字节
WQLEQU4EH;低字节
RCRCEQU4FH;校验码
;**************************************************************************
;液晶显示标志字节(12H),各位定义如下
;**************************************************************************
FWQFEQU0H;传感脉冲处理否标志位.=1,说明已被处理;否则,未处理
READEDEQU1H;读卡标志位.=1,说明IC卡已读
FTCEQU2H;是工厂测试用IC卡否标志位.=1,说明是测试用IC卡
FSTEQU3H;暂时未用
ANKEYEQU4H;暂时未用
FOFFEQU5H;暂时未用
CLOW2EQU6H;暂时未用
SOPENEQU7H;显示开阀标志位.=1,说明开阀;=0,则显示关阀
;**************************************************************************
;标志字节(11H),各位定义如下
;**************************************************************************
FTEQU0H;小数点闪烁标志位.=1,则点亮小数点;=0则不显示
CARDONEQU1H;插卡标志位.=1,说明有IC卡
FWQEQU2H;干簧传感开关闭合标志位(即用水).=1,说明闭合
FVLEQU3H;电池电压过低标志位.=1,说明过低
SWOPENEQU4H;阀门已开否标志.=1说明阀已开;关
CLOWEQU5H;剩水总量过低标志位.=1,说明过低
CNULEQU6H;已无剩水标志位。
=1,说明已无剩水
CLOW1EQU7H;剩水已到关阀警告点标志.=1,说明要告警
;即:
先关阀10秒后开阀
;**************************************************************************
;PIC84片内EEPROM分配(64字节,地址为00H—3FH)
;**************************************************************************
EEPREQU1H;选择片内剩水总量存储单元.=00,选EE1Q;否则,选EE2Q
EE1QLEQU2H;第一剩水总量存储单元,此为低字节
EE1QHEQU3H;高字节
EEWHEQU4H;用水(购水)总量存储单元.高字节
EEWMEQU5H;中字节
EEWLEQU6H;低字节
EEVALEQU7H;SAVEVALVENOCLOSEFLAG(ERRORVALUE0CCH)
EETESTEQU8H;使用工厂测试卡标志.=01,说明可使用测试卡
C0DEEQU9H;用户码(三字节)
EM1EQU0CH;M1码(三字节)
EECRDEQU0FH;原读卡条件标志单元
EE2QLEQU10H;第二剩水总量存储单元(两字节)
EE2QHEQU11H
;**************************************************************************
;所用IC卡单元定义
;**************************************************************************
E2400EQU00H;VALVEERRORFLAG
E2401EQU01H;用水总量存储单元,这里只有中单元,低单元
E2403EQU03H;CONTREADCARD
E2404EQU04H;L,HWQDATAFORUSE,EFLG
E2407EQU07H;此IC卡已读标志.=00,说明此卡上数据已读走,否则未读
E2408EQU08H;用户码存储单元(三字节)
E240BEQU0BH;M1码存储单元(三字节)
E240EEQU0EH;原读卡条件存储单元
E240FEQU0FH;年,月,日,时(各一字节)
E2413EQU13H;M2码存储单元(三字节)
E2416EQU16H;剩水(购水)总量存储单元,高字节在先,低字节在后
E2418EQU18H;CRC校验字节存储单元
LISTF=INHX8M,P=16F84,R=HEX
0RG0
BSTART;复位后从START处开始执行程序
;**************************************************************************
;以下程序:
用于处理0.1m3传感脉冲。
处理的事务有:
1)剩水总数减1,并写入EEPROM;
2)用水总数加1,并写入EEPROM相应单元;
3)根据条件设置剩水不多了等标志位CLOW;
4)设置阀门状态正确与否标志单元:
EEPROM内的EEVAL,RAM内的FVAL
;0CCH表示出错。
;**************************************************************************
WQ11
BSFFLAG,SWOPEN;置位阀已开标志位SWOPEN(<-1)
MOVLWEEVAL
MOVWFEEADR
MOVLW0CCH;写阀门状态出错标志字0CCH(该关时未关)到EEVAL
CALLEEWR
BWQED;转>-将剩水总数WHI,WLOW(十六进制)转换成BCD码
WQ13
BCFDFLG,FWQF;清处理过传感脉冲标志位FWQF
BWQED;转>-将剩水总数WHI,WLOW(十六进制)转换成BCD码
;以下处理0.1m3脉冲过程。
注:
负跳变有效,其他忽略。
WQ1
BTFSSFLAG,FWQ;由FWQ判干簧传感开关闭合否?
BWQ13;NO(=0),说明没有闭合,则转WQ13
BTFSCDFLG,FWQF;YES,则继续由FWQF判(从开->闭的下跳变)次脉
;冲已被处理否?
BWQED;YES(=1),说明此脉冲已处理过。
BSFDFLG,FWQF;NO,则首先置位脉冲已处理标志位FWQF
CALLRDWQ;读取EEPROM中剩水总数到WHI,WLOW单元
MOVFWHI,W
I0RWFWLOW,W;判剩水为0否?
SKPNZ;NO,则继续
BWQ11YES,则出错处理(WQ11)
DECFWLOW,SAME;从WHI,WLOW中减1(即用掉了0.1m3)
INCFWLOW,W;
SKPZ
BWQ14
DECFWHI,SAME
;以下程序首先读取EEPROM中用水总量单元EEWL,EEWM,EEWH,
;加1后回存,并存入RAM中用水总量单元WQFL,WQFM,WQFH
WQ14
MOVLWEEWL
CALLEERD
MOVWFWQTL
INCFWQTL,SAME
SKPZ
BWQ12
MOVLWEEWM
CALLEERD
MOVWFWQTM
INCFWQTM,SAME
SKPZ
BWQ12
MOVLWEEWH
CALLEERD
MOVWFWQTH
INCFWQTH,SAME
WQ12
MOVLWEEWH
MOVWFEEADR
MOVFWQTH,W
CALLEEWR
INCFEEADR,SAME
MOVFWQTM,W
CALLEEWR
INCFEEADR,SAME
MOVFWQTL,W
CALLEEWR
CALLWRWQ;将用水总量回存EEPROM
BTFSSFLAG,CLOW;由CLOW判剩水总量过低否?
BWQED;NO转->将剩水处于WHI,WLOW(十六进制)转换成BCD码
MOVFWLOW,W;YES,则判剩水处于哪个告警档(3m3,2m3,1m3)
XORLW1EH;1EH=30(因3/0.1=30,即3m3)
SKPNZ;不是3m3档,转判是2m3档否
BSFFLAG,CLOW1;是3m3档,则设置关阀告警标志CLOW1
MOVFWLOW,W
X0RLW14H;14H=20(2/0.1=20)
SKPNZ
BSFFLAG,CLOW1
MOVFWLOW,W
X0RLW0AH;0AH=10(1/0.1=10)
SKPNZ
BSFFLAG,CLOW1
WQED
MOVFWHI,W;将剩水总数WHI,WLOW(十六进制)转换成BCD码,
MOVWFS0;以便显示剩水总量。
MOVFWLOW
MOVWFS1
CALLBCD
RETURN
;**************************************************************************
;IC卡插卡处理子程序(包括IC卡有效性判断、IC卡读写、数据解加密处理等)
;**************************************************************************
EEIN
BTFSCFLAG,CARDON;由CARDON标志位判有卡否?
BEEI1;YES(=1),则继续
BCFDFLG,READED;NO,则清卡已读标志位READED.因为无卡,当然如此
SETC;置位C,说明未读卡
RETURN;返回
EEI1
SETC;C初始化为1
BTFSCDFLG,READED;由READED判此卡已读否?
RETURN;YES(=1),则C=1返回
BSFDFLG,READED;NO,先置位READED标志位,接下去进行读卡处理
BSFFLAG,CLOW1;设置告警标志位CLOW1(以关阀10秒)
BSFFLAG,SWOPEN;置位阀已开标志位SW0PEN(1,说明阀已开)
BCFFB,SVOLT;IC卡上电
MOVLW.70;
MOVWFCON1
CALLLOP1;延时9MS,以等待电源稳定
MOVLWREADF;间接寻址,读取IC卡18单元的内容存入READF
;开始的相应单元
MOVWFFSR
MOVLW.18;18字节
MOVWFCON2
CALLBSTA;发IC卡开始命令
MOVLW0A0H;写IC卡地址(写方式),0A0H=B'10100000
MOVWFXDATA
CALLTXB
BCEEND;C=1,说明写卡出错,执行IC卡操作结束命令
MOVLWE2407;C=0,则继续读出IC卡已读卡标志单元E2407
MOVWFXDATA
CALLTXB;写单元地址
BCEEND;C=1,说明写卡出错
CALLBSTA;C=0,则继续发IC卡开始命令
MOVLW0A1H;
MOVWFXDATA
CALLTXB;写读卡方式及IC卡地址(0A1H=B10100001)
BCEEND;C=1,说明写卡出错
ELP
CALLRXB;C=0,则读出E2407单元,内容在XDATA中
MOVFXDATA,W
MOVWF0;间接存储
INCFFSR,SAME;指针下移
MOVLW0RB
TRISPB
BCFPB,SDA;每读一字节,发一个确认信号(即SDA=0期间,
;SCL从高到低)
BSFPB,SCL
BCFPB,SCL
DECFSZCON2,SAME;18字节操作完否?
BELP;NO,继续
CALLBSTOP;YES,发IC卡结束命令
BSFPB,SVOLT;IC卡下电
BSFPB,SDA;置SDA,SCL位为高电平,以降低功耗
BSFPB,SCL;
CALLJM;对已读信息进行解密处理
MOVFREADF,W;由READF判此卡已读否?
SKPNZ;NO,说明未读
BELP1;YES,说明已读,则转
CALLCRC;未读,进行累加和校验.Z=1:
说明校验正确;
;否则错误
SKPZ;校验正确,直接返回
ELP1
SETC;校验不正确,则置位C(C<-1)
RETURN;返回
;**************************************************************************
;START主程序:
是这个程序的入口
首先判断低功耗状态位(/PD)与WDT溢出位(/TO),
只有其中一个有效,则转热启动初始化;
否则,说明是上电复位的冷启动,则进行相应初始化
;**************************************************************************
START
BTFSSSTATUS,PD;由PD判是否处于低功耗状态?
BSTAR;YES,说明是SLEEP被唤醒,则转热启动初始化
BTFSSSTATUS,TO;NO,继续由TO判是否是WDT溢出复位?
BSTAR;YES,说明是WDT被唤醒,则转热启动初始化
START1
CALLDL1S;延时3秒
CALLDL1S
CALLDL1S
MOVLWOCH;对从0CH开始的文件寄存器进行清零初始化
MOVWFFSR
CLRAM
CLRFINDF;清F0,实际上清FSR中寄存器
INCFFSR,SAME
BTFSSFSR,6;判FSR的B6位是否为1(RAM:
OCH-4FH,4FH=01001111B)
BCLRAM;NO,继续清0
BTFSSFSR,