我目前正在尝试将几个字节从 PN532 写入 NTAG213 的用户可编程内存并读回这些字节。当 PN532 检测到 NTAG213 接近时,就会发生写入和读取。我从Adafruits库移植所需的功能在这里的ATxmega32A4U。要扫描和读取 NTAG213 卡,我正在使用以下功能。
// Reads cards, beep and long light flash for good card read, short light flash for no card read, lights mostly on for NFC chip not talking right
void TestNFC_ReadTag (void) {
bool success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
/************************************ Everytime Try Reading a Card ***********************************/
// Check for a good card read
success = PN532_readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength, 1000);
// If card read is good then beep and long flash of main lights
if (success) {
LIGHT_ON();
EventTimerCreate(200,1,TestingLightsOff);
for (int nfcBeep = 0; nfcBeep < 300; nfcBeep++) {
DACB.CH0DATA = 0x700;
_delay_us(200);
DACB.CH0DATA = 0x900;
_delay_us(200);
}
DACB.CH0DATA = 0x800;
_delay_ms(500); // Reduced from 1000ms to 500ms to avoid WDT reset - Vinay
}
// If valid card read then short light flash no beep
else {
LIGHT_ON();
_delay_ms(10);
LIGHT_OFF();
}
}
/**************************************************************************/
/*!
Waits for an ISO14443A target to enter the field
@param cardBaudRate Baud rate of the card
@param uid Pointer to the array that will be populated
with the card's UID (up to 7 bytes)
@param uidLength Pointer to the variable that will hold the
length of the card's UID.
@returns 1 if everything executed properly, 0 for an error
*/
/**************************************************************************/
bool PN532_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
{
// read data packet
if (PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
return 0x0;
}
// check some basic stuff
/* ISO14443A card response should be in the following format:
byte Description
------------- ------------------------------------------
b0 Tags Found
b1 Tag Number (only one used in this example)
b2..3 SENS_RES
b4 SEL_RES
b5 NFCID Length
b6..NFCIDLen NFCID
*/
if (pn532_packetbuffer[0] != 1)
return 0;
uint16_t sens_res = pn532_packetbuffer[2];
sens_res <<= 8;
sens_res |= pn532_packetbuffer[3];
DMSG("ATQA: 0x"); DMSG_HEX(sens_res);
DMSG("SAK: 0x"); DMSG_HEX(pn532_packetbuffer[4]);
DMSG("\r\n");
/* Card appears to be Mifare Classic */
*uidLength = pn532_packetbuffer[5];
for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) {
uid[i] = pn532_packetbuffer[6 + i];
}
return 1;
}
/**************************************************************************/
/*!
@brief Starts the scan
@returns 1 if everything executed properly, 0 for an error
*/
/**************************************************************************/
uint8_t PN532_StartScan(void)
{
uint8_t pn532_packetbuffer[2];
uint8_t ret = 0;
pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
pn532_packetbuffer[1] = 1;
pn532_packetbuffer[2] = PN532_MIFARE_ISO14443A;
/* Disable the interrupt */
PORTA.INT1MASK &= ~(1<<PIN7_bp);
/* Send scan command and read acknowledgments */
if (PN532_writeCommand(pn532_packetbuffer, 3, NULL, 0))
ret = 0x0; // command failed
else
ret = 0x01;
/* Enable the interrupt */
PORTA.INT1MASK |= PIN7_bm;
return(ret);
}
写入和读取 NTAG213 的内存。我使用以下功能。
/**************************************************************************/
/*!
Tries to write an entire 4-bytes data buffer at the specified page
address.
@param page The page number to write into. (0x04..0x27).
@param buffer The byte array that contains the data to write.
@returns 1 if everything executed properly, 0 for an error
*/
/**************************************************************************/
uint8_t PN532_writePage (uint8_t page, uint8_t *buffer)
{
if ((page < NTAG_PAGE_START_ADDRESS) || (page > NTAG_PAGE_END_ADDRESS)) {
DMSG("Page value out of range\n");
return 0;
}
/* Prepare the first command */
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Card number */
pn532_packetbuffer[1] = 1;
pn532_packetbuffer[2] = NTAG_CMD_WRITE_USER_EEPROM; /* NTAG213 Write cmd = 0xA2 */
pn532_packetbuffer[3] = page; /* page Number (0x04..0x27) */
memcpy (pn532_packetbuffer + 4, buffer, 4); /* Data Payload */
/* Send command to write to NTAG 213 EEPROM */
if (PN532_writeCommand(pn532_packetbuffer, 8, NULL, 0))
return 0;
/* Read the response packet */
if(PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer), 100) < 0)
return 0;
return 1;
}
/**************************************************************************/
/*!
Tries to read an entire 4-bytes page at the specified address.
@param page The page number ((0x04..0x27 in most cases)
@param buffer Pointer to the byte array that will hold the
retrieved data (if any)
*/
/**************************************************************************/
uint8_t PN532_readPage (uint8_t page, uint8_t *buffer)
{
if ((page < NTAG_PAGE_START_ADDRESS) || (page > NTAG_PAGE_END_ADDRESS)) {
DMSG("Page value out of range\n");
return 0;
}
/* Prepare the command */
pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
pn532_packetbuffer[1] = 1; /* Card number */
pn532_packetbuffer[2] = NTAG_CMD_READ_USER_EEPROM; /* NTAG Read command = 0x30 */
pn532_packetbuffer[3] = page; /* page Number (0x04..0x27) */
/* Send the command */
if (PN532_writeCommand(pn532_packetbuffer, 4, NULL, 0))
return 0;
/* Read the response packet */
//if(PN532_readResponse(pn532_packetbuffer, sizeof(pn532_packetbuffer), 100))
if(PN532_readResponse(pn532_packetbuffer, 20, 100) < 0)
return 0;
#ifdef PN532_PGREAD_DBG
printf("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n",
pn532_packetbuffer[0], pn532_packetbuffer[1], pn532_packetbuffer[2], pn532_packetbuffer[3],
pn532_packetbuffer[4], pn532_packetbuffer[5], pn532_packetbuffer[6], pn532_packetbuffer[7],
pn532_packetbuffer[8], pn532_packetbuffer[9], pn532_packetbuffer[10], pn532_packetbuffer[11],
pn532_packetbuffer[12], pn532_packetbuffer[13], pn532_packetbuffer[14], pn532_packetbuffer[15],
pn532_packetbuffer[16], pn532_packetbuffer[17], pn532_packetbuffer[18]);
#endif
/* If the status isn't 0x00 we probably have an error */
if (pn532_packetbuffer[0] == 0x00) {
/* Copy the 4 data bytes to the output buffer */
/* Block content starts at byte 1 of a valid response */
/* Note that the command actually reads 16 bytes or 4 */
/* pages at a time ... we simply discard the last 12 */
/* bytes */
memcpy (buffer, pn532_packetbuffer + 1, 4);
}
else {
return 0;
}
// Return OK signal
return 1;
}
我正在执行一些测试,并在尝试从 NTAG 读取时遇到了一些问题。
以下测试代码的工作意义: PN532 能够读取卡以及从 NTAG 写入和读回用户数据。
void TestNFCInterrupt_ReadTag (void){
static uint8_t flag = 0;
/* Test code. Always perform read or write prior to getting the uuid */
if(flag == 0){
testPN532WritePage();
flag = 1;
}
else{
testPN532ReadPage();
flag = 0;
}
/* Needs to restart the scan to detect the NTAG passively */
PN532_StartScan();
TestNFC_ReadTag();
PN532_StartScan();
}
但令人惊讶的是,对于下面的代码,检测到卡,写入工作,但是在检测到卡后进行下一次读取时,我收到状态错误响应 0x27,这表明由于当前上下文,该命令是不可接受的关于 PN532,这可以在PN532 用户手册的第 68 页上看到。
void TestNFCInterrupt_ReadTag (void){
static uint8_t flag = 0;
TestNFC_ReadTag();
/* Test code. Always perform read or write prior to getting the uuid */
if(flag == 0){
testPN532WritePage();
flag = 1;
}
else{
testPN532ReadPage();
flag = 0;
}
/* Needs to restart the scan to detect the NTAG passively */
PN532_StartScan();
}
此外,这里是 NTAG213 手册。抱歉帖子内容详尽,但教了以上信息,有必要寻求帮助。如果有人能花一些时间检查代码或提出任何建议,我将不胜感激。