?? 4442.asm
字號:
;IC卡讀寫實驗程序
;**************************************************************************
IC_CLK EQU P3.3 ;IC卡時鐘口
IC_IO EQU P3.4 ;IC卡數據口
IC_RST EQU P3.5 ;IC卡復位口
IC_RDY EQU P3.2 ;判斷IC卡是否插入
PIN_BEEPER EQU P1.0 ;無用
;---------------------------------------------------------------------------
IC_PWD EQU 10H ;USED IN 4442 IC CARD
IC_PWD_LEN EQU 03H
COM_BUFF EQU 13H
COM_BUFF_LEN EQU 03H
INPUT_DATA0 EQU 16H
IC_RAM EQU 30H
BYTE_COUNT EQU 17H
COUNT1 EQU 18H
COUNT2 EQU 19H
COUNT0 EQU 1AH
ATR_BUFF EQU 20H
WAIT_COUNT EQU 11H ;顯示時暫存延時字
IC_VALUE EQU 0F000H ;00H~0FFH
IC_XRAM EQU 0F010H
;----------------------------------------------------------------------------
ORG 0000H
AJMP MAIN
ORG 0050H
MAIN: MOV SP,#60H
lcall disp11
MOV WAIT_COUNT,#0FH
WAIT12:LCALL DL1MS
DJNZ WAIT_COUNT,WAIT12
MOV R0,#IC_PWD ;IC卡密碼存放地址
MOV R1,#3
MOV DPTR,#TBL_PSC ;數據存放地址
MAIN_LOOP1:
CLR A
MOVC A,@A+DPTR
MOV @R0,A
INC R0
INC DPTR
DJNZ R1,MAIN_LOOP1
lcall pause ;delay 5us
MOV DPTR,#TBL_WT
MOV P2,#HIGH(IC_XRAM);MOV DPTR,#IC_XRAM
MOV R0,#LOW(IC_XRAM)
MOV R1,#8
MAIN_LOOP2:
CLR A
MOVC A,@A+DPTR
MOVX @R0,A
INC R0
INC DPTR
DJNZ R1,MAIN_LOOP2
;JB IC_RDY,ERR_NOIC ;判斷IC卡是否插入(為高)
;lcall disp1
CHK_IC_PSW:
LCALL CARD_RESET;.................卡復位
CJNE A,#00H,ERR_RST
LCALL CHK_IC_PWD;.................卡PSC校驗
CJNE A,#00H,ERR_PWD
MOV R1,#30H
MOV COUNT0,#8
MOV DPTR,#IC_XRAM
LCALL WRITE_CARD;.................寫卡的MAIN MEMORY
CJNE A,#00H,ERR_WT
MOV R1,#30H
MOV BYTE_COUNT,#8
LCALL READ_CARD;...................讀卡MAIN MEMORY
CJNE A,#00H,ERR_RD
AJMP END_OK
;IC卡沒有插入子程序
ERR_NOIC:
MOV A,#01H
LCALL BEEP_N
JMP $
ERR_RST: ;IC卡復位失敗
MOV B,A
MOV A,#2
LCALL BEEP_N
JMP $
ERR_PWD: ;密碼校驗失敗
MOV B,A
MOV A,#3
LCALL BEEP_N
JMP $
ERR_WT: ;寫IC卡密碼失敗
MOV B,A
MOV A,#4
LCALL BEEP_N
JMP $
ERR_RD: ;讀IC卡密碼失敗
MOV B,A
MOV A,#5
LCALL BEEP_N
JMP $
ERR_UP:
MOV B,A
MOV A,#6
LCALL BEEP_N
JMP $
END_OK:
CLR PIN_BEEPER
LCALL DISP1
JMP $
;/////////////////////////////////////////////////////////////////////////////
;在進行4442卡的操作前進行該步驟. //
;IC CARD ANSWER TO RESET //
;INPUT: NONE //
;OUTPUT: A 0:SUCCESS; FE:ANSWER BYTES WRONG; FF:LINE RESPONSE WRONG //
;/////////////////////////////////////////////////////////////////////////////
CARD_RESET:
SETB IC_IO
LCALL PAUSE
LCALL PAUSE
LCALL PAUSE
MOV R0,#ATR_BUFF ;ATR 緩沖區
MOV COUNT1,#4 ;4個字節
CLR IC_RST ;INITIAL FIRST STATE
lcall pause
CLR IC_CLK
LCALL PAUSE
LCALL PAUSE
SETB IC_RST ;GENERATE RESET SIGN
LCALL PAUSE
SETB IC_CLK
LCALL PAUSE
CLR IC_CLK
LCALL PAUSE
CLR IC_RST
ATR_READ:
MOV COUNT2,#8 ;READ ANSWER TO RESET
ATR_BYTE:
LCALL PAUSE ;READ BYTES
SETB IC_CLK
LCALL PAUSE
MOV C,IC_IO
RRC A
LCALL PAUSE
CLR IC_CLK
LCALL PAUSE
DJNZ COUNT2,ATR_BYTE
MOV @R0,A ;SAVE TO BUFFER
INC R0
DJNZ COUNT1,ATR_READ
JB IC_IO,ATR_LINK ;CHECK SDA
MOV A,#0FFH ;IF LINE WRONG,RETURN FF
SETB EA
RET
ATR_LINK:
MOV R0,#ATR_BUFF ;CHECK ATR
CJNE @R0,#0A2H,ATR_WRONG
INC R0
CJNE @R0,#13H,ATR_WRONG
INC R0
CJNE @R0,#10H,ATR_WRONG
INC R0
CJNE @R0,#91H,ATR_WRONG ;IF ALL OK,RETURN 0
MOV A,#00H
SETB EA
RET
ATR_WRONG:
MOV A,#0FEH ;IF ATR WRONG,RETURN FE
SETB EA
RET
;/////////////////////////////////////////////////////////////////
;向4442卡發送命令. //
;IC CARD SEND COMMAND //
;INPUT: COM_BUFF[3]=Control+Address+Data //
;OUTPUT: NONE //
;/////////////////////////////////////////////////////////////////
CARD_COM_MODE:
MOV R0,#COM_BUFF ;命令緩沖區
MOV COUNT1,#3 ;3字節
LCALL PAUSE ;延時
SETB IC_CLK ;
LCALL PAUSE
CLR IC_IO ;
MOV A,@R0
COM_WRITE: ;寫卡
MOV COUNT2,#8 ;寫命令
COM_WR_BYTE:
LCALL PAUSE ;寫字節
CLR IC_CLK
LCALL PAUSE
RRC A
MOV IC_IO,C
LCALL PAUSE
SETB IC_CLK
LCALL PAUSE
DJNZ COUNT2,COM_WR_BYTE
INC R0 ;GET FROM BUFFER
MOV A,@R0
DJNZ COUNT1,COM_WRITE
LCALL PAUSE ;ALL WRITEN
CLR IC_CLK
LCALL PAUSE
CLR IC_IO
LCALL PAUSE
SETB IC_CLK ;GENERATE STOP SIGN
LCALL PAUSE
SETB IC_IO
RET ;RETURN
;/////////////////////////////////////////////////////////////////
;從4442卡讀入BYTE_COUNT個字節.(在CARD_COM_MODE后使用) //
;IC OUTGOING MODE //
;INPUT: BYTE_COUNT= BYTE NUMBER TO READ //
;OUTPUT: A,@IC_VALUE A=0:SUCCESS; FF:LINE RESPONSE WRONG //
;/////////////////////////////////////////////////////////////////
CARD_OUT_MODE:
;MOV DPTR,#IC_VALUE ;CARD BUFFER
MOV R0,#38H
READ_OUT:
MOV COUNT2,#8 ;READ BYTE
READ_BYTE:
LCALL PAUSE
CLR IC_CLK
LCALL PAUSE
LCALL PAUSE
SETB IC_CLK
LCALL PAUSE
MOV C,IC_IO
RRC A
DJNZ COUNT2,READ_BYTE
;MOVX @DPTR,A ;SAVE TO BUFFER
;INC DPTR
MOV @R0,A
INC R0
DJNZ BYTE_COUNT,READ_OUT
LCALL PAUSE
CLR IC_CLK ;ALL READ
LCALL PAUSE
JB IC_IO,RD_OUT_OK ;CHECK SDA LINE
RD_OUT_WG:
MOV A,#0FFH ;IF LINE WRONG,RETURN FF
RET
RD_OUT_OK:
MOV A,#0 ;IF LINE OK,RETURN 0
RET
;/////////////////////////////////////////////////////////////////
;等待4442卡處理完畢.(在CARD_COM_MODE后使用) //
;IC PROCESSING MODE //
;INPUT: NONE //
;OUTPUT: A 0:SUCCESS; FF:LINE RESPONSE WRONG //
;/////////////////////////////////////////////////////////////////
CARD_PRO_MODE:
MOV COUNT2,#0 ;256 BYTES
LCALL PAUSE
CLR IC_CLK
LCALL PAUSE
JB IC_IO,WR_IN_WG ;CHECK SDA
WR_IN_CON:
LCALL PAUSE ;WAIT SDA TO HIGH,MOST 256 PULSES
SETB IC_CLK
LCALL PAUSE
LCALL PAUSE
CLR IC_CLK
LCALL PAUSE
JB IC_IO,WR_IN_OK
DJNZ COUNT2,WR_IN_CON
WR_IN_WG:
MOV A,#0FFH ;IF DEAD LINE,RETURN FF
RET
WR_IN_OK:
MOV A,#0 ;IF OK,RETURN 0
RET
;///////////////////////////////////////////
;4442卡讀主存儲空間; //
;READ 00-FF BYTES FROM CARD //
;INPUT: R1:Address in card,BYTE_COUNT //
;OUTPUT: A=0FFH: WRONG //
; A= 0: OK //
; @IC_VALUE //
;///////////////////////////////////////////
READ_CARD:
SETB IC_IO
LCALL PAUSE
MOV R0,#COM_BUFF ;ALL OK,READ 256 BYTES IN
MOV @R0,#30H
INC R0
MOV A,R1
MOV @R0,A
INC R0
MOV @R0,#0FFH
LCALL CARD_COM_MODE
LCALL CARD_OUT_MODE
RET
;///////////////////////////////////////////
;4442卡寫主存儲空間; //
;INPUT: DPTR=FIRST ADDR TO WRITE IN RAM //
; R1=FIRST ADDR IN CARD //
; COUNT0=NUMBER OF BYTES //
;OUTPUT: A=0FFH: WRONG //
; A= 0: OK //
;///////////////////////////////////////////
WRITE_CARD:
SETB IC_IO
MOV R2,#00
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -