STM32F103C8T6+CLRC66303HN chip is used, spi1 is used for communication. The source code is attached, using the Anticollision register layer for CLRC663.zip library.
Solved! Go to Solution.
Hello @a751116023
报错协议没加载成功,这个时候RF就被关掉了,所以您看不到13.56MHz的RF信号。建议您先排查下SPI通讯,确保MCU和CLRC663之间的通讯是正确的,通常情况下,SPI驱动没问题,当前的代码是完全可以工作的。
Hello @a751116023
不同协议的卡应答有所不同,NXP原有的例程是基于 Tpye 2标签写的。您的工程读的是什么类型的卡?又出现了什么错误呢?或者是在哪一步报错的呢?
非debug模式,是在这里报错的,Error loading Protocol ErrorCode: 0x15
/*-------------------------------------------- SET UP RC663 -----------------------------------------------------------------*/
/* writeRegister(Address, Value)
* writeRegister writes a value into a Register.
*
* The CommandReg (0x00) is used to control the state machine in the RC663, which is able to execute certain commands.
* Command 0x00 cancels previous execution and the state machine returns into Idle mode. */
writeRegister(0x00, 0x00);
/* The FIFOControlReg (0x02) defines the characteristics of the FIFO. Depending on, whether bits are set or not, the FIFO
* characteristics can be changed.
* The value 0xB0 (1011 0000) translates to: FIFO size is 255 bytes
* High Alert deactivated
* Low Alert activated (LoAlert =1 if FIFOLength <= WaterLevel)
* Flush the FIFO*/
writeRegister(0x02, 0xB0);
/* Command 0xF1 is performing a soft Reset. Triggered by this command all the default values for the register setting
* will be read from the EEPROM and copied into the register set.*/
writeRegister(0x00, 0xF1);
/*--------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------- LOAD PROTOCOL - ISO/IEC14443 A - 106 ----------------------------------------*/
/* Command 0x00 cancels previous execution and the state machine returns into Idle mode.*/
writeRegister(0x00, 0x00);
/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 64)*/
writeRegister(0x02, 0xB0);
/* Register 0x05 is the FIFO and used to write into and read from FIFO.
* To load the Protocol ISO/IEC14443 A - 106 the FIFO has to be filled with 0x00 and 0x00 and then
* the Command 0x0D LoadProtocol has to be performed
*
* The RC663 has an EEPROM, where different Register Presets for different Protocols are saved.
* With the LoadProtocol command (0x0D) these presets can be load into the registers.
* */
writeRegister(0x05, 0x00);
writeRegister(0x05, 0x00);
writeRegister(0x00, 0x0D);
/* readRegister(Address, Buffer)
* ReadRegister reads a Register and writes its value into the Buffer.
*
* Register 0x0A is the ErrorRegister.
* The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
readRegister(0x0A, &errorRegister);
/* Checks if an Error has occurred*/
if(errorRegister != 0) {
/* turns on red status LED to notify the user that an Error has occurred*/
HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_SET);
DEBUG_PRINTF("Error loading Protocol \t ErrorCode: 0x%02X\n", errorRegister);
/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
* Value 0x8E switches the RF field OFF */
writeRegister(0x28, 0x86);
HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_RESET);
return 1;
},
Hello @a751116023
报错协议没加载成功,这个时候RF就被关掉了,所以您看不到13.56MHz的RF信号。建议您先排查下SPI通讯,确保MCU和CLRC663之间的通讯是正确的,通常情况下,SPI驱动没问题,当前的代码是完全可以工作的。
修改CLRC663的供电系统后,目前协议不报错了,也正常输出13.56MHz的RF信号了。
我目前改为15693协议读取 I CODE SLIX2的卡,一直读取不到卡,IRQ0的值一直是0x28 是什么原因?
uint8_t waitForCardResponse() {
uint8_t IRQ0[2] = {0x06,0x00};
uint16_t counter = 0x00;
/* Continuous Loop, which exits if the IRQ0 == 0x3c or IRQ0 == 0x03e or the counter is bigger than 1000
*
* Register 0x06 is the IRQ0 (Interrupt Register 0)
*
* When the Card has responded following bits will be set in IRQ0.
* The value 0x3c (0011 1100) translates to: FIFO data number has reached the bottom level as configured by the register WaterLevel
* Command terminated by itself
* Data transmission is completed
* Receiver detects end of data stream
*
* The value 0x3e (0011 1110) translates to: same as 0x3c + An Error has occurred
*
* If the Card hasn't responded after 10000 loop cycles then exit the loop to prevent getting stuck in an infinite loop.
*/
while( IRQ0[1] != 0x3c && IRQ0[1] != 0x3e && counter < 10000) {
IRQ0[0] = 0x06;
IRQ0[1] = 0x00;
readRegister(IRQ0,2);
counter++;
}
return IRQ0[1]==0x3c;
}
之前芯片供电电压有问题,改正确之后。目前芯片正常工作,也能出信号了。但是IRQ0寄存器一直是0x28,读不到卡。会是什么原因?
/*
* Copyright (c), NXP Semiconductors Gratkorn / Austria
*
* (C)NXP Semiconductors
* All rights are reserved. Reproduction in whole or in part is
* prohibited without the written consent of the copyright owner.
* NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
* particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
* arising from its use.
*/
/** \file
* $Author: Vogtberg S $
* $Date: 25.09.2019$
*
*
*
* This Example shows how to communicate between LPC1769 and RC663 via SPI and
* which Register have to be set to send a Select Command and fetch a UID (Works with NTAG216)
*
*/
#include "typeDefs.h"
#include "main.h"
volatile uint16_t delay;
/*******************************************************************************
** Function Declarations
*******************************************************************************/
uint8_t waitForCardResponse(void);
void writeRegister(uint8_t * txData,uint8_t len);
void readRegister(uint8_t * rxData,uint8_t len);
extern SPI_HandleTypeDef hspi1;
/*******************************************************************************
** Main Function
*******************************************************************************/
void RC663_Init(void) {
// 硬件复位
HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(CLRC663_RST_GPIO_Port, CLRC663_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
}
int runApp (void) {
uint8_t counter;
uint8_t txData[10]= {0};
uint8_t errorRegister[2]= {0x0A,0x00};
uint8_t UID[9] = {0x05};
/* Initializes the LPC1769*/
//DEBUG_PRINTF("Start \n");
/*-------------------------------------------- SET UP RC663 -----------------------------------------------------------------*/
/* writeRegister(Address, Value)
* writeRegister writes a value into a Register.
*
* The CommandReg (0x00) is used to control the state machine in the RC663, which is able to execute certain commands.
* Command 0x00 cancels previous execution and the state machine returns into Idle mode. */
writeRegister(txData,2);
/* The FIFOControlReg (0x02) defines the characteristics of the FIFO. Depending on, whether bits are set or not, the FIFO
* characteristics can be changed.
* The value 0xB0 (1011 0000) translates to: FIFO size is 255 bytes
* High Alert deactivated
* Low Alert activated (LoAlert =1 if FIFOLength <= WaterLevel)
* Flush the FIFO*/
txData[0]=0x02;
txData[1]=0xB0;
writeRegister(txData,2);
/* Command 0xF1 is performing a soft Reset. Triggered by this command all the default values for the register setting
* will be read from the EEPROM and copied into the register set.*/
txData[0]=0x00;
txData[1]=0xF1;
writeRegister(txData,2);
/*--------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------- LOAD PROTOCOL - ISO/IEC15693 - 106 ----------------------------------------*/
/* Command 0x00 cancels previous execution and the state machine returns into Idle mode.*/
txData[0]=0x00;
txData[1]=0x00;
writeRegister(txData,2);
/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 64)*/
txData[0]=0x02;
txData[1]=0xB0;
writeRegister(txData,2);
/* Register 0x05 is the FIFO and used to write into and read from FIFO.
* To load the Protocol ISO/IEC14443 A - 106 the FIFO has to be filled with 0x00 and 0x00 and then
* the Command 0x0D LoadProtocol has to be performed
*
* The RC663 has an EEPROM, where different Register Presets for different Protocols are saved.
* With the LoadProtocol command (0x0D) these presets can be load into the registers.
* */
txData[0]=0x05;
txData[1]=0x0A;
txData[2]=0x0A;
writeRegister(txData,3);
txData[0]=0x00;
txData[1]=0x0D;
writeRegister(txData,2);
/* readRegister(Address, Buffer)
* ReadRegister reads a Register and writes its value into the Buffer.
*
* Register 0x0A is the ErrorRegister.
* The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
readRegister(errorRegister,2);
/* Checks if an Error has occurred*/
if(errorRegister[1] != 0) {
/* turns on red status LED to notify the user that an Error has occurred*/
HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_SET);
DEBUG_PRINTF("Error loading Protocol \t ErrorCode: 0x%02X\n", errorRegister[1]);
/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
* Value 0x8E switches the RF field OFF */
txData[0]=0x28;
txData[1]=0x86;
writeRegister(txData,2);
HAL_GPIO_WritePin(LED_SYS_GPIO_Port, LED_SYS_Pin, GPIO_PIN_RESET);
return 1;
}
/*--------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------- Send REQA -------------------------------------------------------------------*/
/* Flushes the FIFO and maintains old FIFO characteristics (detailed description at line 62)*/
txData[0]=0x02;
txData[1]=0xB0;
writeRegister(txData,2);
/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
* Value 0x8E switches the RF field ON */
txData[0]=0x28;
txData[1]=0x8E;
writeRegister(txData,2);
HAL_GPIO_WritePin(LED_15693_GPIO_Port, LED_15693_Pin, GPIO_PIN_SET);
txData[0]=0x05;
txData[1]=0x01;
txData[2]=0x94;
txData[3]=0x28;
txData[4]=0x12;
writeRegister(txData,5);
txData[0]=0x00;
txData[1]=0x0C;
writeRegister(txData,2);
txData[0]=0x00;
txData[1]=0x00;
writeRegister(txData,2);
txData[0]=0x02;
txData[1]=0xB0;
writeRegister(txData,2);
txData[0]=0x06;
txData[1]=0x7F;
writeRegister(txData,2);
txData[0]=0x05;
txData[1]=0x06;
txData[2]=0x01;
txData[3]=0x00;
writeRegister(txData,4);
/* The value 0x07 written into the Command Register triggers the Transceive command
* This command transmits data from FIFO buffer and automatically activates the receiver after a transmission is finished.*/
txData[0]=0x00;
txData[1]=0x07;
writeRegister(txData,2);
/* Register 0x0A is the ErrorRegister.
* The Value of the ErrorRegister should be 0x00 otherwise an Error occurred during the LoadProtocol command.*/
readRegister(errorRegister,2);
/* Checks if an Error has occurred*/
if(errorRegister[1] != 0) {
/* turns on red status LED to notify the user that an Error has occurred*/
HAL_GPIO_WritePin(LED_SYS_GPIO_Port,LED_SYS_Pin, GPIO_PIN_SET);
DEBUG_PRINTF("Error transmitting REQA\t ErrorCode: 0x%02X\n", errorRegister[1]);
/* Register 0x28 is the DriverMode Register, which is used to turn OFF and ON the RF field.
* Value 0x8E switches the RF field OFF */
txData[0]=0x28;
txData[1]=0x86;
writeRegister(txData,2);
HAL_GPIO_WritePin(LED_15693_GPIO_Port,LED_15693_Pin, GPIO_PIN_RESET);
}
/*--------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------- Fetch ATQA -------------------------------------------------------------------*/
/* Wait until the Card has responded*/
for(counter=0; counter<16; counter++) {
if(waitForCardResponse()) {
readRegister(UID,9);
/*Print the UID*/
DEBUG_PRINTF("UID: ");
for(int i = 0; i < 8; i++) {
DEBUG_PRINTF("%02x ", UID[i+1]);
}
DEBUG_PRINTF("\n");
txData[0]=0x33;
txData[1]=0x0C;
writeRegister(txData,2);
txData[0]=0x2E;
txData[1]=0x00;
writeRegister(txData,2);
txData[0]=0x02;
txData[1]=0xB0;
writeRegister(txData,2);
txData[0]=0x00;
txData[1]=0x07;
writeRegister(txData,2);
}
}
DEBUG_PRINTF("\nEND\n");
txData[0]=0x28;
txData[1]=0x86;
writeRegister(txData,2);
return 0;
}
void writeRegister(uint8_t * txData,uint8_t len) {
/* 地址构造:左移1位 + 写操作位(0) */
txData[0] = (txData[0] << 1) & 0xFE; // 写操作必须保证LSB=0
SPI1_NSS_LOW();
CHECK_SPI1_READY
HAL_StatusTypeDef res=HAL_SPI_Transmit(&hspi1, txData,len, HAL_MAX_DELAY);
//DEBUG_PRINTF("writeRegister \t address:0x%02X \t val:0x%02X \t res:0x%02X\n",txData[0],txData[1],res);
CHECK_SPI1_READY
SPI1_NSS_HIGH();
//HAL_Delay(len); // 至少维持1us(根据CLRC663手册要求)
}
void readRegister(uint8_t * rxData,uint8_t len) {
/* 地址构造:左移1位 + 读操作位(1) */
uint8_t address=rxData[0];
rxData[0] = ((address & 0x7F) << 1) | 0x01; // 确保地址不超7bit
SPI1_NSS_LOW();
CHECK_SPI1_READY
HAL_StatusTypeDef res=HAL_SPI_TransmitReceive(&hspi1, rxData, rxData, len, HAL_MAX_DELAY);
//DEBUG_PRINTF("readRegister \t address:0x%02X \t val:0x%02X \t res:0x%02X\n",rxData[0],rxData[1],res);
CHECK_SPI1_READY
SPI1_NSS_HIGH();
//HAL_Delay(len); // 至少维持1us(根据CLRC663手册要求)
}
uint8_t waitForCardResponse() {
uint8_t IRQ0[2] = {0x06,0x00};
uint16_t counter = 0x00;
/* Continuous Loop, which exits if the IRQ0 == 0x3c or IRQ0 == 0x03e or the counter is bigger than 1000
*
* Register 0x06 is the IRQ0 (Interrupt Register 0)
*
* When the Card has responded following bits will be set in IRQ0.
* The value 0x3c (0011 1100) translates to: FIFO data number has reached the bottom level as configured by the register WaterLevel
* Command terminated by itself
* Data transmission is completed
* Receiver detects end of data stream
*
* The value 0x3e (0011 1110) translates to: same as 0x3c + An Error has occurred
*
* If the Card hasn't responded after 10000 loop cycles then exit the loop to prevent getting stuck in an infinite loop.
*/
while( IRQ0[1] != 0x3c && IRQ0[1] != 0x3e && counter < 10000) {
IRQ0[0] = 0x06;
IRQ0[1] = 0x00;
readRegister(IRQ0,2);
counter++;
}
return IRQ0[1]==0x3c;
}
/******************************************************************************
** End Of File
******************************************************************************/
I use the nfc chip of clrc66303 through spi communication, direct register operation, Error loading Protocol ErrorCode: 0xFF has been reported
STM32F103C8T6+CLRC66303HN chip is used, spi1 is used for communication. The source code is attached, using the Anticollision register layer for CLRC663.zip library