www.pudn.com > FM1702SL_Source.rar > RFDriver.asm, change:2005-06-21,size:34138b
;============================================================================ ;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 btfsc status,c return bsf status,rp0 movlw Poll_1702SL_Timeout movwf Temp_2 Read_FIFOLength: movlw FIFOLength_Reg ;读取FIFOLength寄存器 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 ;判断FIFOLength寄存器是否已为0 btfss status,z goto Clear_FIFO_Err bcf status,rp0 bcf status,c return Clear_FIFO_Err: decfsz Temp_2,f goto Read_FIFOLength bcf status,rp0 bsf status,c return ;*********************************************************************** ;读FM1702SL的FIFO寄存器 ;Read_FIFO 读FIFO寄存器 ; 入口: ; N/A ; 出口: ; ReadLength 读得数据长度 ; Send_Buf 读出的数据置于发送,接收缓冲区中 ; c = 1: 读FIFO寄存器失败 ; c = 0: 读FIFO寄存器成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Loop_Count,SpiAddress ;*********************************************************************** Read_FIFO: bsf status,rp0 movlw FIFOLength_Reg ;读取FIFOLength寄存器 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 btfsc status,z goto Read_FIFO_Err movwf ReadLength movwf Loop_Count movlw FIFO_Reg movwf SpiAddress movlw Send_Buf movwf fsr bsf status,irp call SPIRead bcf status,irp return Read_FIFO_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;写FM1702SL的FIFO寄存器 ;Write_FIFO 写FIFO寄存器 ; 入口: ; Send_Length: 要写入的字节数 ; Send_Buf: 待发送数据应放在Send_Buf缓冲区中 ; irp: Ram首地址的Bank标识 ; 出口: ; c = 1: 写FIFO寄存器失败 ; c = 0: 写FIFO寄存器成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Loop_Count,SpiAddress ;*********************************************************************** Write_FIFO: bsf status,rp0 movlw FIFO_Reg movwf SpiAddress movf Send_Length,w btfsc status,z goto Write_FIFO_Empty movwf Loop_Count movlw Send_Buf movwf fsr bsf status,irp call SPIWrite bcf status,irp return Write_FIFO_Empty: bcf status,rp0 bcf status,c return ;*********************************************************************** ;发送接收FM1702SL数据 ;Command_Send 发送接收数据 ; 入口: ; Send_Length: 要写入的字节数 ; Send_Buf: 待发送数据应放在Send_Buf缓冲区中 ; comm_set: 命令操作码 ; 出口: ; c = 1: 命令发送失败 ; c = 0: 命令发送成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ;*********************************************************************** Command_Send: call Clear_FIFO ;清空FIFO寄存器 btfsc status,c return call Write_FIFO ;写FIFO寄存器 btfsc status,c return bsf status,rp0 movlw Command_Reg ;向command寄存器写控制命令码 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movf comm_set,w movwf indf call SPIWrite btfsc status,c return bsf status,rp0 movlw Poll_1702SL_Timeout ;检测命令是否被执行 movwf Temp_2 Read_Command_Loop: movlw Command_Reg 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 bcf status,rp0 btfsc status,z return bsf status,rp0 decfsz Temp_2,f goto Read_Command_Loop bcf status,rp0 bsf status,c return ;=============================================================================== ;FM1702SL对射频卡片的相关操作 ;=============================================================================== ;*********************************************************************** ;FM1702SL向空间发送request信号 ;Request 发送request信号 ; 入口: ; N/A ; 出口: ; c = 1: request命令执行失败 ; c = 0: request命令执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_Length,comm_set,Read_length ;*********************************************************************** Request: bsf status,rp0 movlw BitFraming_Reg ;写bitframing寄存器 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x07 movwf indf call SPIWrite btfsc status,c return 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 TxRx_Buf movwf fsr movf indf,w andlw 0xf7 movwf indf movlw Control_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count call SPIWrite btfsc status,c return bsf status,rp0 movlw ChannelRedundancy_Reg ;写ChannelRedundancy寄存器 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x03 movwf indf call SPIWrite btfsc status,c return bsf status,rp0 movlw Send_Buf ;将待发送数据写入FIFO中,并执行发送接收命令 movwf fsr bsf status,irp movlw 0x52 movwf indf bcf status,irp movlw 0x01 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return call Read_FIFO ;读出FIFO寄存器的内容 btfsc status,c return bsf status,rp0 movf ReadLength,w ;判断回读的应答数据长度为2否 sublw 0x02 btfss status,z goto Request_Err bsf status,rp1 ;判断回应的数据是否为04,00 movf Send_Buf,w bcf status,rp1 sublw 0x04 btfss status,z goto Request_Err bsf status,rp1 movf Send_Buf+1,w bcf status,rp1 btfss status,z goto Request_Err bcf status,rp0 bcf status,c return Request_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;FM1702SL向存在于其发射范围内的卡片发射GET_UID信号 ;Get_UID 发送GET_UID信号 ; 入口: ; N/A ; 出口: ; c = 1: GET_UID命令执行失败 ; c = 0: GET_UID命令执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_length,comm_set,Read_length,Card_UID ;*********************************************************************** Get_UID: bsf status,rp0 movlw ChannelRedundancy_Reg ;写ChannelRedundancy寄存器 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x03 movwf indf call SPIWrite btfsc status,c return bsf status,rp0 movlw Send_Buf ;将待发送数据写入FIFO中,并执行发送接收命令 movwf fsr bsf status,irp movlw 0x93 movwf indf incf fsr,f movlw 0x20 movwf indf bcf status,irp movlw 0x02 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return call Read_FIFO ;读出FIFO寄存器的内容 btfsc status,c return bsf status,rp0 movf ReadLength,w ;判断回读的应答数据长度为5否 sublw 0x05 btfss status,z goto Get_UID_Err bcf status,rp0 movlw Send_Buf ;保存得到的5位UID号 movwf temp0 movlw Card_UID movwf temp1 movlw .5 movwf temp2 bsf source_irp bcf destination_irp movlw high copydata movwf pclath call copydata movlw high Get_UID movwf pclath call Check_UID ;校验得到的5位UID是否正确 return Get_UID_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;对收到的UID号进行校验 ;Check_UID 校验UID ; 入口: ; N/A ; 出口: ; c = 1: UID校验错误 ; c = 0: UID校验成功 ;影响的寄存器: ; w,status,fsr,Temp2,Temp3 ;*********************************************************************** Check_UID: movlw Card_UID movwf fsr clrf Temp2 movlw .5 movwf Temp3 Check_UID_Loop: ;对5位UID号进行异或操作 movf indf,w xorwf Temp2,f incf fsr,f decfsz Temp3,f goto Check_UID_Loop movf Temp2,w btfss status,z goto Check_UID_Err bcf status,c return Check_UID_Err: bsf status,c return ;*********************************************************************** ;FM1702SL向存在于其发射范围内的卡片发射选择卡片信号 ;Select_Tag 发送Select_TAG信号 ; 入口: ; N/A ; 出口: ; c = 1: 选择卡片执行失败 ; c = 0: 选择卡片执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_length,comm_set,Read_length,Src,Dst,count ;*********************************************************************** Select_Tag: bsf status,rp0 movlw ChannelRedundancy_Reg ;写ChannelRedundancy寄存器 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x0f movwf indf call SPIWrite btfsc status,c return movlw Send_Buf ;将待发送数据写入FIFO中,并执行发送接收命令 movwf fsr bsf status,irp movlw 0x93 movwf indf incf fsr,f movlw 0x70 movwf indf bcf status,irp incf fsr,f movf fsr,w movwf temp1 movlw Card_UID movwf temp0 movlw .5 movwf temp2 bcf source_irp bsf destination_irp movlw high copydata movwf pclath call copydata movlw high Select_Tag movwf pclath bsf status,rp0 movlw 0x07 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return call Read_FIFO ;读出FIFO寄存器的内容 btfsc status,c return bsf status,rp0 movf ReadLength,w ;判断回读的应答数据长度为1否 sublw 0x01 btfss status,z goto Select_Tag_Err bsf status,rp1 movf Send_Buf,w ;判断回应的数据是否为08 bcf status,rp1 sublw 0x08 btfss status,z goto Select_Tag_Err bcf status,rp0 bcf status,c return Select_Tag_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;FM1702SL将密码装入EE中 ;Load_Key 发送Load_Key信号 ; 入口: ; Send_Buf 写入FM1702SL EE中的EE地址(2bytes)及密码(6bytes), ; EE地址低字节在前 ; 出口: ; c = 1: Load_Key失败操作 ; c = 0: Load_Key操作成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Src,Dst,count,Send_Length,comm_set ;*********************************************************************** Load_Key: movlw Send_Buf+02h ;密码搬运 movwf temp0 movlw Send_Buf+0ah movwf temp1 movlw .6 movwf temp2 bsf source_irp bsf destination_irp movlw high copydata movwf pclath call copydata movlw high Load_Key movwf pclath bsf status,rp0 bsf status,irp movlw Send_Buf+0ah ;计算出存放于EE中的密码 movwf Src movlw Send_Buf+02h movwf Dst movlw .6 movwf loop_count Key_Transfer: movf Src,w movwf fsr movf indf,w movwf Temp_5 incf Src,f comf Temp_5,w andlw 0xf0 movwf Temp_4 swapf Temp_5,w andlw 0x0f iorwf Temp_4,f comf Temp_5,w andlw 0x0f movwf Temp_3 swapf Temp_3,f movf Temp_5,w andlw 0x0f iorwf Temp_3,f movf Dst,w movwf fsr movf Temp_4,w movwf indf incf fsr,f incf Dst,f movf Temp_3,w movwf indf incf Dst,f decfsz loop_count,f goto Key_Transfer bcf status,irp movlw 0x0e ;将密码写入FM1702SL的EE中 movwf Send_Length movlw WriteEE movwf comm_set call command_send bsf status,rp0 movlw SecondaryStatus_Reg ;读取SecondaryStatus寄存器 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 ;判断LoadKey执行是否正确 andlw 0x40 btfsc status,z goto Load_Key_Err movlw Command_Reg ;向command寄存器写控制命令码 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x00 movwf indf call SPIWrite bcf status,c return Load_Key_Err: movlw Command_Reg ;向command寄存器写控制命令码 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x00 movwf indf call SPIWrite bsf status,c return ;*********************************************************************** ;FM1702SL将EE中的密码调入密码缓冲区中 ;Load_Key_EE 发送Load_Key_EE信号 ; 入口: ; Send_Buf 待装载密码的EE地址(2bytes),EE地址低字节在前 ; 出口: ; c = 1: 密码装载执行失败 ; c = 0: 密码装载执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_Length,comm_set,Src,Dst,count ;*********************************************************************** Load_Key_EE: bsf status,rp0 movlw 0x02 ;将待发送数据写入FIFO中 movwf Send_Length movlw LoadKeyE2 movwf comm_set call command_send btfsc status,c return bsf status,rp0 movlw ErrorFlag_Reg ;读取ErrorFlag寄存器 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 ;判断LoadKey执行是否正确 andlw 0x40 btfss status,z goto Load_Key_EE_err bcf status,rp0 bcf status,c return Load_Key_EE_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;FM1702SL向存在于其发射范围内的卡片发射认证信号 ;Authentication 发送Authentication信号 ; 入口: ; Block_num: 块号 ; 出口: ; c = 1: 三重认证执行失败 ; c = 0: 三重认证执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_Length,comm_set ;*********************************************************************** Authentication: ;写ChannelRedundancy寄存器 bsf status,rp0 movlw ChannelRedundancy_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x0f movwf indf call SPIWrite btfsc status,c return ; ;改写control寄存器 ; movlw Control_Reg ; movwf SpiAddress ; movlw 0x01 ; movwf Loop_Count ; movlw TxRx_Buf ; movwf fsr ; call SPIRead ; btfsc status,c ; return ; ; movlw TxRx_Buf ; movwf fsr ; movf indf,w ; andlw 0xf7 ; movwf indf ; movlw Control_Reg ; movwf SpiAddress ; movlw 0x01 ; movwf Loop_Count ; call SPIWrite ; btfsc status,c ; return ;将待发送数据写入FIFO中,并执行Authent1命令 bsf status,rp0 bsf status,rp1 movlw 0x60 movwf Send_Buf bcf status,rp1 movf Block_num,w bsf status,rp1 movwf Send_Buf+1 bcf status,rp1 bcf status,rp0 movlw Send_Buf+2 movwf temp1 movlw Card_UID movwf temp0 movlw .4 movwf temp2 bcf source_irp bsf destination_irp movlw high copydata movwf pclath call copydata movlw high Authentication movwf pclath bsf status,rp0 movlw 0x06 movwf Send_Length movlw Authent1 movwf comm_set call command_send btfsc status,c return ;读取ErrorFlag寄存器 bsf status,rp0 movlw ErrorFlag_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr call SPIRead btfsc status,c return ;判断Authent1执行是否正确 bsf status,rp0 movf TxRx_Buf,w andlw 0x0e btfss status,z goto Authentication_Err ;执行Authent2命令 clrf Send_Length movlw Authent2 movwf comm_set call command_send btfsc status,c return ;读取ErrorFlag寄存器 bsf status,rp0 movlw ErrorFlag_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr call SPIRead btfsc status,c return ;判断Authent2执行是否正确 bsf status,rp0 movf TxRx_Buf,w andlw 0x0e btfss status,z goto Authentication_Err ;读取Control寄存器 bsf status,rp0 movlw Control_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr call SPIRead btfsc status,c return ;判断Authent2认证通过否 bsf status,rp0 movf TxRx_Buf,w andlw 0x08 btfsc status,z goto Authentication_Err bcf status,rp0 bcf status,c return Authentication_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;FM1702SL向存在于其发射范围内的卡片发射读块信号 ;Read_Block 发送Read_Block信号 ; 入口: ; Block_num: 块号 ; 出口: ; Send_Buf 读出数据置于Send_Buf中 ; c = 1: 读块操作执行失败 ; c = 0: 读块操作执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_Length,comm_set ;*********************************************************************** Read_Block: ;写ChannelRedundancy寄存器 bsf status,rp0 movlw ChannelRedundancy_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x0f movwf indf call SPIWrite btfsc status,c return ;为不影响Send_Buf缓冲区,做如下处理 ;movf Send_Buf,w ;movwf Send_Buf+10h ;movf Send_Buf+1,w ;movwf Send_Buf+11h ;将待发送数据写入FIFO中,并执行发送接收命令 bsf status,rp0 bsf status,rp1 movlw 0x30 movwf Send_Buf bcf status,rp1 movf Block_num,w bsf status,rp1 movwf Send_Buf+1 bcf status,rp1 movlw 0x02 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return ;将Send_Buf缓冲区复原 ;movf Send_Buf+10h,w ;movwf Send_Buf ;movf Send_Buf+11h,w ;movwf Send_Buf+1 ;读取ErrorFlag寄存器 bsf status,rp0 movlw ErrorFlag_Reg movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr call SPIRead btfsc status,c return ;判断ReadBlock执行是否正确 bsf status,rp0 movf TxRx_Buf,w andlw 0x0e btfss status,z goto Read_Block_Err ;读出FIFO寄存器的内容 call Read_FIFO btfsc status,c return ;判断回读的应答数据位数为16否 bsf status,rp0 movf ReadLength,w sublw 0x10 btfss status,z goto Read_Block_Err bcf status,rp0 bcf status,c return Read_Block_Err: bcf status,rp0 bsf status,c return ;*********************************************************************** ;FM1702SL向存在于其发射范围内的卡片发射写块信号 ;Write_Block 发送Write_Block信号 ; 入口: ; Send_Buf 待写入卡片Block中的16bytes数据 ; Block_num: 块号 ; 出口: ; c = 1: 写块操作执行失败 ; c = 0: 写块操作执行成功 ;影响的寄存器: ; w,status,fsr,Temp5,Temp4,Temp3,Temp2,Loop_Count,SpiAddress ; Send_Length,comm_set ;*********************************************************************** Write_Block: bsf status,rp0 movlw ChannelRedundancy_Reg ;写ChannelRedundancy寄存器 movwf SpiAddress movlw 0x01 movwf Loop_Count movlw TxRx_Buf movwf fsr movlw 0x07 movwf indf call SPIWrite btfsc status,c return bsf status,rp0 bsf status,rp1 movf Send_Buf,w movwf Send_Buf+10h movf Send_Buf+1,w movwf Send_Buf+11h movlw 0xa0 ;将待发送数据写入FIFO中,并执行发送接收命令 movwf Send_Buf bcf status,rp1 movf Block_num,w bsf status,rp1 movwf Send_Buf+1 bcf status,rp1 movlw 0x02 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return call Read_FIFO ;读出FIFO寄存器的内容 btfsc status,c return bsf status,rp0 movf ReadLength,w ;判断回读的应答数据长度为1否 sublw 0x01 btfss status,z goto Write_Block_Err bsf status,rp1 movf Send_Buf,w ;判断回应的数据是否为0a bcf status,rp1 sublw 0x0a btfss status,z goto Write_Block_Err bsf status,rp1 movf Send_Buf+10h,w movwf Send_Buf movf Send_Buf+11h,w movwf Send_Buf+1 bcf status,rp1 movlw 0x10 ;将待发送数据写入FIFO中,并执行发送接收命令 movwf Send_Length movlw Transceive movwf comm_set call command_send btfsc status,c return call Read_FIFO ;读出FIFO寄存器的内容 btfsc status,c return bsf status,rp0 movf ReadLength,w ;判断回读的应答数据长度为1否 sublw 0x01 btfss status,z goto Write_Block_Err bsf status,rp1 movf Send_Buf,w ;判断回应的数据是否为0a bcf status,rp1 sublw 0x0a btfss status,z goto Write_Block_Err bcf status,rp0 bcf status,c return Write_Block_Err: bcf status,rp0 bsf status,c return ;==================================================================== ;射频卡操作 ;入口参数:N/A ;出口参数:c=1 射频卡操作失败 ; c=0 射频卡操作正常 ;==================================================================== RF_Operation: ;对FM1702SL进行复位操作 bcf FM1702SL_RST movlw 0xff movwf temp1 movlw 0x10 movwf temp2 Rst_Loop: nop nop nop nop decfsz temp1,f goto Rst_Loop movlw 0xff movwf temp1 decfsz temp2,f goto Rst_Loop ;初始化SPI接口及1702SL call SPI_Init call FM1702SL_Init ; bsf status,rp0 ; bsf status,rp1 ; movlw 0x80 ; movwf Send_Buf ; clrf Send_Buf+.1 ; movlw 0xff ; movwf Send_Buf+.2 ; movwf Send_Buf+.3 ; movwf Send_Buf+.4 ; movwf Send_Buf+.5 ; movwf Send_Buf+.6 ; movwf Send_Buf+.7 ; bcf status,rp1 ; bcf status,rp0 ; call Load_Key ;进行Request操作 call Request ;进行GET_UID操作 call Get_UID ;进行Select_Tag操作 call Select_Tag ;进行Load_Key_EE操作,验证密码在FM1702SL EE中的0x0080地址起 bsf status,rp0 bsf status,rp1 movlw 0x80 movwf Send_Buf clrf Send_Buf + .1 bcf status,rp1 call Load_Key_EE ;进行Authentication操作 bsf status,rp0 movlw 0x07 movwf Block_num call Authentication ;进行Write_Block操作 bsf status,rp0 bsf status,rp1 movlw 0x11 movwf Send_Buf movlw 0x22 movwf Send_Buf + .1 movlw 0x33 movwf Send_Buf + .2 movlw 0x44 movwf Send_Buf + .3 movlw 0x55 movwf Send_Buf + .4 movlw 0x66 movwf Send_Buf + .5 movlw 0x77 movwf Send_Buf + .6 movlw 0x88 movwf Send_Buf + .7 movlw 0x99 movwf Send_Buf + .8 movlw 0xaa movwf Send_Buf + .9 movlw 0xbb movwf Send_Buf + .10 movlw 0xcc movwf Send_Buf + .11 movlw 0xdd movwf Send_Buf + .12 movlw 0xee movwf Send_Buf + .13 movlw 0xff movwf Send_Buf + .14 movlw 0x16 movwf Send_Buf + .15 bcf status,rp1 bcf status,rp0 bsf status,rp0 movlw 0x04 movwf Block_num call Write_Block ;进行Read_Block操作 bsf status,rp0 movlw 0x04 movwf Block_num call Read_Block bsf FM1702SL_RST return End