VFP reads and writes NFC tag Ntag card

The reader used in this example: Android Linux RFID reader NFC card issuer WEB programmable NDEF text/smart poster/-Taobao.com (taobao.com) 

        The NTAG21x series is  the second generation of NFC tag IC products released by NXP Semiconductors. The new NTAG21x series not only improves the radio frequency performance, but also has a memory capacity ranging from 48 to 888 bytes. In addition , The series also offers several new features such as UID ASCII mirroring, NFC counter, integrated original signature and password protection. Customers need products to support multiple applications, fast serialization, smaller size, and easy product verification. The above characteristics fully meet the above needs, so they can be widely deployed in publishing, retail, advertising, consumer electronics, gaming, and smartphone applications.

        There are four products under the NTAG21x series: NTAG210, NTAG213, NTAG215 and NTAG216, which will respectively provide 48, 144, 504 and 888 bytes of user memory , corresponding to the maximum amount of information that can be stored.

 

Declare the function: 

set proc to funprogram

declare integer pcdbeep in OUR_MIFARE.dll integer xms                                     &&让设备发出声响
declare integer pcdgetdevicenumber in OUR_MIFARE.dll string @pdevicenumber                &&读取设备编号
declare integer piccrequest_ul in OUR_MIFARE.dll string @mypiccserial                     &&寻卡选卡激活卡
declare integer piccread_ul in OUR_MIFARE.dll integer blockaddr,string @mypiccdata        &&读块 
declare integer piccwrite_ul in OUR_MIFARE.dll integer blockaddr,string @mypiccdata       &&写块
declare integer piccauthkey_ntag in OUR_MIFARE.dll string @picckey,string @piccntagpack   &&NTAG21x密码认证
declare integer piccgetversion_ntag in OUR_MIFARE.dll string @piccversiondata             &&读取卡版本信息 
declare integer piccreadsig_ntag in OUR_MIFARE.dll string @piccversiondata                &&读取卡的签字信息 
declare integer piccreadcnt_ntag in OUR_MIFARE.dll string @picccntdata                    &&读取卡的单向操作计数器(操作流水号)
declare integer picclock_ntag in OUR_MIFARE.dll integer locktype,string @serial           &&锁定页数据
declare integer piccinit_ntag in OUR_MIFARE.dll integer ctrlword,string @serial,string @picckey,string @piccdata           &&初始化卡
declare integer piccreadex_ntag in OUR_MIFARE.dll integer ctrlword,string @serial,string @picckey,integer blockaddr,integer blocksize1,string @piccdata           &&轻松读卡
declare integer piccwriteex_ntag in OUR_MIFARE.dll integer ctrlword,string @serial,string @picckey,integer blockaddr,integer blocksize1,string @piccdata          &&轻松写卡

thisform.pagF1.page1.text3.Value="00000000" 
thisform.pagF1.page1.text6.Value="12345678" 

thisform.pagF1.page2.combo1.AddItem ("开启密码保护功能")
thisform.pagF1.page2.combo1.AddItem ("取消密码保护功能")
thisform.pagF1.page2.combo1.ListIndex =1

thisform.pagF1.page2.text1.Value="12345678" 
thisform.pagF1.page2.text2.Value=30
thisform.pagF1.page2.text3.Value=0
thisform.pagF1.page2.text5.Value="12345678" 
thisform.pagF1.page2.text6.Value="12345678" 
thisform.pagF1.page2.text7.Value=30
thisform.pagF1.page2.text8.Value=10

 Easy card reading operation:

mypiccserial=spac(7)   &&返回7字节卡序列号
mypicckey=SPACE(4)     &&卡认证密码
mypiccdata=SPACE(48)   &&读卡的数据缓冲

IF thisform.pagF1.page2.check3.Value >0
	IF LEN(ALLTRIM(thisform.pagF1.page2.text5.Value))<>8
		= MESSAGEBOX('   卡密码必须为8个字符!',16,'提示:')
		thisform.pagF1.page2.text5.SetFocus 
		RETURN		
	ENDIF
	
	Pas1str=ALLTRIM(thisform.pagF1.page2.text5.Value)
	mypicckey=""
    FOR i=1 TO 4
        mypicckey=mypicckey+CHR(HexToDec(SUBSTR(Pas1str,i*2-1,2)+"00"))        
    NEXT
    myctrlword=16      &&需要密码
ELSE
    mypicckey=CHR(0)+CHR(0)+CHR(0)+CHR(0)
	myctrlword=0
ENDIF

myblockaddr=thisform.pagF1.page2.text7.Value 
myblocksize=thisform.pagF1.page2.text8.Value  

IF myblocksize=0 OR  myblocksize>12
	= MESSAGEBOX('读卡页数据要大于0小于12!',16,'提示:')
	thisform.pagF1.page2.text8.SetFocus 
	RETURN	
ENDIF

&&-------------------------------------------------------------- 显示16进制的串口调试指令
comedc=27
dispstr="0F1B"

dispstr=dispstr+LEFT(DecToHex(myctrlword),2)
comedc=BITXOR(comedc,myctrlword)

FOR i=1 TO 7
	dispstr=dispstr+"00"
	comedc=BITXOR(comedc,0)
NEXT

FOR i=1 TO 4
	dispstr=dispstr+LEFT(DecToHex(ASC(SUBSTR(mypicckey,i,1))),2)
	comedc=BITXOR(comedc,ASC(SUBSTR(mypicckey,i,1)))
NEXT

dispstr=dispstr+LEFT(DecToHex(myblockaddr),2)
comedc=BITXOR(comedc,myblockaddr)

dispstr=dispstr+LEFT(DecToHex(myblocksize),2)
comedc=BITXOR(comedc,myblocksize)

dispstr=dispstr+LEFT(DecToHex(comedc),2)
thisform.pagF1.page2.edit2.Value =dispstr 
&&--------------------------------------------------------------------

QuestRec= piccreadex_ntag(myctrlword,@mypiccserial,@mypicckey,myblockaddr,myblocksize,@mypiccdata)
DO case
   CASE QuestRec=0
   		=pcdbeep(50)
        CardIdH=""
        FOR i=1 TO 7
            CardIdH=CardIdH+LEFT(DecToHex(ASC(SUBSTR(mypiccserial,i,1))),2)
        NEXT
        thisform.pagF1.page2.text4.Value  =CardIdH 
        
        CardDa=""
        FOR i=1 TO myblocksize*4
            CardDa=CardDa+LEFT(DecToHex(ASC(SUBSTR(mypiccdata,i,1))),2)
        NEXT
        thisform.pagF1.page2.edit1.Value  =CardDa
        
   CASE QuestRec=8
        = MESSAGEBOX('   请将卡放在感应区!   ',16,'提示:')
   CASE QuestRec=23
        = MESSAGEBOX('   请连上USB 读写器!   ',16,'提示:')
   OTHERWISE
        = MESSAGEBOX('   操作失败,错误代码:'+STR(QuestRec),16,'提示:')
ENDCASE

 Easy card writing operation

mypiccserial=spac(7)   &&返回7字节卡序列号
mypicckey=SPACE(4)     &&卡认证密码
mypiccdata=SPACE(48)   &&读卡的数据缓冲

IF thisform.pagF1.page2.check3.Value >0
	IF LEN(ALLTRIM(thisform.pagF1.page2.text5.Value))<>8
		= MESSAGEBOX('   卡密码必须为8个字符!',16,'提示:')
		thisform.pagF1.page2.text5.SetFocus 
		RETURN		
	ENDIF
		
	Pas1str=ALLTRIM(thisform.pagF1.page2.text5.Value)
	mypicckey=""
    FOR i=1 TO 4
        mypicckey=mypicckey+CHR(HexToDec(SUBSTR(Pas1str,i*2-1,2)+"00"))        
    NEXT
    myctrlword=16      &&需要密码
ELSE
	mypicckey=CHR(0)+CHR(0)+CHR(0)+CHR(0)
	myctrlword=0
ENDIF

myblockaddr=thisform.pagF1.page2.text7.Value 
myblocksize=thisform.pagF1.page2.text8.Value  

IF myblocksize=0 OR  myblocksize>11
	= MESSAGEBOX('写卡页数据要大于0小于12!',16,'提示:')
	thisform.pagF1.page2.text8.SetFocus 
	RETURN	
ENDIF

IF LEN(ALLTRIM(thisform.pagF1.page2.edit1.Value))<myblocksize*4*2
	answ= MESSAGEBOX('   写卡数据不足,是否要自动补0?',0+32+0,'提示:')
	IF answ<>1 THEN 
		RETURN
	ELSE
	    thisform.pagF1.page2.edit1.Value=LEFT(ALLTRIM(thisform.pagF1.page2.edit1.Value)+"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",myblocksize*4*2)	
	ENDIF
ENDIF

writstr=ALLTRIM(thisform.pagF1.page2.edit1.Value)
mypiccdata=""
FOR i=1 TO myblocksize*4
    mypiccdata=mypiccdata+CHR(HexToDec(SUBSTR(writstr,i*2-1,2)+"00"))        
NEXT

&&-------------------------------------------------------------- 显示16进制的串口调试指令
comedc=28
dispstr="3B1C"

dispstr=dispstr+LEFT(DecToHex(myctrlword),2)
comedc=BITXOR(comedc,myctrlword)

FOR i=1 TO 7
	dispstr=dispstr+"00"
	comedc=BITXOR(comedc,0)
NEXT

FOR i=1 TO 4
	dispstr=dispstr+LEFT(DecToHex(ASC(SUBSTR(mypicckey,i,1))),2)
	comedc=BITXOR(comedc,ASC(SUBSTR(mypicckey,i,1)))
NEXT

dispstr=dispstr+LEFT(DecToHex(myblockaddr),2)
comedc=BITXOR(comedc,myblockaddr)

dispstr=dispstr+LEFT(DecToHex(myblocksize),2)
comedc=BITXOR(comedc,myblocksize)

FOR i=1 TO myblocksize*4
	dispstr=dispstr+LEFT(DecToHex(ASC(SUBSTR(mypiccdata,i,1))),2)
	comedc=BITXOR(comedc,ASC(SUBSTR(mypiccdata,i,1)))       
NEXT

FOR i=myblocksize*4+1 TO 44
	dispstr=dispstr+"00"
	comedc=BITXOR(comedc,0)
NEXT


dispstr=dispstr+LEFT(DecToHex(comedc),2)
thisform.pagF1.page2.edit2.Value =dispstr 
&&--------------------------------------------------------------------

QuestRec= piccwriteex_ntag(myctrlword,@mypiccserial,@mypicckey,myblockaddr,myblocksize,@mypiccdata)
DO case
   CASE QuestRec=0
   		=pcdbeep(50)
        CardIdH=""
        FOR i=1 TO 7
            CardIdH=CardIdH+LEFT(DecToHex(ASC(SUBSTR(mypiccserial,i,1))),2)
        NEXT
        thisform.pagF1.page2.text4.Value  =CardIdH 
        
        
   CASE QuestRec=8
        = MESSAGEBOX('   请将卡放在感应区!   ',16,'提示:')
   CASE QuestRec=23
        = MESSAGEBOX('   请连上USB 读写器!   ',16,'提示:')
   OTHERWISE
        = MESSAGEBOX('   操作失败,错误代码:'+STR(QuestRec),16,'提示:')
ENDCASE

 Initialize the Ntag card, set whether the card needs an authentication password to read and write

 

mypiccserial=spac(7) && return 7-byte card serial number
mypicckey=SPACE(4) && card authentication password
mypiccdata=SPACE(16) && read card data buffer, the array length of Ultralight card and NTAG21x card must be 16 characters Section, write card is 4 bytes

Card PIN must be 8 characters! ',16,'Hint:')














   



        thisform.pagF1.page2.text1.SetFocus 
        RETURN        
    ENDIF
    
    mypiccdata=CHR(0)                                              &&MIRROR
    mypiccdata=mypiccdata+CHR(0)                                   &&RFUI
    mypiccdata=mypiccdata+CHR(0)                                   &&MIRROR_PAGE
    mypiccdata=mypiccdata+CHR(thisform.pagF1.page2.text2.Value)    &&AUTH0
    myctrlword=myctrlword+1
    
    ACCESS=MOD(thisform.pagF1.page2.text3.Value, 8)
    IF thisform.pagF1.page2.check2.Value >0
        ACCESS=ACCESS+128
    ENDIF
    mypiccdata=mypiccdata+CHR(ACCESS)                              &&ACCESS
    mypiccdata=mypiccdata+CHR(0)+CHR(0)+CHR(0)                     &&启用计数器
    myctrlword=myctrlword+2 
        
    Pas1str=ALLTRIM(thisform.pagF1.page2.text1.Value)
    FOR i=1 TO 4
        mypiccdata=mypiccdata+CHR(HexToDec(SUBSTR(Pas1str,i*2-1,2)+"00"))        
    NEXT
    
    mypiccdata=mypiccdata+CHR(22)                                   &&PACK
    mypiccdata=mypiccdata+CHR(22)                                   &&PACK
    mypiccdata=mypiccdata+CHR(0)                                    &&RFUI
    mypiccdata=mypiccdata+CHR(0)                                    &&RFUI
    myctrlword=myctrlword+4
ELSE
    mypiccdata=CHR(0)                                              &&MIRROR
    mypiccdata=mypiccdata+CHR(0)                                   &&RFUI
    mypiccdata=mypiccdata+CHR(0)                                   &&MIRROR_PAGE
    mypiccdata=mypiccdata+CHR(255)                                 &&AUTH0
    myctrlword=myctrlword+1
    
    FOR i=5 TO 16
        mypiccdata=mypiccdata+CHR(0)
    NEXT
    myctrlword=myctrlword+2         
ENDIF

&&------------------------------------------------- ------------- Display the hexadecimal serial debugging command
comedc=22
dispstr="1D16"

dispstr=dispstr+LEFT(DecToHex(myctrlword),2)
comedc=BITXOR(comedc,myctrlword)

FOR i=1 TO 7
    dispstr=dispstr+"00"
    comedc=BITXOR(comedc,0)
NEXT

FOR i=1 TO 4
    dispstr=dispstr+LEFT(DecToHex(ASC(SUBSTR(mypicckey,i,1))),2)
    comedc=BITXOR(comedc,ASC(SUBSTR(mypicckey,i,1)))
NEXT

FOR i=1 TO 16
    dispstr=dispstr+LEFT(DecToHex(ASC(SUBSTR(mypiccdata,i,1))),2)
    comedc=BITXOR(comedc,ASC(SUBSTR(mypiccdata,i,1)))
NEXT

dispstr=dispstr+LEFT(DecToHex(comedc),2)
thisform.pagF1.page2.edit2.Value =dispstr 
&&--------------------------------------------------------------------

QuestRec= piccinit_ntag(myctrlword,@mypiccserial,@mypicckey,@mypiccdata) 
DO case
   CASE QuestRec=0
        =pcdbeep(50)
        CardIdH=""
        FOR i=1 TO 7
            CardIdH=CardIdH+LEFT(DecToHex(ASC(SUBSTR(mypiccserial, i,1))),2)
        NEXT
        thisform.pagF1.page2.text4.Value =CardIdH 
        = MESSAGEBOX('Card number:'+CardIdH +", the card is initialized successfully!",64,'Prompt:')        
   CASE QuestRec=8
        = MESSAGEBOX('Please put the card in the sensing area! ',16,'Prompt:')
   CASE QuestRec=12
        = MESSAGEBOX('Wrong password! ',16,'Prompt:')
   CASE QuestRec=14
        = MESSAGEBOX('Set Failed, password verification may be required! ',16,'Prompt:'        )        
   CASE QuestRec=23
        = MESSAGEBOX('Please connect the USB reader! ',16,'Prompt:')
   OTHERWISE
        = MESSAGEBOX('Operation failed, error code:'+STR(QuestRec),16,'Prompt:')
ENDCASE

Download address of this example: NTAG21x chip read and write VFP example source code.rar-Other Document Resources-CSDN Library

Guess you like

Origin blog.csdn.net/zhangjin7422/article/details/128572940