⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iccardv17.inc

📁 本程序为某企业的税控机固件程序.基于东芝TMP93CS41 16位单片机编写,符合国家标准.该程序已经经过多次长期调试.
💻 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 + -