#include #include #include "DP1312EA_Config.h" #include "DP1312EA.h" #include "TypeA.h" #include "nfc_platform.h" // 定义卡片状态 typedef enum { CARD_STATE_IDLE, CARD_STATE_READY, CARD_STATE_ACTIVE, CARD_STATE_HALT } CardState; // 卡片信息结构 typedef struct { uint8_t uid[10]; // UID (4,7或10字节) uint8_t uid_len; // UID长度 CardState state; // 卡片状态 } CardInfo; // 系统参数 #define MAX_CARDS 10 // 最大检测卡片数量 CardInfo detectedCards[MAX_CARDS]; uint8_t cardCount = 0; // 函数声明 void DP1312EA_Config(void); uint8_t DP1312EA_Transceive(uint8_t *send, uint8_t sendLen, uint8_t *recv, uint8_t *recvLen); uint8_t DP1312EA_Request(uint8_t cmd, uint8_t *atq); uint8_t DP1312EA_Anticollision(uint8_t level, uint8_t *uid, uint8_t *uid_len); uint8_t DP1312EA_Select(uint8_t level, uint8_t *uid, uint8_t uid_len, uint8_t *sak); uint8_t DP1312EA_Halt(void); void DP1312EA_HandleCollision(uint8_t *uid, uint8_t uid_len, uint8_t level); void FindAllCards(void); int TypeA_AntiColl(void); // DP1312EA初始化 void DP1312EA_Config(void) { DP1312EA_Reset(); // 配置DP1312EA寄存器 DP1312EA_PcdConfigISOType('A'); DP1312EA_FieldOn(); nfc_platform_sleep_ms(10); } // 发送和接收数据 uint8_t DP1312EA_Transceive(uint8_t *send, uint8_t sendLen, uint8_t *recv, uint8_t *recvLen) { // 清除FIFO DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); DP1312EA_WriteRawRC(0x01, DP1312EA_MEM); // 写入发送数据 DP1312EA_WriteFIFO(send, sendLen); // 启动传输 DP1312EA_WriteRawRC(0x01, DP1312EA_TRANSCEIVE); DP1312EA_WriteRawRC(0x0D, 0x30); // 启用发送和接收 // 等待传输完成 uint16 timeout = 2000; // 超时时间 while (!(DP1312EA_ReadRawRC(0x04) & 0x30) ){ // 等待TxIRq或RxIRq if (--timeout == 0) { DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); // 停止传输 return 1; // 超时错误 } //nfc_platform_sleep_ms(1); //Delay_us(100); } // 检查错误 if (DP1312EA_ReadRawRC(0x06) & 0x13) { // 检查错误标志 DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); return 2; // 通信错误 } // 读取接收数据 *recvLen = DP1312EA_ReadRawRC(0x0A); // FIFOLevel if (*recvLen > 0) { DP1312EA_ReadFIFO(recv, *recvLen); } DP1312EA_WriteRawRC(0x01, DP1312EA_IDLE); return 0; // 成功 } // 请求阶段 uint8_t DP1312EA_Request(uint8_t cmd, uint8_t *atq) { uint8_t response[2]; uint8_t resLen = 2; uint8_t status = DP1312EA_Transceive(&cmd, 1, response, &resLen); if (status == 0 && resLen == 2) { atq[0] = response[0]; atq[1] = response[1]; return 1; // 成功 } return 0; // 失败 } // 防冲突函数 uint8_t DP1312EA_Anticollision(uint8_t level, uint8_t *uid, uint8_t *uid_len) { uint8_t anticoll_cmd; uint8_t nvb; switch(level) { case 0: anticoll_cmd = PICC_ANTICOLL1; nvb = 0x20; // 32位 break; case 1: anticoll_cmd = PICC_ANTICOLL2; nvb = 0x20; // 32位 break; case 2: anticoll_cmd = PICC_ANTICOLL3; nvb = 0x20; // 32位 break; default: return 0; } uint8_t sendBuf[2] = {anticoll_cmd, nvb}; uint8_t recvBuf[10]; // 最大UID长度+1 uint8_t recvLen = sizeof(recvBuf); uint8_t status = DP1312EA_Transceive(sendBuf, 2, recvBuf, &recvLen); if (status != 0 || recvLen < 5) { // 至少4字节UID+1字节BCC return 0; // 失败 } // 检查冲突 if (DP1312EA_ReadRawRC(0x06) & 0x08) { // CollErr标志 return 2; // 冲突 } // 计算BCC uint8_t bcc = 0; for (uint8_t i = 0; i < recvLen - 1; i++) { bcc ^= recvBuf[i]; } if (bcc != recvBuf[recvLen-1]) { return 0; // BCC错误 } // 复制UID *uid_len = recvLen - 1; memcpy(uid, recvBuf, *uid_len); return 1; // 成功 } // 选择卡片 uint8_t DP1312EA_Select(uint8_t level, uint8_t *uid, uint8_t uid_len, uint8_t *sak) { uint8_t select_cmd; switch(level) { case 0: select_cmd = SELECT_0; break; case 1: select_cmd = SELECT_1; break; case 2: select_cmd = SELECT_2; break; default: return 0; } uint8_t sendBuf[10]; // SEL + NVB + UID + BCC uint8_t sendLen = 0; sendBuf[sendLen++] = select_cmd; sendBuf[sendLen++] = 0x70; // NVB=64位 uint8_t bcc = 0; for (uint8_t i = 0; i < uid_len; i++) { sendBuf[sendLen++] = uid[i]; bcc ^= uid[i]; } sendBuf[sendLen++] = bcc; uint8_t response[3]; uint8_t resLen = sizeof(response); if (DP1312EA_Transceive(sendBuf, sendLen, response, &resLen) != 0 || resLen < 1) { return 0; // 失败 } *sak = response[0]; return 1; // 成功 } // 休眠卡片 uint8_t DP1312EA_Halt(void) { uint8_t halt_cmd[4] = {PICC_HALT, 0, 0, 0}; // CRC由DP1312EA计算 uint8_t resLen = 0; return (DP1312EA_Transceive(halt_cmd, 4, NULL, &resLen) == 0); } // 处理冲突 void DP1312EA_HandleCollision(uint8_t *uid, uint8_t uid_len, uint8_t level) { uint8_t coll_pos = DP1312EA_ReadRawRC(BitFramingReg) & 0x1F; uint8_t bit_pos = coll_pos % 8; uint8_t byte_pos = coll_pos / 8; // 确定冲突位的位置 // uint8_t collision_byte = uid[byte_pos]; // 尝试两种可能的值 (0和1) for (uint8_t bit_value = 0; bit_value <= 1; bit_value++) { // 创建新的UID分支 uint8_t new_uid[10]; memcpy(new_uid, uid, uid_len); // 设置冲突位的值 if (bit_value) { new_uid[byte_pos] |= (1 << bit_pos); } else { new_uid[byte_pos] &= ~(1 << bit_pos); } // 尝试防冲突 uint8_t status = DP1312EA_Anticollision(level, new_uid, &uid_len); if (status == 1) { // 成功获取UID uint8_t sak; if (DP1312EA_Select(level, new_uid, uid_len, &sak)) { // 检查SAK的UID完整标志 if (sak & 0x04) { // UID完整,存储卡片 if (cardCount < MAX_CARDS) { memcpy(detectedCards[cardCount].uid, new_uid, uid_len); detectedCards[cardCount].uid_len = uid_len; detectedCards[cardCount].state = CARD_STATE_ACTIVE; cardCount++; } // 使卡片休眠 DP1312EA_Halt(); } else { // UID不完整,进入下一级防冲突 DP1312EA_HandleCollision(new_uid, uid_len, level + 1); } } } else if (status == 2) { // 仍有冲突,递归处理 DP1312EA_HandleCollision(new_uid, uid_len, level); } } } // 完整的防冲突流程 void FindAllCards(void) { cardCount = 0; // 重置卡片计数 // 1. 发送REQA唤醒卡片 uint8_t atq[2]; if (!DP1312EA_Request(PICC_REQIDL, atq)) { return; // 没有卡片 } // 2. 初始防冲突循环 uint8_t uid[10]; uint8_t uid_len; uint8_t status; while (cardCount < MAX_CARDS) { status = DP1312EA_Anticollision(0, uid, &uid_len); if (status == 1) { // 成功获取UID uint8_t sak; if (DP1312EA_Select(0, uid, uid_len, &sak)) { // 检查SAK的UID完整标志 if (sak & 0x04) { // UID完整,存储卡片 memcpy(detectedCards[cardCount].uid, uid, uid_len); detectedCards[cardCount].uid_len = uid_len; detectedCards[cardCount].state = CARD_STATE_ACTIVE; cardCount++; // 使卡片休眠 DP1312EA_Halt(); } else { // UID不完整,进入下一级防冲突 DP1312EA_HandleCollision(uid, uid_len, 1); } } } else if (status == 2) { // 冲突发生,处理冲突 DP1312EA_HandleCollision(uid, uid_len, 0); } else { // 没有更多卡片 break; } } } // 主函数 int TypeA_AntiColl(void) { DP1312EA_Config(); while (1) { FindAllCards(); if (cardCount > 0) { // 处理所有检测到的卡片 for (uint8_t i = 0; i < cardCount; i++) { // 打印UID nfc_platform_log("Card %d UID: ", i); for (uint8_t j = 0; j < detectedCards[i].uid_len; j++) { nfc_platform_log("%02X ", detectedCards[i].uid[j]); } nfc_platform_log("\n"); } } //Delay_ms(500); // 延时后再检测 } }