📄 ticcard.asm
字号:
MOVF irqBits,W
ANDLW 20H
BTFSC STATUS,Z
GOTO SRI_6
MOVLW RegInterruptRq
MOVWF ADDRESS
MOVLW 20H
MOVWF DAT3
CALL PUTRC500
MOVLW MI_NOTAGERR
MOVWF MfStatus
SRI_6:
GOTO SRI_0
SRI_EX:
MOVF oldPageSelect,W
IORLW 0X80
MOVWF DAT3
MOVLW REGPAGE
MOVF ADDRESS
CALL PUTRC500 ;还原页面地址
GOTO INTERRUPT_RET
;++++++++++++++++++++++++++++++++++++++++++++++
;rc500的库函数
;++++++++++++++++++++++++++++++++++++++++++++++
;***********************************************************
;射频卡子程序
;PcdReset 初始化RC500
;Mf500PiccCommonRequest 寻卡
;Mf500PiccCascAnticoll 防冲撞
;Mf500PiccCascSelect 选定一张卡
;CHANGE_KEY 转换密钥匙格式
;Mf500PiccAuthKey 传送密钥
;PCD_AUTHENTICATION 验证密钥
;PCD_RED 读卡
;PCD_WRITE 写卡
;PCD_MANIPULATION 扣款/充值
;PCD_RESTORE 调钱包
;PCD_TRANSFER 保存钱包
;Mf500PiccHalt 卡休眠
;PCD_READ_EE 读RC500-EEPROM
;PCD_WRITE_EE 写RC500-EEPROM
;RESTORE 恢复RC500出厂设置
;LOADCONFIG 调自定义RC500设置
;LOADKEYEE 调RC500-EEPROM中的密钥
;PCD_RFON 开天线
;PCD_RFOFF 关天线
;=================================================
; 设置RC500定时
;=================================================
;=======================================
PcdSetTmo:
MOVWF COUNT0
MOVLW 08H
SUBWF COUNT0,W
BTFSC STATUS,C
GOTO pst_08
MOVF COUNT0,W
ADDWF PCL,F
GOTO pst_08
GOTO pst_01
GOTO pst_02
GOTO pst_03
GOTO pst_04
GOTO pst_05
GOTO pst_06
GOTO pst_07
pst_01
MOVLW 07H
MOVWF VALUE
MOVLW 6AH
MOVWF RF1
GOTO pst_RET
pst_02:
MOVLW 07H
MOVWF VALUE
MOVLW 0A0H
MOVWF RF1
GOTO pst_RET
pst_03:
MOVLW 09H
MOVWF VALUE
MOVLW 0A0H
MOVWF RF1
GOTO pst_RET
pst_04:
MOVLW 09H
MOVWF VALUE
MOVLW 0FFH
MOVWF RF1
GOTO pst_RET
pst_05:
MOVLW 0BH
MOVWF VALUE
MOVLW 0FFH
MOVWF RF1
GOTO pst_RET
pst_06:
MOVLW 0DH
MOVWF VALUE
MOVLW 0FFH
MOVWF RF1
GOTO pst_RET
pst_07
MOVLW 0FH
MOVWF VALUE
MOVLW 0FFH
MOVWF RF1
GOTO pst_RET
pst_08
MOVLW 07H
MOVWF VALUE
MOVF COUNT0,W
MOVWF RF1
pst_RET
MOVLW REGTIMERCLOCK ;PAGE5
MOVWF address1
CALL WRITERC
MOVLW REGTIMERRELOAD ;PAGE5启动时定时器装入TReloadValue,改变该寄存器只在下次启动事件影响定时
MOVWF address
MOVF RF1,W
MOVWF DAT3
CALL PUTRC500
RETURN
;----------------------------------
;=================================================
; 初始化RC500
;注 意:RC500上电后应延时500ms才能可靠初始化
;占用资源:
;=================================================
;//////////////////////////////////////////////////////////////////////
;// R E S E T
;///////////////////////////////////////////////////////////////////////
PcdRfReset:
MOVLW RegTxControl
MOVWF ADDRESS1
MOVLW 03H
MOVWF CLRBUF
call CLEARBIT
MOVF COUNT0,F
BTFSC STATUS,Z
GOTO PRR_ex
call Delay1ms
MOVLW RegTxControl
MOVWF ADDRESS1
MOVLW 03H
MOVWF SETBUF
call SetBit
PRR_ex:
MOVLW MI_OK
MOVWF STATUS_REG
RETURN
;;
;/////////////////////////////////////////////////////////////////////
; M I F A R E M O D U L E R E S E T
;/////////////////////////////////////////////////////////////////////
PcdReset:
BCF RC500_RST
CALL DELAY25MS
BSF RC500_RST
CALL DELAY10MS
BCF RC500_RST
; CALL DELAY2.5MS
BCF RC500_CS
MOVLW 03H
MOVWF PORTA
MOVLW 83H
MOVWF TMR1L
MOVLW 6DH
MOVWF TMR1H
MOVLW D'21'
MOVWF TMR1_CNT
CALL StartT2Timeout ;2.1S
MOVLW REGPAGE
MOVWF ADDRESS1
CLRF VALUE
CALL WRITERC
MOVLW REGCOMMAND ;启动(和停止)命令的执行
MOVWF address1 ;读REGCOMMAND地址
MOVLW REGPAGE
MOVWF VALUE ;读页面
MOVF address1,W
MOVWF ADDRESS
pr_00:
CALL GETRC500 ;读REGCOMMAND值
MOVF TEMP_DATA,W
ANDLW 3FH
XORLW 3FH ;判断读出数据是否3FH
BTFSC STATUS,Z
GOTO pr_01
pr_001:
BTFSC FLAG_T2OUT
GOTO pr_err
GOTO pr_00
pr_01:
MOVLW REGCOMMAND ;启动(和停止)命令的执行
MOVWF address
CALL GETRC500 ;读REGCOMMAND值
MOVF TEMP_DATA,W
ANDLW 3FH
BTFSC STATUS,Z
GOTO pr_02
BTFSC FLAG_T2OUT
GOTO pr_err
GOTO pr_01
pr_02
call StopT2Timeout
MOVLW REGPAGE
MOVWF ADDRESS
MOVLW 80H
MOVWF DAT3 ;向REGCOMMAND写入80H
CALL PUTRC500
MOVLW RegCommand
MOVWF ADDRESS
CALL GETRC500
MOVF TEMP_DATA,W
BTFSS STATUS,Z
GOTO pr_03
MOVLW MI_OK
MOVWF STATUS_REG
MOVLW REGPAGE
MOVWF ADDRESS
MOVLW 00H
MOVWF DAT3 ;
CALL PUTRC500
RETURN
pr_03:
MOVLW MI_INTERFACEERR
MOVWF STATUS_REG
RETURN
pr_err:
call StopT2Timeout
MOVLW MI_RESETERR
MOVWF STATUS_REG
RETURN
;///////////////////////////////////////////////////////////////////////
;// M I F A R E M O D U L E C O N F I G U R A T I O N
;///////////////////////////////////////////////////////////////////////
Mf500PcdConfig:
call PcdReset
movlw MI_OK
XORWF STATUS_REG,W
BTFSS STATUS,Z
GOTO MPC_ex
MOVLW REGCLOCKQCONTROL ;控制时钟产生用于90度相移的Q信道时钟
MOVWF ADDRESS1
MOVLW 00H ;80H
MOVWF VALUE
CALL WRITERC
MOVLW REGCLOCKQCONTROL
MOVWF ADDRESS1
MOVLW 40H ;0C0H
MOVWF VALUE
CALL WRITERC
CALL DELAY100US
MOVLW REGCLOCKQCONTROL
MOVWF ADDRESS1
MOVLW 40H
MOVWF CLRBUF
CALL CLEARBIT
MOVLW REGBITPHASE ;选择发送器和接收器时钟之间的位相位
MOVWF ADDRESS1
MOVLW 0ADH
MOVWF VALUE
CALL WRITERC
MOVLW REGRXTHRESHOLD
MOVWF ADDRESS1
MOVLW 0FFH ;BIT7-BIT4定义解码器输入端可接受的最小信号强度,如果信号小于该值将不进行计算
;BIT3-BIT0定义解码器输入的最小信号强度,该信号必须被Manchester编码信号的弱半位达到以产生相对于强半位幅度的位冲突
MOVWF VALUE
CALL WRITERC
MOVLW RegRxControl2
MOVWF ADDRESS1
MOVLW 01H ;81H ;接收器始终有效,内部解调器
MOVWF VALUE
CALL WRITERC
MOVLW REGFIFOLEVEL
MOVWF ADDRESS1
MOVLW 04H ;1AH ;该寄存器定义了MF RC500用于微处理器的FIFO上溢和下溢警告界限,
;如果FIFO缓冲区剩余空间等于或小于FIFO缓冲区中的WaterLevel字节,HiAlert设置为1,
;如果等于或小于FIFO缓冲区中的WaterLevel字节,LoAlert设置为1
MOVWF VALUE
CALL WRITERC
MOVLW RegTimerControl
MOVWF ADDRESS1
MOVLW 02H ;
MOVWF VALUE
CALL WRITERC
MOVLW 01H
CALL PcdSetTmo
MOVLW REGIRQPINCONFIG ;
MOVWF ADDRESS1
MOVLW 03H ;管脚IRQ上的信号与对应的位IRQ状态相反,IRQ为开漏输出
MOVWF VALUE
CALL WRITERC
MOVLW 01H
MOVWF COUNT0
call PcdRfReset
; MOVLW RegTxControl ;天线驱动脚TX1和TX2的逻辑状态控制
; MOVWF ADDRESS1
; MOVLW 5BH
; MOVWF VALUE
; CALL WRITERC
MOVLW MI_OK
MOVWF STATUS_REG
MPC_ex:
RETURN
;=================================================
; 寻卡
;入 口:@RF_SBUF=寻卡方式
; @RF_SBUF=52H:寻天线区内所有符合14443A标准的卡
; @RF_SBUF=26H:只寻未进入休眠状态的卡
;出 口:CERR=0/1:有卡/无卡
;占用资源:
;=================================================
;///////////////////////////////////////////////////////////////////////
;// M I F A R E C O M M O N R E Q U E S T
;///////////////////////////////////////////////////////////////////////
Mf500PiccCommonRequest:
MOVLW MI_OK
MOVWF STATUS_REG
; MOVLW D'106'
; call PcdSetTmo
MOVLW REGCHANNELREDUNDANCY ;选择 信道上数据完整性检测的类型和模式
MOVWF ADDRESS1
MOVLW 03H
MOVWF VALUE
CALL WRITERC
MOVLW REGCONTROL ;不同的控制标志:例如:定时器,节电
MOVWF ADDRESS1
MOVLW 08H ;清除与卡的所有数据通信加密
MOVWF CLRBUF
CALL CLEARBIT
MOVLW REGBITFRAMING ;位方式帧的调节
MOVWF ADDRESS1
MOVLW 07H
MOVWF VALUE
CALL WRITERC
MOVLW RegTxControl
MOVWF ADDRESS1
MOVLW 03H
MOVWF SETBUF
CALL SetBit ;启动天线
CALL ResetInfo
; MOVF RF1,W
; MOVWF SND_QUEUE
MOVLW 01H
MOVWF MfBytesToSend
MOVLW PCD_TRANSCEIVE
call PcdSingleResponseCmd
MOVLW MI_OK
XORWF STATUS_REG,W
BTFSS STATUS,Z
GOTO MPCR_ex
MOVLW D'16'
XORWF MfBitsReceived,W
BTFSS STATUS,Z
GOTO MPCR_1
MOVF RCV_QUEUE,W
MOVWF ATQ_BUF
MOVF RCV_QUEUE+1,W
MOVWF ATQ_BUF+1
MOVLW MI_OK
MOVWF STATUS_REG
GOTO MPCR_ex
MPCR_1:
MOVLW MI_BITCOUNTERR
MOVWF STATUS_REG
MPCR_ex:
RETURN
;=================================================
; 防冲撞
;入 口:无
;出 口:CERR=0/1:成功/失败
; @RF_SBUF-@(RF_SBUF+3)=序列号
; @(RF_SBUF+4)=序列号的校验字
;占用资源:
;注 :寻卡成功后,通过此函数向天线区内卡片发送防冲撞
; 命令,无论天线区内有几张卡,此函数只得到一张卡片
; 的序列号,再用Pcdselect()函数选定这张卡,则所有
; 后续命令针对此卡,操作完毕后用PcdHalt()命令此卡
; 进入休眠状态,再寻未进入休眠状态的卡,可进行其
; 它卡片的操作
;=================================================
;///////////////////////////////////////////////////////////////////////
;// M I F A R E A N T I C O L L I S I O N
;// for extended serial numbers
;///////////////////////////////////////////////////////////////////////
Mf500PiccCascAnticoll:
GOTO Mf500PiccCascAnticoll_1
;=================================================
; 选定一张卡
;入 口:@RF_SBUF-@(RF_SBUF+3)=序列号
; @(RF_SBUF+4)=序列号的校验字
;出 口:CERR=0/1:成功/失败
;占用资源:ACC,temp_data,R0-R7,PSW
;=================================================
;///////////////////////////////////////////////////////////////////////
;// M I F A R E C A S C A D E D S E L E C T
;// for extended serial number
;R1-RF1,R2-RF2,A-RF3,R0-RF0
;///////////////////////////////////////////////////////////////////////
Mf500PiccCascSelect:
MOVLW MI_OK
MOVWF STATUS_REG
MOVLW D'106'
CALL PcdSetTmo
MOVLW RegChannelRedundancy ;PAGE4
MOVWF ADDRESS1
MOVLW 0fh
MOVWF VALUE
CALL WRITERC
MOVLW REGCONTROL ;PAGE1不同的控制标志:例如:定时器,节电
MOVWF ADDRESS1
MOVLW 08H ;清除与卡的所有数据通信加密
MOVWF CLRBUF
CALL CLEARBIT
; //************* Cmd Sequence **********************************
call ResetInfo
MOVLW SND_QUEUE
MOVWF FSR
MOVF RF2,W
MOVWF INDF
INCF FSR
MOVLW 70H
MOVWF INDF
MOVF RF0,W
MOVWF RF2
MOVWF FSR1
MOVLW SND_QUEUE+2
MOVWF FSR2
MOVLW 04H
MOVWF COUNT0
MPCS_1:
MOVF FSR1,W
MOVWF FSR
MOVF INDF,W
MOVWF COUNT1
MOVF FSR2,W
MOVWF FSR
MOVF COUNT1,W
MOVWF INDF
INCF FSR1
INCF FSR2
DECFSZ COUNT0,F
GOTO MPCS_1
MOVF RF2,W
MOVWF FSR
MOVF INDF,W
INCF FSR
XORLW INDF
INCF FSR
XORLW INDF
INCF FSR
XORLW INDF
MOVWF COUNT0
MOVF FSR2,W
MOVWF FSR
MOVF COUNT0,W
MOVWF INDF
MOVLW 07H
MOVWF MfBytesToSend
MOVLW PCD_TRANSCEIVE
call PcdSingleResponseCmd
BTFSC CERR
GOTO MPCS_ex
MOVLW 08H
XORWF MfBitsReceived,W
BTFSS STATUS,Z
GOTO MPCS_2
MOVF RCV_QUEUE,W
MOVWF SAK_BUF
MOVF RF2,W
MOVWF FSR1
MOVLW MLastSelectedSnr
MOVWF FSR2
MOVLW 04H
MOVWF COUNT0
MPCS1_1:
MOVF FSR1,W
MOVWF FSR
MOVF INDF,W
MOVWF COUNT1
MOVF FSR2,W
MOVWF FSR
MOVF COUNT1,W
MOVWF INDF
INCF FSR1
INCF FSR2
DECFSZ COUNT0,F
GOTO MPCS1_1
BCF CERR
GOTO MPCS_ex
MPCS_2:
MOVLW MI_BITCOUNTERR
MOVWF STATUS_REG
MPCS_ex:
RETURN
;=================================================
; 和RC500通讯
;入 口:@RF_SBUF=RC500命令字
; @(RF_SBUF+1)=发送的数据长度
; @(RF_SBUF+2)...@(RF_SBUF+N)=发送数据
;出 口:@RF_SBUF=错误字
; @(RF_SBUF+1)=接收到的位长度
; @(RF_SBUF+2)...@(RF_SBUF+N)=接收数据
;=================================================
;//////////////////////////////////////////////////////////////////////
;// W R I T E A P C D C O M M A N D
;///////////////////////////////////////////////////////////////////////
PcdSingleResponseCmd:
GOTO PcdSingleResponseCmd_1
;=================================================
; 命令卡进入休眠状态
;入 口:无
;出 口:CERR=0/1:成功/失败
;占用资源:
;=================================================
;///////////////////////////////////////////////////////////////////////
;// M I F A R E H A L T
;///////////////////////////////////////////////////////////////////////
Mf500PiccHalt:
MOVLW D'106'
CALL PcdSetTmo
; // ************* Cmd Sequence **********************************
call ResetInfo
MOVLW PICC_HALT
MOVWF SND_QUEUE
CLRF SND_QUEUE+1
MOVLW 02H
MOVWF MfBytesToSend
MOVLW PCD_TRANSCEIVE
call PcdSingleResponseCmd
MOVLW MI_OK
XORWF STATUS_REG,W
BTFSC STATUS,Z
GOTO MPH_ex
MPH_1:
MOVLW MI_NOTAGERR
XORWF STATUS_REG,W
BTFSC STATUS,Z
GOTO MPH1_1
MOVLW MI_OK
MOVWF STATUS_REG
GOTO MPH_ex
MPH1_1:
MOVLW MI_ACCESSTIMEOUT
XORWF STATUS_REG,W
BTFSS STATUS,Z
GOTO MPH_ex
MOVLW MI_OK
MOVWF STATUS_REG
MPH_ex:
MOVLW RegCommand
MOVWF ADDRESS1
MOVLW PCD_IDLE
MOVWF VALUE
CALL WRITERC
RETURN
;=================================================
; 读RC500-EEPROM的数据
;入 口:@RF_SBUF--@(RF_SBUF+1)=读取的起始地址(低位在前)
; @(RF_SBUF+2)=读字节数
;出 口:CERR=0/1:读成功/失败
; @RF_SBUF--@RF_SBUF+15=读出的数据
;占用资源:ACC,temp_data,R0-R7,PSW
;=================================================
;///////////////////////////////////////////////////////////////////////
;// E E P R O M R E A D
;///////////////////////////////////////////////////////////////////////
PcdReadE2:
call ResetInfo
MOVF RF_SBUF,W
MOVWF SND_QUEUE
MOVF RF_SBUF+1,W
MOVWF SND_QUEUE+1
MOVF RF_SBUF+2,W ;读取数据位数
MOVWF SND_QUEUE+2
MOVLW 03H
MOVWF MfBytesToSend
MOVLW PCD_READE2
call PcdSingleResponseCmd
MOVLW MI_OK
XORWF STATUS_REG,W
BTFSS STATUS,Z
GOTO PRE_ex
MOVLW RCV_QUEUE
MOVWF FSR1
MOVLW RC500_SNR
MOVWF FSR2
PRE_1:
MOVF FSR1,W
MOVWF FSR
MOVF INDF,W ;把序列号存储至RC500_SNR
MOVWF COUNT0
MOVF FSR2,W
MOVWF FSR
MOVF COUNT0,W
MOVWF INDF
INCF FSR1
INCF FSR2
DECFSZ RF_SBUF+1,F
GOTO PRE_1
MOVLW MI_OK
MOVWF STATUS_REG
PRE_ex:
RETURN
;=================================================
; 写数据到RC500-EEPROM
;入 口:@RF_SBUF--@(RF_SBUF+1)=写起始地址(低位在前)
; @(RF_SBUF+2)=写字节数
; @(RF_SBUF+3).....=要写的数据
;出 口:CERR=0/1:写成功/失败
;占用资源:
;=================================================
;///////////////////////////////////////////////////////////////////////
;// E E P R O M W R I T E
;///////////////////////////////////////////////////////////////////////
PcdWriteE2:
call ResetInfo
MOVF RF7,W
MOVWF COUNT0
INCF COUNT0
INCF COUNT0
MOVF COUNT0,W
MOVWF MfBytesToSend
MOVLW SND_QUEUE+2
MOVWF FSR1
MOVF RF0
MOVWF FSR2
PWE_1:
MOVF FSR2,W
MOVWF FSR
MOVF INDF,W
MOVWF COUNT0
MOVF FSR1,W
MOVWF FSR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -