📄 rfdriver.asm
字号:
;============================================================================
;Ver: RFDriver2005-2-3
;针对FM1702SL芯片的底层驱动程序
;作者:梁磊
;日期: 二零零五年二月三日
;============================================================================
;驱动程序描述:
; FM1702SL射频芯片对外接口为SPI总线方式,对FM1702的操作实际上就是通过SPI总线
;对FM1702SL内部的相关寄存器进行读写操作,从而实现射频读/写卡功能。本驱动程序基于
;FM2306A编写(兼容PIC指令集的其他MCU也同样试用),通过IO口软件模拟SPI总线时序。本
;驱动程序从底到高可以分为三层,依次为:
; 1.SPI总线驱动程序
; 2.针对FM1702SL相关寄存器的读/写寄存器操作
; 3.利用FM1702SL对射频卡片的相关操作
;在使用时需要调用的函数
;上电初始化后,对FM1702SL进行一些初始化的操作,需要调用如下函数(按照先后顺序):
; 1.SPI_Init()
; 2.FM1702SL_Init()
;对射频卡片一次完整的操作,按照先后顺序需要调用如下一些函数:
; 1.Request()
; 2.Get_UID()
; 3.Select_Tag()
; 4.Load_Key_EE()
; 5.Authentication()
; 6.Read_Block()/Write_Block()
;注: 1.由于射频读卡芯片功耗较大,在不做射频处理时,尽量让射频芯片处于休眠模式,
;以降低系统的功耗。为了实现这一点,可以在对射频卡操作完毕以后,调用FM1702_Standby()。
;但要注意,在每次对卡片操作之前,要调用FM1702_Wakeup()以唤醒射频读卡芯片。
; 2.对于初次使用FM1702SL射频芯片,必须要调用Load_Key()函数将认证时使用的
;认证密码装入FM1702SL的EEPROM中。
include "p16c77.inc"
include "RFMeter.inc"
org 0000h
goto main
main:
call initial
bsf pclath,3
bsf pclath,4
call rf_operation
bcf pclath,4
bcf pclath,3
btfsc status,c
goto last_loop
;request成功,蜂鸣器短鸣一声
bsf Beep_Cnt
last_loop:
movlw 0xff
movwf temp1
movlw 0x90
movwf temp2
Delay_Loop:
nop
nop
nop
nop
decfsz temp1,f
goto Delay_Loop
movlw 0xff
movwf temp1
decfsz temp2
goto Delay_Loop
bcf Beep_Cnt
goto main
initial:
clrf STATUS
clrf INTCON
;bank1的操作
bsf STATUS,RP0 ;初始化I/O
movlw 31H ;PORTA口初始化(04)
movwf TRISA
movlw 07h ;PortA定义为全数字口
movwf ADCON1
movlw 030H ;PORTB口初始化
movwf TRISB
;movlw 00H ;外部地址总线(全部输出)
clrf TRISC
;movlw 00H ;外部数据总线的双向数据线(一般状态下是输出,只有读数据时是输入状态)
clrf TRISD
clrf TRISE ;端口E的方向定义为输出(产生控制信息)
;movlw 00H ;OPTION初始化
clrf OPTION_REG ;PORTB口弱上拉,TMR0内部时钟,预分频器给TMR0,分频值1:2
bcf STATUS,RP0 ;bank0
;bank0的操作
movlw 0FFH
movwf PORTA ;PORTA口初始状态
bcf SPIMasterSCLK ;
bcf SPIMasterSDO ;
bsf SPIMasterCS ;
bsf FM1702SL_RST
bcf Beep_Cnt
return
;============================================================================
;子程序文件名:copydata
;实现功能:ram中拷贝块数据
;功能:拷贝数据从temp0 到 temp1,长度为temp2
;入口参数: temp0---------------源ram地址指针,
; temp1---------------目的ram地址指针,
; temp2---------------长度,
; source_irp
; destination_irp
;返回参数 :无
; irp=0
;影响的寄存器 :temp3
;执行时间 :19 *lenμs
;堆栈级数 :0
;说明 :temp0 --> temp1(len=temp2)
;=============================================================================
copydata: ;拷贝数据
movf temp2,w
btfsc status,z
goto copydata_out ;如果拷贝0个那么立刻返回
sublw 20h
btfss status,c
goto copydata_out ;如果拷贝大于32字节那么立刻返回
copydata_next: ;继续拷贝下一个字节
movf temp0,w
movwf fsr
bcf status,irp
btfsc source_irp ;源irp
bsf status,irp
movf indf,w ;将ram中数据存到tempf
movwf temp3
movf temp1,w
movwf fsr
bcf status,irp
btfsc destination_irp
bsf status,irp
movf temp3,w
movwf indf
incf temp0,f
incf temp1,f
decfsz temp2,f
goto copydata_next
bcf status,irp
bcf logic_status
return
copydata_out:
bcf status,irp
bsf logic_status
return
org 0x0800
org 0x1000
org 1800h
;============================================================================
;SPI总线驱动程序
;============================================================================
;***********************************************************************
;SPI写入程序
;SPIWrite 把缓冲区中的数据写入到FM1702SL中
; 入口:
; SpiAddress: 要写到FM1702SL内的寄存器地址[0x01~0x3f]
; Loop_Count: 要写入的字节数
; fsr: 要写入的数据在Ram中的首地址
; 出口:
; c = 1: SPI写操作失败
; c = 0: SPI 写操作成功
;影响的寄存器:
; w,status,fsr,Temp5,Temp4,Loop_Count
;***********************************************************************
SPIWrite:
bsf status,rp0
movlw 0xc0
andwf SpiAddress,w
btfss status,z
goto SPIWriteAddressError
rlf SpiAddress,f
movlw 0x7e
andwf SpiAddress,f ;最高比特为"0"表示写操作
bcf status,rp0
bcf SPIMasterCS ;CS有效
bsf status,rp0
movf SPIAddress,w
movwf Temp_4
movlw .8
movwf Temp_5
SPICommunicationWriteForWriteLp:
bcf status,rp0
bcf SPIMasterSDO
bsf status,rp0
rlf Temp_4,f
bcf status,rp0
btfsc status,c
bsf SPIMasterSDO
bsf SPIMasterSCLK
nop
bcf SPIMasterSCLK
bsf status,rp0
decfsz Temp_5,f
goto SPICommunicationWriteForWriteLp
goto $ + .1
goto $ + .1
SPIWriteLoop:
movf indf,w
movwf Temp_4
movlw .8
movwf Temp_5
SPIWriteByteWriteLoop:
bcf status,rp0
bcf SPIMasterSDO
bsf status,rp0
rlf Temp_4,f
bcf status,rp0
btfsc status,c
bsf SPIMasterSDO
bsf SPIMasterSCLK
nop
bcf SPIMasterSCLK
bsf status,rp0
decfsz Temp_5,f
goto SPIWriteByteWriteLoop
incf fsr,f
decfsz Loop_Count,f
goto SPIWriteLoop
bcf status,rp0
bsf SPIMasterCS ;CS无效
bcf status,c
return
SPIWriteAddressError:
bcf status,rp0
bsf status,c
return
;***********************************************************************
;SPI读取程序
;SPIRead 读取FM1702SL相应寄存器的内容到缓冲区中
; 入口:
; SpiAddress: 要读的FM1702SL内的寄存器地址[0x01~0x3f]
; Loop_Count: 要读出的字节数
; fsr: 读出的数据放在Ram中的首地址
; 出口:
; c = 1: SPI读操作失败
; c = 0: SPI读操作成功
;影响的寄存器:
; w,status,fsr,Temp5,Temp4,Temp3,Loop_Count
;***********************************************************************
SPIRead:
bsf status,rp0
movlw 0xc0
andwf SpiAddress,w
btfss status,z
goto SPIReadAddressError
rlf SpiAddress,f
movlw 0x80 ;最高比特为"1"表示读操作
iorwf SpiAddress,f
movlw 0xfe
andwf SpiAddress,f
bcf status,rp0
bcf SPIMasterCS ;CS有效
bsf status,rp0
movf SPIAddress,w
movwf Temp_4
movlw .8
movwf Temp_5
SPICommunicationWriteForReadLp:
bcf status,rp0
bcf SPIMasterSDO
bsf status,rp0
rlf Temp_4,f
bcf status,rp0
btfsc status,c
bsf SPIMasterSDO
bsf SPIMasterSCLK
nop
bcf SPIMasterSCLK
bsf status,rp0
decfsz Temp_5,f
goto SPICommunicationWriteForReadLp
goto $ + .1
goto $ + .1
goto $ + .1
movlw 0x7f
andwf SpiAddress,f
SPIReadLoop:
movf SpiAddress,w
movwf Temp_3
decfsz Loop_Count,f
goto SPINormalRead
clrf Temp_3
SPINormalRead:
movlw .8
movwf Temp_5
clrf Temp_4
SPIReadByteLoop:
bcf status,rp0
bcf SPIMasterSDO
bsf status,rp0
rlf Temp_3
bcf status,rp0
btfsc status,c
bsf SPIMasterSDO
bsf SPIMasterSCLK
bcf status,c
btfsc SPIMasterSDI
bsf status,c
bsf status,rp0
rlf Temp_4,f
bcf status,rp0
bcf SPIMasterSCLK
bsf status,rp0
decfsz Temp_5,f
goto SPIReadByteLoop
movf Temp_4,w
movwf indf
incf fsr,f
incf Loop_Count,f
decfsz Loop_Count,f
goto SPIReadLoop
bcf status,rp0
bsf SPIMasterCS ;CS无效
bcf status,c
return
SPIReadAddressError:
bcf status,rp0
bsf status,c
return
;======================================================================
;FM1702SL相关寄存器的读/写寄存器操作
;======================================================================
;***********************************************************************
;SPI接口初始化
;SPI_Init 初始化FM1702SL的SPI接口
; 入口:
; N/A
; 出口:
; c = 1: 初始化SPI接口失败
; c = 0: 初始化SPI接口成功
;影响的寄存器:
; w,status,fsr,Temp5,Temp4,Temp3,Loop_Count,SpiAddress
;***********************************************************************
SPI_Init:
bsf status,rp0
movlw Command_Reg ;判断Command寄存器值是否为0x00
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
call SPIRead
btfsc status,c
return
bsf status,rp0
movf TxRx_Buf,w
btfss status,z
goto SPI_Init_Err
movlw Page_Reg ;往Page寄存器中写入0x80
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x80
movwf indf
call SPIWrite
btfsc status,c
return
bsf status,rp0
movlw Command_Reg ;判断Command寄存器值是否为0x00
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
call SPIRead
btfsc status,c
return
bsf status,rp0
movf TxRx_Buf,w
btfss status,z
goto SPI_Init_Err
movlw Page_Reg ;往Page寄存器中写入0x00
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
clrf indf
call SPIWrite
btfss status,c
return
SPI_Init_Err:
bcf status,rp0
bsf status,c
return
;***********************************************************************
;FM1702SL初始化
;FM1702SL_Init 初始化FM1702SL各相关寄存器
; 入口:
; N/A
; 出口:
; c = 1: 初始化FM1702SL各寄存器失败
; c = 0: 初始化FM1702SL各寄存器成功
;影响的寄存器:
; w,status,fsr,Temp5,Temp4,Temp3,Loop_Count,SpiAddress
;***********************************************************************
FM1702SL_Init:
bsf status,rp0
movlw InterruptEn_Reg ;禁止所有中断
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x7f
movwf indf
call SPIWrite
btfsc status,c
return
bsf status,rp0
movlw InterruptRq_Reg ;中断标识清零
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x7f
movwf indf
call SPIWrite
btfsc status,c
return
bsf status,rp0
movlw TxControl_Reg ;设置发射控制寄存器
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x5B
movwf indf
call SPIWrite
btfsc status,c
return
bsf status,rp0
movlw RxControl2_Reg ;设置接收控制寄存器
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x01
movwf indf
call SPIWrite
bsf status,rp0
movlw RxWait_Reg ;设置接收延时控制寄存器
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movlw 0x07
movwf indf
call SPIWrite
return
;***********************************************************************
;清空FM1702SL的FIFO寄存器
;Clear_FIFO 清空FIFO寄存器
; 入口:
; N/A
; 出口:
; c = 1: FIFO寄存器清空失败
; c = 0: FIFO寄存器清空成功
;影响的寄存器:
; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress
;***********************************************************************
Clear_FIFO:
bsf status,rp0
movlw Control_Reg ;读取Control寄存器
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
call SPIRead
btfsc status,c
return
bsf status,rp0
movlw Control_Reg ;设置Control寄存器
movwf SpiAddress
movlw 0x01
movwf Loop_Count
movlw TxRx_Buf
movwf fsr
movf indf,w
iorlw 0x01
movwf indf
call SPIWrite
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -