📄 4428.asm
字号:
. MainLoop:
Jb ICInput,ICOperate ;有IC卡插入吗,有则处理
Clr C
Mov A,DataOff+2 ;购入量与已用量相比较
Subb A,Data+2
Mov A,DataOff+1
Subb A,Data+1
Mov A,DataOff
Subb A,Data
Jnc TakeOn ;是否小于已用量?
TakeOff:
Jnb SWIFON,MainLoop ;如果控制线已经设置,则直接返回
Mov A,#8 ;设置控制线
ACall SetSwitch
Clr SWIFON
Ljmp MainLoop
TakeOn:
Jb SWIFOn,MainLoop ;如果控制线已经清除,则返回
Mov A,#4 ;清除控制线
LCall SetSwitch
SetB SWIFON ;设置已清除标志
Ljmp MainLoop
END.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; IC卡数据定义区,此定义区域资源用作其它用途时注意保存
; IC卡源程序使用了A、C、R0、R1、ByteCnt、BitCnt等资源
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICRst Bit p0.6 ;IC卡复位信号线
ICScl Bit p0.5 ;IC卡时钟信号线
ICSda Bit P0.7 ;IC卡数据信号线
ICKey Bit P1.1 ;IC卡开关信号线
ICRam Data 70H ;IC卡数据缓冲区
ICAddr Data 71H ;IC卡命令地址字节
ICCtrl Data 72H ;IC卡命令控制字字节
ICData Data 73H ;IC卡命令数据字节
BitCnt Data 74H ;位数
ByteCnt Data 75H ;字节个数
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; IC卡起动条件
; 要写入IC卡的参数放在ACC中
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICStart: ;请参看复位与复位应答时序逻辑
SetB ICRST
Nop ;空操作次数可根据系统的时钟频
Nop ;率设定
SetB ICScl
Nop
Nop
Clr ICScl
Nop
Nop
Clr ICRst
LCall ICReadFirst ;读入第一个8位
LCall ICReadByte ;读入第二个8位
LCall ICReadByte
LCall ICReadByte
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; IC卡读字节过程
; 读入的数据存放在A中
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICReadFirst: ;接收复位后的第一个字节
Mov BitCnt,#8 ;接收数据位为8位
Clr ICRst ;接收时,ICRST线为低
Sjmp ICRead ;读取数据,加电复位后,
ICReadByte:
Mov BitCnt,#8 ;正常读取数据
Clr ICRst
ICReadLoop:
SetB ICScl
Nop
Nop
Clr ICScl
Nop
Nop
ICRead:
Mov C,ICSda
RRC A
DJNZ BitCnt, ICReadLoop
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; IC卡写字节过程
; 要写入IC卡的参数放在ACC中
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICWriteEightBit:
Mov BitCnt,#8 ;设置计数位数
SetB ICRst ;RST输出高
WriteLoop:
RRC A ;A右移出一位
Mov ICSda,C
Nop
Nop
SetB ICScl
Nop
Nop
Clr ICScl
DJNZ BitCnt,WriteLoop
SetB ICSDA
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 写IC卡命令
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICWriteAddress:
Mov A,ICCtrl ;取高字节
LCall ICWriteEightBit ;写控制字及高地址
Mov A,ICAddr ;取地址
LCAll ICWriteEightBit ;写地址
Mov A,ICData ;取数据
LCall ICWriteEightBit ;写数据
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 向IC卡内写指定地址内写一个字节
; 控制字及高地址放在R0中,低地址放在R1中,数据放在B中
; 要写入IC卡的参数放在ACC中
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICWriteByte:
LCall ICWriteAddress
Clr ICRst
Mov BitCnt,#203 ;IC卡写入数据后延续时钟
ICWriteLoop: ;最多203个时钟
JNB ICSda,ToReturn
SetB ICScl
Nop
Nop
Clr ICScl
Djnz BitCnt,ICWriteLoop
ToReturn:
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 从IC卡指定地址内读入N个字节
; 高地址及控制字放在R0中,低地址放在R1中
; 字节数放在ByteCnt中
; 读出的数据放在ICRam中
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICReadBytes:
LCall ICWriteAddress
Mov R0,#ICRam
ReadLoop:
LCall ICReadByte
Mov @R0,A
Inc R0
DJNZ ByteCnt,ReadLoop
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 向IC卡内写指定地址内写N个字节
; 数据缓冲区的地址放在ICData中,起始地址放在ICAddr中,
; 注意,此过程不要涉及到高位地址改变的写操作
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ICWriteBytes:
Mov R0,#ICRam ;读入ICRam内的数据
ICWriteLp:
Mov ICData,@R0 ;数据缓冲区地址加一
Inc R0
LCall ICWriteByte
INC ICAddr ;写入地址加一
Djnz ByteCnt,ICWriteLp
Ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; IC卡PSC校验
; 出口参数:A为零,正确,非零,不正确
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ICPSC: ;请参看PSC校验流程图
LCall ICStart
Mov ICAddr,#0FDH ;错误计数器
Mov ICCtrl,#011001110B ;读
Mov ByteCnt,#1 ;读入字数为1
LCall ICReadBytes ;读入数据(计数值)
CLR C ;清C,为写入数据作准备
RLC A ;错误计数器值清除一位未写位
Mov ICData,A ;放到B中传入
Mov ICAddr,#0FDH ;写错误计数器
Mov ICCtrl,#011110010B ;ID识别写错误计数器
LCall ICWriteByte ;写入错误计数值
Mov ICAddr,#0FEH ;第一位PSC
Mov ICCtrl,#011001101b ;PSC校验操作
Mov ICData,#0FFH ;密码 操作时请按实际PSC输入
LCall ICWriteByte ;写入IC卡
Inc ICAddr ;地址加1
LCall ICWriteByte ;写入IC卡
Mov ICData,#0FFH ;恢复错误数据计数器
Mov ICAddr,#0FDH
Mov ICCtrl,#011110011B
Mov ByteCnt,#1
LCall ICWriteByte ;写入错误计数值
Mov ICAddr,#0FDH ;错误计数器
Mov ICCtrl,#011001110B ;读
Mov ByteCnt,#1 ;读入字数为1
LCall ICReadBytes ;读入数据(计数值)
INC A ;退出条件A=0正确,否则不正确
Ret
.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -