📄 iccardv17.inc
字号:
;***********************************************************
;程序名称: SSF1101卡操作子程序
;程序开发: 前锋集团技术中心
;编写时间: 2004年7月13日
;软件环境: 供税控收款机QF560型的上层C语言使用
;硬件环境: QF560硬件版本V2.15,明华公司SSF1101卡片
;MCU: TOSHIBA TMP93CS41@max 16M/1
;程序版本: V1.70
;最后修订时间: 2004年12月4日
;修订部分说明:
;V1.5: 补充复位流程,精简了部分指令
;V1.7: 更正了新,老卡可能读写错误的问题,修正了读取的位置
;----------------------------------------------------------
;汇编词典:
;w : 数据长度计数器
;xwa : 计算缓冲区指针的临时寄存器
;b : 发送子函数使用的计数器
;c : 时钟产生程序使用的参数寄存器
;e : 发送和接收函数使用的数据传送寄存器
;xhl : 指向缓冲区的指针
;----------------------------------------------------------
;需要的变量定义:
padr equ 0x100 ;当前操作的页面地址,长度为12位
badr equ 0x102 ;当前操作的页面内偏移地址,长度2字节
size equ 0x104 ;当前操作的数据的长度
sf_offset equ 0x10D ;SSF1101内存空间存储偏移量,用于给出缓冲区偏移地址
sf_data equ 0x145 ;用于和上层C语言接口的缓冲区首地址
sf_error equ 0x144 ;SSF1101硬件错误代码
;----------------------------------------------------------
;全局函数声明
PUBLIC __ICrd ;ssf1101卡片的读操作
PUBLIC __ICwr
;----------------------------------------------------------
;定义伪指令,当硬件结构改变时修改本位置上的指令即可完成程序修改
;----------------------------------------------------------
;SSF1101卡的user电源控制被安排在端口sfpow_port的sfpow_bit位上
sfpow_port equ P3 ;---sSF1101 card POWer control PORT
sfpow_bit equ 2 ;---sSF1101 card POWer control BIT
;----------------------------------------------------------
;SSF1101卡的MOSI口被安排在端口sfsi_port的sfsi_bit位上
sfmosi_port equ P6 ;---sSF1101 card MOSI PORT
sfmosi_bit equ 1 ;---sSF1101 card MOSI BIT
;----------------------------------------------------------
;SSF1101卡的MISO口被安排在端口sfso_port的sfso_bit位上
sfmiso_port equ P6 ;---sSF1101 card MISO PORT
sfmiso_bit equ 0 ;---sSF1101 card MISO BIT
;----------------------------------------------------------
;SSF1101卡的时钟CLK口被安排在端口sfclk_port的sfclk_bit位上
sfclk_port equ P6 ;---sSF1101 card CLK PORT
sfclk_bit equ 2 ;---sSF1101 card CLK BIT
;----------------------------------------------------------
;SSF1101卡的复位Reset口被安排在端口sfclk_port的sfclk_bit位上
sfrst_port equ P6 ;---sSF1101 card ReSeT PORT
sfrst_bit equ 3 ;---sSF1101 card ReSeT BIT
;----------------------------------------------------------
;SSF1101卡的片选CS口被安排在端口sfcs_port的sfcs_bit位上
sfcs_port equ P8 ;---sSF1101 card CS PORT
sfcs_bit equ 5 ;---sSF1101 card CS BIT
;----------------------------------------------------------
;SSF1101卡端口方向控制字的内存映像被放置在
;sf_cr_ram equ PACR_RAM
;----------------------------------------------------------
;SSF1101卡端口的方向控制字为 ;---Test Only
sf_cr equ PACR
;----------------------------------------------------------
;!!!!注意!!!!本程序不负责开关IC卡的电源,交给上层程序处理,在上电后
;应等待600mS,待复位稳定后再对卡进行操作!!!!
;********************Main Of SSF1101***********************
__ICrd: ;SSF1101读
call sf_reset ;复位
res sfcs_bit,(sfcs_port) ;CS=0
ld e,0x1C ;直接读命令,器件地址1100
call trans
ld e,(padr+1) ;取页地址高位的低4位发送
rlc 4,e
call trans_half
ld e,(padr) ;取页地址低位发送
call trans
ld e,(badr+1) ;取页内地址高位的低4位发送
rlc 4,e
call trans_half
ld e,(badr) ;取页内地址低位发送
call trans
ld c,0x02
call sf_pulse ;凑够34个时钟脉冲,第35个脉冲由接收函数产生
ld xhl,sf_data ;指针初始化
ld xwa,0x000000
ld a,(sf_offset) ;缓冲区中的存储偏移量
add xhl,xwa ;计算指针位置
ld w,(size) ;数据长度计数器
ssf_r_loop: ;SSF1101 card Read Loop
call sf_receive
ld (xhl+),e ;将接收到的数据送缓冲
djnz w,ssf_r_loop
sf_fini:
set sfcs_bit,(sfcs_port) ;CS=1
;ld (sf_cr_ram),0x60 ;操作完成,刷新口线方向字
;ld (sf_cr),(sf_cr_ram)
ld (sf_cr),0x60
ret
;----------------------------------------------------------
__ICwr: ;SSF1101写
call sf_reset ;复位
res sfcs_bit,(sfcs_port) ;CS=0
ld d,0x00 ;装载时间保护计数器动作时间29ms
ld (sf_error),0xC1 ;默认设置为超时跳出
sf_wini_busy: ;---SSF1101卡写操作前的忙标检测,每次检测时间为921ST,115uS
ld e,0x0C ;读状态寄存器命令,器件地址1100
call trans
ld c,26
call sf_pulse ;凑够34个时钟脉冲,第35个脉冲由接收函数产生
call sf_receive ;读入状态字
and e,0x80 ;检测忙标位
jr z,sf_pld ;忙标为0,开始写操作
djnz d,sf_wini_busy
jp sf_fini ;超时跳出
sf_pld: ;---SSF1101卡页面到缓冲区1加载操作
set sfcs_bit,(sfcs_port) ;CS=1
nop
res sfcs_bit,(sfcs_port) ;CS=0
ld e,0xCC ;读页面到缓冲区1命令
call trans
ld e,(padr+1) ;取页地址高位的低4位发送
rlc 4,e
call trans_half
ld e,(padr) ;取页地址低位发送
call trans
ld c,15 ;凑够35个时钟脉冲
call sf_pulse
set sfcs_bit,(sfcs_port) ;CS=1
nop
res sfcs_bit,(sfcs_port) ;CS=0
sf_pld_busy: ;---SSF1101卡页面到缓冲区1装载忙标检测
ld e,0x0C ;读状态寄存器命令,器件地址1100
call trans
ld c,26
call sf_pulse ;凑够34个时钟脉冲,第35个脉冲由接收函数产生
call sf_receive ;读入状态字
and e,0x80 ;检测忙标位
jr z,sf_wr_load ;忙标为0,开始写操作
djnz d,sf_pld_busy
jp sf_fini ;超时跳出
sf_wr_load: ;---SSF110卡缓冲区1写入程序
set sfcs_bit,(sfcs_port) ;CS=1
nop
res sfcs_bit,(sfcs_port) ;CS=0
ld e,0x6C ;写缓冲区1命令,器件地址1100
call trans
ld c,12
call sf_pulse ;本命令没有页面地址信息,但要发送12个脉冲
ld e,(badr+1)
call trans_half ;发送页面内偏移地址高位字节的低4位
ld e,(badr)
call trans ;发送页面内偏移地址低位字节
ld xhl,sf_data ;指针初始化
ld xwa,0x000000
ld a,(sf_offset) ;缓冲区中的存储偏移量
add xhl,xwa ;计算指针位置
ld w,(size) ;初始化长度计数器
sf_wr_loop: ;---SSF1101卡缓冲区1写入循环
ld e,(xhl+) ;载入要发送的数据
call trans ;发送数据到总线
djnz w,sf_wr_loop
ld c,3
call sf_pulse ;最后一个数据输出后要求额外的3-7个脉冲
set sfcs_bit,(sfcs_port) ;CS=1
nop
res sfcs_bit,(sfcs_port) ;CS=0
sf_wr_send: ;---SSF1101缓冲区1写入到页面
ld e,0xAC ;用内擦除周期,从缓冲区1写入页面命令
call trans
ld e,(padr+1) ;取页地址高位的低4位发送
rlc 4,e
call trans_half
ld e,(padr) ;取页地址低位发送
call trans
ld c,15 ;凑够35个时钟脉冲
call sf_pulse
set sfcs_bit,(sfcs_port) ;CS=1
;ld (sf_cr_ram),0x60 ;操作完成,刷新口线方向字
;ld (sf_cr),(sf_cr_ram)
ld (sf_cr),0x60
ld (sf_error),0xC0 ;页面写任务完成,置硬件DEBUG代码为C0
ret
;*****************SSF1101卡读写子程序***********************
sf_reset: ;---SSF1101 card reset
ld (sf_cr),0xAE
set sfcs_bit,(sfcs_port) ;CS=1
res sfclk_bit,(sfclk_port) ;CLK=0
set sfrst_bit,(sfrst_port) ;RST=1
res sfcs_bit,(sfcs_port) ;CS=0
res sfrst_bit,(sfrst_port) ;RST=0
ld e,0x07
delay_rest:
ldcf 1,(PA) ;复位延迟用,无实际意义
djnz e,delay_rest
set sfrst_bit,(sfrst_port) ;RST=1
set sfcs_bit,(sfcs_port) ;CS=1
nop
nop
ret
;----------------------------------------------------------
trans_half: ;发送函数,发送e中的高半字节到总线
ld b,4
jp next_trans
trans: ;发送函数,发送e中的一个字节到总线
ld b,8 ;计数器
next_trans:
rlc 1,e ;发送时高位在前
stcf sfmosi_bit,(sfmosi_port)
set sfclk_bit,(sfclk_port) ;CLK=1
res sfclk_bit,(sfclk_port) ;CLK=0
djnz b,next_trans
ret
;----------------------------------------------------------
sf_receive: ;接收函数,从总线上接收一个字节到a寄存器
ld b,8
sf_r_b_l: ;SSF1101 card Receive Byte Loop
set sfclk_bit,(sfclk_port) ;产生第35个脉冲,以便器件将数据发送到线上
res sfclk_bit,(sfclk_port)
ldcf sfmiso_bit,(sfmiso_port)
rl 1,e
djnz b,sf_r_b_l
ret
;----------------------------------------------------------
sf_pulse: ;时钟产生,在总线上产生时钟脉冲,个数由C寄存器传送
set sfclk_bit,(sfclk_port) ;CLK=1
res sfclk_bit,(sfclk_port) ;CLK=0
djnz c,sf_pulse
ret
;**********************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -