📄 rc500-1.asm
字号:
DJNZ R7,KEYCARD_02
MOV R0,#KEY_BUF
LCALL CHANGE_KEY ;转换密钥
LCALL PCD_KEY ;传送密钥
JB CERR,KEYCARD_02
MOV R0,#RF_SBUF
MOV @R0,#60H ;取验证方式 A
INC R0
MOV @R0,#1 ;验证第一个扇区密钥
MOV R0,#CARD_NO
MOV R1,#RF_SBUF+2
MOV R2,#4
LCALL MEM_COPYA
LCALL PCD_AUTHENTICATION ;验证密钥
JB CERR,KEYCARD_RET ;FCARD_06 ;如果验证通不过则转到开始验证下一个扇区
MOV R0,#RF_SBUF
MOV @R0,#3
INC R0
MOV R7,#6
KEYCARD_03:
MOV @R0,#0FFH
INC R0
DJNZ R7,KEYCARD_03
MOV @R0,#0FFH
INC R0
MOV @R0,#07H
INC R0
MOV @R0,#80H
INC R0
MOV @R0,#69H
LCALL PCD_WRITE
JB CERR,KEYCARD_RET
LCALL PCD_HALT
SETB FCARDKEY
KEYCARD_RET:
RET
;=======================================
;
;=======================================
RC500_READY:
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL D100MS
CALL PCD_RESET
JNB CERR,RC500_READY1
CALL D100MS
CALL PCD_RESET
JNB CERR,RC500_READY1
RET
RC500_READY1:
SETB RC500_OK
RET
;======================================
; 数据传递
;入口:R0=被传送数据地址
; R1=传送数据地址
; R2=传送字节数
;======================================
MEM_COPYA:
MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R2,MEM_COPYA
RET
MEM_COPYB:
MOV A,@R0
MOV @R1,A
DEC R0
DEC R1
DJNZ R2,MEM_COPYB
RET
;=======================================
; 延时子程序
;
;占用资源:R6,R7
;=======================================
D100US: MOV R6,#93
DJNZ R6,$
RET
D100MS: MOV R7,#180
DELAY: MOV R6,#0
del1: NOP
NOP
DJNZ R6,del1
DJNZ R7,DELAY
RET
;***********************************************************
;射频卡子程序
;PCD_RESET 初始化RC500
;PCD_REQUEST 寻卡
;PCD_ANTICOLLISION 防冲撞
;PCD_SELECT 选定一张卡
;CHANGE_KEY 转换密钥匙格式
;PCD_KEY 传送密钥
;PCD_AUTHENTICATION 验证密钥
;PCD_RED 读卡
;PCD_WRITE 写卡
;PCD_MANIPULATION 扣款/充值
;PCD_RESTORE 调钱包
;PCD_TRANSFER 保存钱包
;PCD_HALT 卡休眠
;PCD_READ_EE 读RC500-EEPROM
;PCD_WRITE_EE 写RC500-EEPROM
;RESTORE 恢复RC500出厂设置
;LOADCONFIG 调自定义RC500设置
;LOADKEYEE 调RC500-EEPROM中的密钥
;PCD_RFON 开天线
;PCD_RFOFF 关天线
;=================================================
;MIFARE卡命令字
PICC_REQIDL EQU 26H ;寻天线区内未进入休眠状态的卡
PICC_REQALL EQU 52H ;寻天线区内全部卡
PICC_ANTICOLL1 EQU 93H ;防冲撞
PICC_AUTHENT1A EQU 60H ;验证A密钥
PICC_AUTHENT1B EQU 61H ;验证B密钥
PICC_READ EQU 30H ;读块
PICC_WRITE EQU 0A0H ;写块
PICC_DECREMENT EQU 0C0H ;扣款
PICC_INCREMENT EQU 0C1H ;充值
PICC_RESTORE EQU 0C2H ;调钱包到缓冲区
PICC_TRANSFER EQU 0B0H ;保存缓冲区中数据
PICC_HALT EQU 50H ;休眠
;=================================================
;RC500命令字
PCD_IDLE EQU 00H ;取消当前命令
PCD_WRITEE2 EQU 01H ;写EEPROM
PCD_READE2 EQU 03H ;读EEPROM
PCD_LOADCONFIG EQU 07H ;调EEPROM中保存的RC500设置
PCD_LOADKEYE2 EQU 0BH ;将EEPROM中保存的密钥调入缓存
PCD_AUTHENT1 EQU 0CH ;验证密钥第一步
PCD_AUTHENT2 EQU 14H ;验证密钥第二步
PCD_RECEIVE EQU 16H ;接收数据
PCD_LOADKEY EQU 19H ;传送密钥
PCD_TRANSMIT EQU 1AH ;发送数据
PCD_TRANSCEIVE EQU 1EH ;发送并接收数据
PCD_RESETPHASE EQU 3FH ;复位
PCD_CALCCRC EQU 12H ;CRC计算
;=================================================
;RC500寄存器定义
RegPage EQU 00H
RegCommand EQU 01H
RegFIFOData EQU 02H
RegPrimaryStatus EQU 03H
RegFIFOLength EQU 04H
RegSecondaryStatus EQU 05H
RegInterruptEn EQU 06H
RegInterruptRq EQU 07H
RegControl EQU 09H
RegErrFlag EQU 0AH
RegCollPos EQU 0BH
RegTimerValue EQU 0CH
RegCRCResultLSB EQU 0DH
RegCRCResultMSB EQU 0EH
RegBitFraming EQU 0FH
RegTxControl EQU 11H
RegCwConductance EQU 12H
RFU13 EQU 13H
RegCoderControl EQU 14H
RegModWidth EQU 15H
RegRxControl1 EQU 19H
RegDecoderControl EQU 1AH
RegBitPhase EQU 1BH
RegRxThreshold EQU 1CH
RegRxControl2 EQU 1EH
RegClockQControl EQU 1FH
RegRxWait EQU 21H
RegChannelRedundancy EQU 22H
RegCRCPresetLSB EQU 23H
RegCRCPresetMSB EQU 24H
RegMfOutSelect EQU 26H
RegFIFOLevel EQU 29H
RegTimerClock EQU 2AH
RegTimerControl EQU 2BH
RegTimerReload EQU 2CH
RegIRqPinConfig EQU 2DH
RFU39 EQU 39H
RegTestAnaSelect EQU 3AH
RegTestDigiSelect EQU 3DH
RegTestDigiAccess EQU 3FH
;RC500通讯返回代码定义
MI_OK EQU 0
MI_CHK_OK EQU 0
MI_CRC_ZERO EQU 0
MI_CRC_NOTZERO EQU 1
MI_NOTAGERR EQU (-1)
MI_CHK_FAILED EQU (-1)
MI_CRCERR EQU (-2)
MI_CHK_COMPERR EQU (-2)
MI_EMPTY EQU (-3)
MI_AUTHERR EQU (-4)
MI_PARITYERR EQU (-5)
MI_CODEERR EQU (-6)
MI_SERNRERR EQU (-8)
MI_KEYERR EQU (-9)
MI_NOTAUTHERR EQU (-10)
MI_BITCOUNTERR EQU (-11)
MI_BYTECOUNTERR EQU (-12)
MI_IDLE EQU (-13)
MI_TRANSERR EQU (-14)
MI_WRITEERR EQU (-15)
MI_INCRERR EQU (-16)
MI_DECRERR EQU (-17)
MI_READERR EQU (-18)
MI_OVFLERR EQU (-19)
MI_POLLING EQU (-20)
MI_FRAMINGERR EQU (-21)
MI_ACCESSERR EQU (-22)
MI_UNKNOWN_COMMAND EQU (-23)
MI_COLLERR EQU (-24)
MI_RESETERR EQU (-25)
MI_INITERR EQU (-25)
MI_INTERFACEERR EQU (-26)
MI_ACCESSTIMEOUT EQU (-27)
MI_NOBITWISEANTICOLL EQU (-28)
MI_QUIT EQU (-30)
MI_RECBUF_OVERFLOW EQU (-50)
MI_SENDBYTENR EQU (-51)
MI_SENDBUF_OVERFLOW EQU (-53)
MI_BAUDRATE_NOT_SUPPORTED EQU (-54)
MI_SAME_BAUDRATE_REQUIRED EQU (-55)
MI_WRONG_PARAMETER_VALUE EQU (-60)
MI_BREAK EQU (-99)
MI_NY_IMPLEMENTED EQU (-100)
MI_NO_MFRC EQU (-101)
MI_MFRC_NOTAUTH EQU (-102)
MI_WRONG_DES_MODE EQU (-103)
MI_HOST_AUTH_FAILED EQU (-104)
MI_WRONG_LOAD_MODE EQU (-106)
MI_WRONG_DESKEY EQU (-107)
MI_MKLOAD_FAILED EQU (-108)
MI_FIFOERR EQU (-109)
MI_WRONG_ADDR EQU (-110)
MI_DESKEYLOAD_FAILED EQU (-111)
MI_WRONG_SEL_CNT EQU (-114)
MI_WRONG_TEST_MODE EQU (-117)
MI_TEST_FAILED EQU (-118)
MI_TOC_ERR EQU (-119)
MI_COMM_ABORT EQU (-120)
MI_INVALID_BASE EQU (-121)
MI_MFRC_RESET EQU (-122)
MI_WRONG_VALUE EQU (-123)
MI_VALERR EQU (-124)
;=================================================
; 初始化RC500
;注意:RC500上电后应延时500ms才能可靠初始化
;占用资源:ACC,R0,R1,R2,R6,R7
;=================================================
PCD_RESET:
SETB CERR
CLR RC500_CE
SETB RC500_RST
CALL D100MS
CALL D100MS
CLR RC500_RST
MOV R6,#20H
MOV R7,#0FFH
MOV R0,#REGCOMMAND
MOV R1,#REGPAGE
PCD_RESET1:
CALL WAIT_RC500
MOV A,R6
JZ PCD_RESET4
MOVX A,@R0
CJNE A,#3FH,PCD_RESET1
PCD_RESET2:
CALL WAIT_RC500
MOV A,R6
JZ PCD_RESET4
MOVX A,@R0
XRL A,#3FH
JZ PCD_RESET2
MOV A,#80H
MOVX @R1,A
PCD_RESET3:
CALL WAIT_RC500
MOV A,R6
JZ PCD_RESET
MOVX A,@R0
JB ACC.7,PCD_RESET3
JNZ PCD_RESET4
MOV R1,#REGCLOCKQCONTROL
MOV R2,#0
CALL WRITERC
MOV R1,#REGCLOCKQCONTROL
MOV R2,#40H
CALL WRITERC
CALL D100US
MOV R1,#REGCLOCKQCONTROL
MOV R2,#40H
CALL CLEARBIT
MOV R1,#REGBITPHASE
MOV R2,#0ADH
CALL WRITERC
MOV R1,#REGRXTHRESHOLD
MOV R2,#0FFH
CALL WRITERC
MOV R1,#RegRxControl2
MOV R2,#1
CALL WRITERC
MOV R1,#REGFIFOLEVEL
MOV R2,#1AH
CALL WRITERC
MOV R1,#REGTIMERCONTROL
MOV R2,#2
CALL WRITERC
MOV R1,#REGIRQPINCONFIG
MOV R2,#2
CALL WRITERC
MOV R1,#RegTxControl
MOV R2,#5BH
CALL WRITERC
CLR CERR
PCD_RESET4:
SETB RC500_CE
RET
;=================================================
; 寻卡
;入口:@RF_SBUF=寻卡方式
; @RF_SBUF=52H:寻天线区内所有符合14443A标准的卡
; @RF_SBUF=26H:只寻未进入休眠状态的卡
;出口:CERR=0/1:有卡/无卡
;占用资源:ACC,B,R0-R7,PSW
;=================================================
PCD_REQUEST:
CLR RC500_CE
SETB CERR
MOV A,#1
CALL PCD_SET_TIMER
MOV R1,#REGCHANNELREDUNDANCY
MOV R2,#3
CALL WRITERC
MOV R1,#REGCONTROL
MOV R2,#8
CALL CLEARBIT
MOV R1,#REGBITFRAMING
MOV R2,#7
CALL WRITERC
MOV R0,#RF_SBUF
MOV A,@R0
MOV @R0,#PCD_TRANSCEIVE
INC R0
MOV @R0,#1
INC R0
MOV @R0,A
CALL PCD_COM_TRANSCEIVE
MOV R0,#RF_SBUF
MOV A,@R0
CJNE A,#MI_OK,PCD_REQUEST1
INC R0
MOV A,@R0
CJNE A,#16,PCD_REQUEST1
CLR CERR
PCD_REQUEST1:
SETB RC500_CE
RET
;=================================================
; 防冲撞
;入口:无
;出口:CERR=0/1:成功/失败
; @RF_SBUF-@(RF_SBUF+3)=序列号
; @(RF_SBUF+4)=序列号的校验字
;占用资源:ACC,B,R0-R7,PSW
;注: 寻卡成功后,通过此函数向天线区内卡片发送防冲撞
; 命令,无论天线区内有几张卡,此函数只得到一张卡片
; 的序列号,再用Pcdselect()函数选定这张卡,则所有
; 后续命令针对此卡,操作完毕后用PcdHalt()命令此卡
; 进入休眠状态,再寻未进入休眠状态的卡,可进行其
; 它卡片的操作
;=================================================
PCD_ANTICOLLISION:
CLR RC500_CE
SETB CERR
MOV A,#1
CALL PCD_SET_TIMER
MOV R1,#RegDecoderControl
MOV R2,#28H
CALL WRITERC
MOV R1,#REGCONTROL
MOV R2,#8
CALL CLEARBIT
MOV R1,#RegChannelRedundancy
MOV R2,#3
CALL WRITERC
MOV R0,#RF_SBUF
MOV @R0,#PCD_TRANSCEIVE
INC R0
MOV @R0,#2
INC R0
MOV @R0,#PICC_ANTICOLL1
INC R0
MOV @R0,#20H
CALL PCD_COM_TRANSCEIVE
MOV R0,#RF_SBUF
MOV A,@R0
JNZ PCD_ANTICOLLISION2
MOV R0,#RF_SBUF+2
MOV R2,#5
CLR A
PCD_ANTICOLLISION1:
XRL A,@R0
INC R0
DJNZ R2,PCD_ANTICOLLISION1
JNZ PCD_ANTICOLLISION2
CLR CERR
PCD_ANTICOLLISION2:
MOV R1,#RegDecoderControl
MOV R2,#20H
CALL CLEARBIT
MOV R0,#RF_SBUF+2
MOV R1,#RF_SBUF
MOV R2,#5
CALL MEM_COPYA
SETB RC500_CE
RET
;=================================================
; 选定一张卡
;入口:@RF_SBUF-@(RF_SBUF+3)=序列号
; @(RF_SBUF+4)=序列号的校验字
;出口:CERR=0/1:成功/失败
;占用资源:ACC,B,R0-R7,PSW
;=================================================
PCD_SELECT:
CLR RC500_CE
SETB CERR
MOV A,#1
CALL PCD_SET_TIMER
MOV R1,#RegChannelRedundancy
MOV R2,#0FH
CALL WRITERC
MOV R1,#REGCONTROL
MOV R2,#8
CALL CLEARBIT
MOV R0,#RF_SBUF+4
MOV R1,#RF_SBUF+8
MOV R2,#5
CALL MEM_COPYB
MOV R0,#RF_SBUF
MOV @R0,#PCD_TRANSCEIVE
INC R0
MOV @R0,#7
INC R0
MOV @R0,#PICC_ANTICOLL1
INC R0
MOV @R0,#70H
CALL PCD_COM_TRANSCEIVE
MOV R0,#RF_SBUF
MOV A,@R0
JNZ PCD_SELECT1
INC R0
MOV A,@R0
CJNE A,#8,PCD_SELECT1
CLR CERR
PCD_SELECT1:
SETB RC500_CE
RET
;=================================================
; 转换密钥格式
;功能:将密钥转换为RC500接收格式
; 密钥格式见048020.PDF第67页
;入口:@R0--@(R0+5)=未转换的密钥
;出口:@RF_SBUF-@(RF_SBUF+11)=转换结果
;占用资源:ACC,B,R0-R2,PSW
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -