RFID(NFC) CLRC663非接触读取芯片GD32/STM32 SPI读取

文章目录

    • 基本介绍
    • 硬件配置连接
    • 硬件连接详解
    • 程序代码
    • 代码解释

基本介绍

CLRC663 是高度集成的收发器芯片,用于 13.56 兆赫兹的非接触式通讯。CLRC663 收发器芯片支
持下列操作模式
• 读写模式支持 ISO/IEC 14443A/MIFARE
• 读写模式支持 SO/IEC 14443IB
• JIS X 6319-4 读写模式支持(等效于FeliCa1
方案,请参阅章节 21.5)
• 相应于 ISO/IEC 18092 的被动发起方模式
• 读写模式支持 ISO/IEC 15693
• 读写模式支持 ICODE EPC UID/EPC OTP
• 读写模式支持 ISO/IEC 18000-3 mode 3/ EPC Class-1 H
CLRC663 能够透过内建发射器直接驱动外置天线与 ISO/IEC 14443A 或 MIFARE 卡片进行通信,而无
需附加有源电路。数字模块负责全部的 ISO/IEC 14443A 组帧和错误检测功能(奇偶校验和 CRC 循環
冗餘校驗)。
CLRC663支持MIFARE Classic 1K,MIFARE Classic 4K,MIFARE Ultralight,MIFARE Ultralight C,
MIFARE PLUS和 MIFARE DESFire产品。CLRC663支持MIFARE高达848k位元/秒的更高双向传输速
度。
CLRC663支持ISO/IEC 14443B第2和第3层的读写通信方案,除了防碰撞(Anti-collision)功能。防碰
撞功能需在主机控制器的固件及更上层中执行。
CLRC663能进行FeliCa编码信号的解调和解码。FeliCa接收器器件提供为FeliCa编码信号的解调和解码
电路。CLRC663处理,如CRC的FeliCa的制定和错误检测。CLRC663支持FeliCa高达424k位元/秒的更
高速双向传输速度

芯片引脚如下
在这里插入图片描述
硬件连接如下
在这里插入图片描述

硬件配置连接

1供电VBAT和TVDD_INO给的3.3V
2 IFSEL1=1、IFSEL0=0
3 PD拉低
4PVDD高 TVDD高 VDD高
5IRQ拉低
6SPI按照标准4线进行连接

硬件连接详解

供电要求
VDD(PVDD)的伏特必须与VDD一样或更低

IFSEL1=1、IFSEL0=0 主要是用来设置SPI通讯,该芯片支持I2C UART SPI通讯
在这里插入图片描述

IRQ是中断请求,输出信号以示意中断事件,可以用来识别触发,可以配置成外部触发,当然直接拉低不使用也可以

SPI连接如图
在这里插入图片描述

程序代码

具体代码可以淘宝购买开发板提供。或者csdn搜索资源下载
阿松大

main.c主程序

#include <stdio.h>
#include "stm32f10x.h"
#include "RC663.h"void System_Init(void);
int main()
{System_Init();RC663_Init();printf("reset!!!!\n");LED_1;while(1){RC663_MifareClassic();	//ISO14443ARC663_ID2();	//ISO14443B RC663_Felica();	//RC663_ISO15693();delay_ms(100);}
}int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);return ch;
}void System_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PCLK2Config(RCC_HCLK_Div1); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );UART1GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = 115200;  		USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);			//Enable UART1 receive interruptUSART_Cmd(USART1, ENABLE);USART_ClearFlag(USART1, USART_FLAG_TC); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;				//flag pb10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);FLAG_0;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;				//led pc13GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);LED_0;delay_init(72);
}

RC663.h

#ifndef __RC663_H
#define __RC663_H#include "stm32f10x.h"#define UART_PRINT#define	 RC663_NSS	 	GPIO_Pin_12				//PB12
#define	 RC663_NSS_0	 GPIO_ResetBits(GPIOB,RC663_NSS)
#define	 RC663_NSS_1	 GPIO_SetBits(GPIOB,RC663_NSS)#define	 RC663_IRQ	 	GPIO_Pin_11			//PB11   #define	 PDOWN	 		GPIO_Pin_8			//PA8
#define	 PDOWN_0	 	GPIO_ResetBits(GPIOA,PDOWN)
#define	 PDOWN_1	 	GPIO_SetBits(GPIOA,PDOWN)#define	 FLAG_0	 	GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#define	 FLAG_1	 	GPIO_SetBits(GPIOB,GPIO_Pin_10)#define	 LED_0	 	GPIO_ResetBits(GPIOC,GPIO_Pin_13)
#define	 LED_1	 	GPIO_SetBits(GPIOC,GPIO_Pin_13)/
#define rRegCommand 					0x00 // Starts and stops command execution
#define rRegHostCtrl 				0x01 // Host control register
#define rRegFIFOControl 			0x02 // Control register of the FIFO
#define rRegWaterLevel 			0x03 // Level of the FIFO underflow and overflow warning
#define rRegFIFOLength 			0x04 // Length of the FIFO
#define rRegFIFOData 				0x05 // Data In/Out exchange register of FIFO buffer
#define rRegIRQ0 						0x06 // Interrupt register 0
#define rRegIRQ1 						0x07 // Interrupt register 1
#define rRegIRQ0En 					0x08 // Interrupt enable register 0
#define rRegIRQ1En 					0x09 // Interrupt enable register 1
#define rRegError 						0x0A // Error bits showing the error status of the last command execution
#define rRegStatus 					0x0B // Contains status of the communication
#define rRegRxBitCtrl 				0x0C // Control register for anticollision adjustments for bit oriented protocols
#define rRegRxColl 					0x0D // Collision position register
#define rRegTControl 				0x0E // Control of Timer 0..3
#define rRegT0Control 				0x0F // Control of Timer0
#define rRegT0ReloadHi 			0x10 // High register of the reload value of Timer0
#define rRegT0ReloadLo 			0x11 // Low register of the reload value of Timer0
#define rRegT0CounterValHi 	0x12 // Counter value high register of Timer0
#define rRegT0CounterValLo 	0x13 // Counter value low register of Timer0
#define rRegT1Control 				0x14 // Control of Timer1
#define rRegT1ReloadHi 			0x15 // High register of the reload value of Timer1
#define rRegT1ReloadLo 			0x16 // Low register of the reload value of Timer1
#define rRegT1CounterValHi 	0x17 // Counter value high register of Timer1
#define rRegT1CounterValLo 	0x18 // Counter value low register of Timer1
#define rRegT2Control 				0x19 // Control of Timer2
#define rRegT2ReloadHi 			0x1A // High byte of the reload value of Timer2
#define rRegT2ReloadLo 			0x1B // Low byte of the reload value of Timer2
#define rRegT2CounterValHi 	0x1C // Counter value high byte of Timer2
#define rRegT2CounterValLo 	0x1D // Counter value low byte of Timer2
#define rRegT3Control 				0x1E // Control of Timer3
#define rRegT3ReloadHi 			0x1F // High byte of the reload value of Timer3
#define rRegT3ReloadLo 			0x20 // Low byte of the reload value of Timer3
#define rRegT3CounterValHi 	0x21 // Counter value high byte of Timer3
#define rRegT3CounterValLo 	0x22 // Counter value low byte of Timer3
#define rRegT4Control 				0x23 // Control of Timer4
#define rRegT4ReloadHi 			0x24 // High byte of the reload value of Timer4
#define rRegT4ReloadLo 			0x25 // Low byte of the reload value of Timer4
#define rRegT4CounterValHi 	0x26 // Counter value high byte of Timer4
#define rRegT4CounterValLo 	0x27 // Counter value low byte of Timer4
#define rRegDrvMod 					0x28 // Driver mode register
#define rRegTxAmp 						0x29 // Transmitter amplifier register
#define rRegDrvCon 					0x2A // Driver configuration register
#define rRegTxl 							0x2B // Transmitter register
#define rRegTxCrcPreset 			0x2C // Transmitter CRC control register, preset value
#define rRegRxCrcPreset 			0x2D // Receiver CRC control register, preset value
#define rRegTxDataNum 				0x2E // Transmitter data number register
#define rRegTxModWidth 			0x2F // Transmitter modulation width register
#define rRegTxSym10BurstLen 	0x30 // Transmitter symbol 1 + symbol 0 burst length register
#define rRegTXWaitCtrl 			0x31 // Transmitter wait control
#define rRegTxWaitLo 				0x32 // Transmitter wait low
#define rRegFrameCon 				0x33 // Transmitter frame control
#define rRegRxSofD 					0x34 // Receiver start of frame detection
#define rRegRxCtrl 					0x35 // Receiver control register
#define rRegRxWait 					0x36 // Receiver wait register
#define rRegRxThreshold 			0x37 // Receiver threshold register
#define rRegRcv 							0x38 // Receiver register
#define rRegRxAna 						0x39 // Receiver analog register
#define rRegRFU_3A						0x3A // -
#define rRegSerialSpeed 			0x3B // Serial speed register
#define rRegLFO_Trimm 				0x3C // Low-power oscillator trimming register
#define rRegPLL_Ctrl 				0x3D // IntegerN PLL control register, for microcontroller clock output adjustment
#define rRegPLL_DivOut 			0x3E // IntegerN PLL control register, for microcontroller clock output adjustment
#define rRegLPCD_QMin 				0x3F // Low-power card detection Q channel minimum threshold
#define rRegLPCD_QMax 				0x40 // Low-power card detection Q channel maximum threshold
#define rRegLPCD_IMin 				0x41 // Low-power card detection I channel minimum threshold
#define rRegLPCD_I_Result 		0x42 // Low-power card detection I channel result register
#define rRegLPCD_Q_Result 		0x43 // Low-power card detection Q channel result register
#define rRegPadEn 						0x44 // PIN enable register
#define rRegPadOut 					0x45 // PIN out register
#define rRegPadIn 						0x46 // PIN in register
#define rRegSigOut 					0x47 // Enables and controls the SIGOUT Pin
#define rRegTxBitMod 				0x48 // Transmitter bit mode register
#define rRegRFU_49						0x49 // -
#define rRegTxDataCon 				0x4A // Transmitter data configuration register
#define rRegTxDataMod 				0x4B // Transmitter data modulation register
#define rRegTxSymFreq 				0x4C // Transmitter symbol frequency
#define rRegTxSym0H 					0x4D // Transmitter symbol 0 high register
#define rRegTxSym0L 					0x4E // Transmitter symbol 0 low register
#define rRegTxSym1H 					0x4F // Transmitter symbol 1 high register
#define rRegTxSym1L 					0x50 // Transmitter symbol 1 low register
#define rRegTxSym2 					0x51 // Transmitter symbol 2 register
#define rRegTxSym3 					0x52 // Transmitter symbol 3 register
#define rRegTxSym10Len 			0x53 // Transmitter symbol 1 + symbol 0 length register
#define rRegTxSym32Len 			0x54 // Transmitter symbol 3 + symbol 2 length register
#define rRegTxSym10BurstCtrl 0x55 // Transmitter symbol 1 + symbol 0 burst control register
#define rRegTxSym10Mod 			0x56 // Transmitter symbol 1 + symbol 0 modulation register
#define rRegTxSym32Mod 			0x57 // Transmitter symbol 3 + symbol 2 modulation register
#define rRegRxBitMod 				0x58 // Receiver bit modulation register
#define rRegRxEofSym 				0x59 // Receiver end of frame symbol register
#define rRegRxSyncValH 			0x5A // Receiver synchronisation value high register
#define rRegRxSyncValL 			0x5B // Receiver synchronisation value low register
#define rRegRxSyncMod 				0x5C // Receiver synchronisation mode register
#define rRegRxMod 						0x5D // Receiver modulation register
#define rRegRxCorr 					0x5E // Receiver correlation register
#define rRegFabCal 					0x5F // Calibration register of the receiver, calibration performed at production
#define rReg_60 							0x60 //
#define rReg_61 							0x61 //
#define rReg_66 							0x66 //
#define rReg_6A 							0x6A //
#define rReg_6B 							0x6B //
#define rReg_6C 							0x6C //
#define rReg_6D 							0x6D //
#define rReg_6E 							0x6E //
#define rReg_6F 							0x6F //
#define rRegVersion 					0x7F // Version and subversion register
//
//		Command 			No. Parameter (bytes) 	Short description
#define RC663_Idle 				0x00 //- 					no action, cancels current command execution
#define RC663_LPCD 				0x01 //- 					low-power card detection
#define RC663_LoadKey 		0x02 //(keybyte1..6); 		reads a MIFARE key (size of 6 bytes) from FIFO buffer and puts it into Key buffer
#define RC663_MFAuthent 	0x03 //60h or 61h,(block address),(card serial number byte0..3) 	performs the MIFARE standard authentication in MIFARE read/write mode only
#define RC663_AckReq 			0x04 //- 					performs a query, an Ack and a Req-Rn for ISO/IEC 18000-3 mode 3/ EPC Class-1 HF
#define RC663_Receive 		0x05 //- 					activates the receive circuit
#define RC663_Transmit 		0x06 //- 					transmits data from the FIFO buffer
#define RC663_Transceive 	0x07 //- 					transmits data from the FIFO buffer and automatically activates the receiver after transmission finished
#define RC663_WriteE2 		0x08 //addressH, addressL, data; 	gets one byte from FIFO buffer and writes it to the internal EEPROM, 
#define RC663_WriteE2Page 0x09 //(page Address), data0, [data1..data63]; 	gets up to 64 bytes (one EEPROM page) from the FIFO buffer and writes it to the EEPROM
#define RC663_ReadE2 			0x0A // address H, addressL,length; 	reads data from the EEPROM and copies it into the FIFO buffer
#define RC663_LoadReg 		0x0C //(EEPROM addressL), (EEPROM addressH), RegAdr, (number of Register to be copied);  reads data from the internal EEPROM and initializes the CLRC663 registers. EEPROM address needs to be within EEPROM sector 2
#define RC663_LoadProtocol 0x0D //(Protocol number RX), (Protocol number TX);		reads data from the internal EEPROM and initializes the CLRC663 registers needed for a Protocol change
#define RC663_LoadKeyE2 	0x0E //KeyNr; 				copies a key of the EEPROM into the key buffer
#define RC663_StoreKeyE2 	0x0F //KeyNr, byte1..6;	stores a MIFARE key (size of 6 bytes) into the EEPROM
#define RC663_ReadRNR 		0x1C //- 					Copies bytes from the Random Number generator into the FIFO until the FiFo is full
#define RC663_Soft_Reset 	0x1F //- 					resets the CLRC663//
void delay_init(u8 SYSCLK);
void delay_us(u32);
void delay_ms(u16);void RC663_Init(void);
u8 RC663_ReadReg(u8);
void RC663_WriteReg(u8, u8);s8 RC663_CMD_ReadE2(u16 addr,u8 len,u8 *pdat);
s8 RC663_CMD_WriteE2(u16 addr,u8 dat);
s8 RC663_CMD_LoadProtocol(u8 rx,u8 tx);
s8 RC663_PcdConfigISOType(u8 type);
void RC663_MifareClassic(void);
void RC663_ID2(void);
void RC663_Felica(void);
void RC663_ISO15693(void);s8 RC663_Lpcd_Calib(u8 *pI,u8 *pQ);
s8 RC663_Lpcd_Det(u8 ValueI,u8 ValueQ);#endif

#include “RC663.h”
#include “nfc.h”
#include <stdio.h>
#include <string.h>

static u8 fac_us=0;
static u16 fac_ms=0;

//delay
void delay_ns(u32 ns)
{
u32 i;
for(i=0;i<ns;i++)
{
__nop();
__nop();
__nop();
}
}

void delay_init(u8 SYSCLK) //unit:MHz
{
SysTick->CTRL &= 0xfffffffb;//select internal clk: HCLK/8
fac_us = SYSCLK/8;
fac_ms = (u16)fac_us*1000;
}

void delay_us(u32 Nus)
{
SysTick->LOAD=Nus*fac_us; //load time
SysTick->CTRL|=0x01; //start count
while(!(SysTick->CTRL&(1<<16)));//wait time out
SysTick->CTRL=0X00000000; //close counter
SysTick->VAL=0X00000000; //clear counter
}

void delay_ms(u16 nms) //nms <= 0xffffff8/SYSCLK; for 72M, Nms<=1864
{
SysTick->LOAD=(u32)nms
fac_ms;
SysTick->CTRL|=0x01;
while(!(SysTick->CTRL&(1<<16)));
SysTick->CTRL&=0XFFFFFFFE;
SysTick->VAL=0X00000000;
}

/
void RC663_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
u8 temp;

GPIO_InitStructure.GPIO_Pin = PDOWN;	 					//PA8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
GPIO_Init(GPIOA, &GPIO_InitStructure);
PDOWN_1;GPIO_InitStructure.GPIO_Pin = RC663_IRQ;  					//PB11	
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 		 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);/* Enable AFIO clock */	
/* Connect EXTI9 Line to PC.9 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);	 //IRQ
/* Configure EXTI6 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line11; // pb11
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	//falling edge of IRQ result interrupt
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);	//IFSEL0,IFSEL1:0 1
//RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );
GPIO_InitStructure.GPIO_Pin = RC663_NSS;	 			
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
GPIO_Init(GPIOB, &GPIO_InitStructure);					 
RC663_NSS_1;			             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//SPI_BaudRatePrescaler_64;	
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	
SPI_InitStructure.SPI_CRCPolynomial = 7;	
SPI_Init(SPI2, &SPI_InitStructure);  
SPI_Cmd(SPI2, ENABLE); PDOWN_0;	//	->RESET
delay_ms(30);
temp = RC663_ReadReg(rRegVersion);

#ifdef UART_PRINT
printf(“version: %X\n”,temp);
#endif
}

//
u8 RC663_SPIWriteByte(u8 Byte)
{
while((SPI2->SR&0X02)==0);
SPI2->DR=Byte;
while((SPI2->SR&0X01)==0);
return SPI2->DR;
}

/

void RC663_WriteReg(u8 Address, u8 value)
{
RC663_NSS_0;
RC663_SPIWriteByte(Address<<1);
RC663_SPIWriteByte(value);
RC663_NSS_1;
delay_ns(10);
}

u8 RC663_ReadReg(u8 Address)
{
u8 ucResult=0;
RC663_NSS_0;
RC663_SPIWriteByte((Address<<1)|0x01);
ucResult = RC663_SPIWriteByte(0);
RC663_NSS_1;
delay_ns(10);
return ucResult;
}

void RC663_SetBitMask(u8 reg,u8 mask)
{
u8 tmp = RC663_ReadReg(reg);
RC663_WriteReg(reg,tmp | mask);
}

void RC663_ClearBitMask(u8 reg,u8 mask)
{
u8 tmp = RC663_ReadReg(reg);
RC663_WriteReg(reg, tmp & ~mask);
}

void RC663_SetRawRC(u8 reg,u8 mask,u8 set)
{
u8 temp = RC663_ReadReg(reg);
temp = (temp&mask)|set;
RC663_WriteReg(reg,temp);
}
///
void RC663_FlushFifo()
{
RC663_SetBitMask(rRegFIFOControl,0x10);
}

void RC663_FieldOn()
{
RC663_SetBitMask(rRegDrvMod,0x08);
}

void RC663_FieldOff()
{
RC663_ClearBitMask(rRegDrvMod,0x08);
}

void RC663_FieldReset()
{
RC663_FieldOff();
delay_ms(20);
RC663_FieldOn();
delay_ms(20);
}

extern u8 Status_INT;
u8 mode;
s8 RC663_Command_Int(struct TranSciveBuffer *pi)
{
u16 i;
u8 j,n;
RC663_WriteReg(rRegCommand,RC663_Idle);
RC663_SetBitMask(rRegFIFOControl,0x10); //FlushFifo
RC663_WriteReg(rRegIRQ0,0x7F);
RC663_WriteReg(rRegIRQ1,0x7F);

for(n=0;n<pi->Length;n++)RC663_WriteReg(rRegFIFOData, pi->Data[n]);
if(pi->Command&0x80)
{RC663_WriteReg(rRegIRQ0En,0x90);		if(mode)RC663_WriteReg(rRegIRQ1En,0xE0);		elseRC663_WriteReg(rRegIRQ1En,0xE8);		Status_INT=0;RC663_WriteReg(rRegCommand, pi->Command);while(Status_INT==0);				//wait for IRQStatus_INT=0;RC663_WriteReg(rRegIRQ0En,0x10);		if(mode)RC663_WriteReg(rRegIRQ1En,0x20);		elseRC663_WriteReg(rRegIRQ1En,0x28);		
}
elseRC663_WriteReg(rRegCommand, pi->Command);for(i=2000;i>0;i--)
{n = RC663_ReadReg(rRegIRQ0);	if(n&0x10) break;		//IDLEIRQ
}
if(i==0)return MI_ERR;
n = RC663_ReadReg(rRegFIFOLength);
for(j=0;j<n;j++)pi->Data[j]= RC663_ReadReg(rRegFIFOData);
return MI_OK;

}

s8 RC663_CMD_LoadProtocol(u8 rx,u8 tx)
{
struct TranSciveBuffer ComData;

ComData.Command = RC663_LoadProtocol;
ComData.Length = 2;
ComData.Data[0] = rx;
ComData.Data[1] = tx;return RC663_Command_Int(&ComData);

}

s8 RC663_CMD_LoadKey(u8* pkey)
{
struct TranSciveBuffer ComData;

ComData.Command = RC663_LoadKey;
ComData.Length = 6;
memcpy(ComData.Data,pkey,6);return RC663_Command_Int(&ComData);

}

s8 RC663_CMD_MfcAuthenticate(u8 auth_mode,u8 block,u8 *pSnr)
{
s8 status;
u8 reg;
struct TranSciveBuffer ComData;

ComData.Command = RC663_MFAuthent;
ComData.Length = 6;
ComData.Data[0] = auth_mode;
ComData.Data[1] = block;
memcpy(&ComData.Data[2],pSnr,4);status= RC663_Command_Int(&ComData);
if(status==MI_OK)
{reg = RC663_ReadReg(rRegStatus);if(!(reg&0x20))status=MI_AUTHERR;
}
return status;

}

s8 RC663_PcdConfigISOType(u8 type)
{
// u8 temp;
RC663_WriteReg(rRegT0Control,0x98); //Starts at the end of Tx. Stops after Rx of first data. Auto-reloaded. 13.56 MHz input clock.
RC663_WriteReg(rRegT1Control,0x92); //Starts at the end of Tx. Stops after Rx of first data. Input clock - cascaded with Timer-0.
RC663_WriteReg(rRegT2Control,0x20); //Timer used for LFO trimming
RC663_WriteReg(rRegT2ReloadHi,0x03); //
RC663_WriteReg(rRegT2ReloadLo,0xFF); //
RC663_WriteReg(rRegT3Control,0x00); //Not started automatically. Not reloaded. Input clock 13.56 MHz
if(type==‘A’)
{
RC663_WriteReg(rRegWaterLevel,0x10); //Set WaterLevel =(FIFO length -1)

	RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x80);	//Tx2Inv=1RC663_WriteReg(rRegTxAmp,0xC0);	// 0x00RC663_WriteReg(rRegDrvCon,0x09);	//01RC663_WriteReg(rRegTxl,0x05);	//RC663_WriteReg(rRegRxSofD,0x00);	//RC663_CMD_LoadProtocol(0,0);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x20); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0); // Symbol 1 and 0 burst lengths = 8 bits.RC663_WriteReg(rRegFrameCon,0xCF); // Start symbol=Symbol2, Stop symbol=Symbol3RC663_WriteReg(rRegRxCtrl,0x04); // Set Rx Baudrate 106 kBaud RC663_WriteReg(rRegRxThreshold,0x55); // Set min-levels for Rx and phase shift  //32 RC663_WriteReg(rRegRcv,0x12);	//RC663_WriteReg(rRegRxAna,0x0A); //0RC663_WriteReg(rRegDrvMod,0x81);//> MIFARE Crypto1 state is further disabled.RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x89);
}
else if(type=='B')
{RC663_WriteReg(rRegWaterLevel,0x10);	//Set WaterLevel =(FIFO length -1)RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x8F);	//Tx2Inv=1RC663_WriteReg(rRegTxAmp,0x0C);	// 0xCC	RC663_WriteReg(rRegDrvCon,0x01);	RC663_WriteReg(rRegTxl,0x05);	RC663_WriteReg(rRegRxSofD,0x00);	RC663_CMD_LoadProtocol(4,4);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x0A); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0); // Symbol 1 and 0 burst lengths = 8 bits.RC663_WriteReg(rRegTXWaitCtrl,1);	RC663_WriteReg(rRegFrameCon,0x05); RC663_WriteReg(rRegRxSofD,0xB2);RC663_WriteReg(rRegRxCtrl,0x34); // Set Rx Baudrate 106 kBaud RC663_WriteReg(rRegRxThreshold,0x9F); // Set min-levels for Rx and phase shift  0x7F RC663_WriteReg(rRegRcv,0x12);RC663_WriteReg(rRegRxAna,0x0a); //0x0a 0X0eRC663_WriteReg(rRegDrvMod,0x87);RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x8F);
}
else if(type=='F')
{RC663_WriteReg(rRegWaterLevel,0x10);	//Set WaterLevel =(FIFO length -1)RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x88);	//Tx2Inv=1RC663_WriteReg(rRegTxAmp,0x04);	//RC663_WriteReg(rRegDrvCon,0x01);	//RC663_WriteReg(rRegTxl,0x05);	//RC663_WriteReg(rRegRxSofD,0x00);	//RC663_CMD_LoadProtocol(8,8);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x00); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0x03); // Symbol 1 and 0 burst lengths = 8 bits.//RC663_WriteReg(rRegTXWaitCtrl,0xC0);	//RC663_WriteReg(rRegTxWaitLo,0);RC663_WriteReg(rRegFrameCon,0x01);//RC663_WriteReg(rRegRxSofD,0xB2);RC663_WriteReg(rRegRxCtrl,0x05); // Set Rx Baudrate 212 kBaud RC663_WriteReg(rRegRxThreshold,0x5C); // Set min-levels for Rx and phase shift  0x3C RC663_WriteReg(rRegRcv,0x12);RC663_WriteReg(rRegRxAna,0x02); //0xa  initial value 0x02RC663_WriteReg(rRegRxWait,0x86);RC663_WriteReg(rRegDrvMod,0x87);RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x8F);
}
else if(type=='V')
{RC663_WriteReg(rRegWaterLevel,0x10);	//Set WaterLevel =(FIFO length -1)RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x89);	//Tx2Inv=1 0x80RC663_WriteReg(rRegTxAmp,0x10);	//0	//0x04RC663_WriteReg(rRegDrvCon,0x09);	//0x01RC663_WriteReg(rRegTxl,0x0A);	//0x05RC663_WriteReg(rRegRxSofD,0x00);	//RC663_CMD_LoadProtocol(0x0A,0x0A);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x00); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0); // Symbol 1 and 0 burst lengths = 8 bits.//RC663_WriteReg(rRegTXWaitCtrl,0xC0);	//0x88//RC663_WriteReg(rRegTxWaitLo,0);	//0xa9RC663_WriteReg(rRegFrameCon,0x0F);//RC663_WriteReg(rRegRxSofD,0xB2);RC663_WriteReg(rRegRxCtrl,0x02); // Set Rx Baudrate 26 kBaud RC663_WriteReg(rRegRxThreshold,0x74); // Set min-levels for Rx and phase shift  RC663_WriteReg(rRegRcv,0x12);RC663_WriteReg(rRegRxAna,0x07); RC663_WriteReg(rRegRxWait,0x9C);	RC663_WriteReg(rRegDrvMod,0x81);RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x89);
}
return MI_OK;

}

s8 RC663_PcdComTransceive(struct TranSciveBuffer *pi)
{
s8 status= MI_ERR;
u16 i;
u8 reg1,temp,lastBits; //reg0,
u8 errReg;
// Terminate any running command.
RC663_WriteReg(rRegCommand,RC663_Idle); // 0x00 // Starts and stops command execution
RC663_SetBitMask(rRegFIFOControl,0x10); //Flush_FiFo 0x02 // Control register of the FIFO
// Clear all IRQ 0,1 flags
RC663_WriteReg(rRegIRQ0,0x7F);
RC663_WriteReg(rRegIRQ1,0x7F);

for(i=0;i<pi->Length;i++)RC663_WriteReg(rRegFIFOData,pi->Data[i]);           //  0x05 // Data In/Out exchange register of FIFO buffer
// Idle interrupt(Command terminated), RC663_BIT_IDLEIRQ=0x10
RC663_WriteReg(rRegIRQ0En,0x18);	//IdleIRQEn,TxIRQEn
RC663_WriteReg(rRegIRQ1En,0x42);	//Global IRQ,Timer1IRQEn
//>  Start RC663 command "Transcieve"=0x07. Activate Rx after Tx finishes.
RC663_WriteReg(rRegCommand,RC663_Transceive);do	

{
reg1 = RC663_ReadReg(rRegIRQ1); //07h //wait for TxIRQ
}while((reg1&0x40)==0); //GlobalIRQ

RC663_WriteReg(rRegIRQ0En,0x54);	//HiAlertIRQEN,IdleIRQEn,RxIRQEn
RC663_WriteReg(rRegIRQ1En,0x42);	//Global IRQ,Timer1IRQEnfor(i=8000;i>0;i--)
{reg1 = RC663_ReadReg(rRegIRQ1);	  //07h  //wait for RxIRQif(reg1&0x40) break;	//GlobalIRQ
}RC663_WriteReg(rRegIRQ0En,0);		
RC663_WriteReg(rRegIRQ1En,0);errReg = RC663_ReadReg(rRegError);
if(i==0)status = MI_QUIT;
else if(reg1&0x02)		//Timer1IRQstatus = MI_NOTAGERR;
else if( errReg)	  //0Bh
{if(errReg&0x04)status = MI_COLLERR;else if(errReg&0x01)status = MI_FRAMINGERR;elsestatus = MI_ERR;
}
else
{status = MI_OK;if (pi->Command == RC663_Transceive){temp = RC663_ReadReg(rRegFIFOLength);		 //04hlastBits = RC663_ReadReg(rRegRxBitCtrl) & 0x07;	 //0chif (lastBits)pi->Length = (temp-1)*8 + lastBits;elsepi->Length = temp*8;if (temp == 0)	temp = 1;if (temp > 250) temp = 250; //maxlen ...for (i=0; i<temp; i++)pi->Data[i] = RC663_ReadReg(rRegFIFOData);  //05h}
}
return status;

}
s8 RC663_PcdHaltA(void)
{
s8 status;
struct TranSciveBuffer ComData,*pi= &ComData;

ComData.Command = RC663_Transceive;
ComData.Length  = 2;
ComData.Data[0] = PICC_HALT;
ComData.Data[1] = 0;status = RC663_PcdComTransceive(pi);
if(status == MI_NOTAGERR)		//halt command has no responsestatus = MI_OK;
elsestatus = MI_ERR;
return status;

}

s8 RC663_PcdRequestA(u8 req_code,u8 *pTagType)
{
s8 status;
struct TranSciveBuffer ComData,*pi= &ComData;

RC663_WriteReg(rRegTxCrcPreset,0x18);  //0x2C Transmitter CRC control register, preset value
RC663_WriteReg(rRegRxCrcPreset,0x18);
RC663_WriteReg(rRegStatus,0);           //  0x0B  Contains status of the communicationRC663_WriteReg(rRegTXWaitCtrl,0xC0);	//0x31  TxWaitStart at the end of Rx data
RC663_WriteReg(rRegTxWaitLo,0x0B);	// 0x32   Set min.time between Rx and Tx or between two Tx   
// Set timeout for this command cmd. Init reload values for timers-0,1 
RC663_WriteReg(rRegT0ReloadHi,0x08); 	//2196/fc        0x10 // High register of the reload value of Timer0
RC663_WriteReg(rRegT0ReloadLo,0x94);            //0x11 // Low register of the reload value of Timer0
RC663_WriteReg(rRegT1ReloadHi,0);                     //0x15 // High register of the reload value of Timer1
RC663_WriteReg(rRegT1ReloadLo,0x40);	//timerout ~= 10ms      	0x16 // Low register of the reload value of Timer1RC663_WriteReg(rRegIRQ0,0x08);                          //	0x06 // Interrupt register 0
RC663_WriteReg(rRegRxWait,0x90);                            //0x36 // Receiver wait register
RC663_WriteReg(rRegTxDataNum,0x0F);  //7bit                      0x2E // Transmitter data number register//> Send the ReqA command
ComData.Command = RC663_Transceive;           //0x07 //- transmits data from the FIFO buffer and automatically activates the receiver after transmission finished
ComData.Length  = 1;
ComData.Data[0] = req_code;
FLAG_1;
status = RC663_PcdComTransceive(pi);
FLAG_0;
if (status == MI_OK)
{if(ComData.Length == 0x10){*pTagType     = ComData.Data[0];*(pTagType+1) = ComData.Data[1];}elsestatus = MI_VALERR;
}
//RC663_WriteReg(rRegTxDataNum,0x08);
return status;

}

s8 RC663_PcdAnticoll(u8 *pSnr)
{
s8 status ;
u8 i;
u8 ucBits,ucBytes;
u8 snr_check = 0;
u8 ucCollPosition = 0;
u8 ucTemp;
u8 ucSNR[5] = {0, 0, 0, 0 ,0};
struct TranSciveBuffer ComData,*pi = &ComData;

	RC663_WriteReg(rRegTxDataNum,0x08);
do
{ucBits = (ucCollPosition) % 8;if (ucBits != 0){ucBytes = ucCollPosition / 8 + 1;RC663_SetRawRC(rRegRxBitCtrl, 0x8f,ucBits<<4);RC663_SetRawRC(rRegTxDataNum, 0xf8,ucBits);}elseucBytes = ucCollPosition / 8;ComData.Command = RC663_Transceive;ComData.Data[0] = PICC_ANTICOLL1;ComData.Data[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F);for (i=0; i<ucBytes; i++)ComData.Data[i + 2] = ucSNR[i];ComData.Length = ucBytes + 2;status = RC663_PcdComTransceive(pi);ucTemp = ucSNR[(ucCollPosition / 8)];if (status == MI_COLLERR){for (i=0; i < 5 - (ucCollPosition / 8); i++)ucSNR[i + (ucCollPosition / 8)] = ComData.Data[i+1];ucSNR[(ucCollPosition / 8)] |= ucTemp;ucCollPosition = ComData.Data[0];}else if (status == MI_OK){for (i=0; i < (ComData.Length / 8); i++)ucSNR[4 - i] = ComData.Data[ComData.Length/8 - i - 1];ucSNR[(ucCollPosition / 8)] |= ucTemp;}
} while (status == MI_COLLERR);if (status == MI_OK)
{for (i=0; i<4; i++){   *(pSnr+i)  = ucSNR[i];snr_check ^= ucSNR[i];}if (snr_check != ucSNR[i])status = MI_COM_ERR;
}
return status;

}

s8 RC663_PcdSelect(u8 *pSnr,u8 *pSize)
{
s8 status;
u8 i,snr_check = 0;
struct TranSciveBuffer ComData,*pi = &ComData;

RC663_SetRawRC(rRegTxCrcPreset,0xfe,0x01);	//On
RC663_SetRawRC(rRegRxCrcPreset,0xfe,0x01);	//OnComData.Command = RC663_Transceive;
ComData.Length  = 7;
ComData.Data[0] = PICC_ANTICOLL1;
ComData.Data[1] = 0x70;
for (i=0; i<4; i++)
{snr_check ^= *(pSnr+i);ComData.Data[i+2] = *(pSnr+i);
}
ComData.Data[6] = snr_check;status = RC663_PcdComTransceive(pi);if (status == MI_OK)
{
if (ComData.Length != 0x8)status = MI_BITCOUNTERR;
else*pSize = ComData.Data[0];
}
return status;

}

s8 RC663_PcdRead(u8 addr,u8 *pReaddata)
{
s8 status;
struct TranSciveBuffer ComData,*pi = &ComData;

RC663_SetRawRC(rRegTxCrcPreset,0xfe,0x01);	//on
RC663_SetRawRC(rRegRxCrcPreset,0xfe,0x00);	//off

ComData.Command = RC663_Transceive;
ComData.Length = 2;
ComData.Data[0] = PICC_READ;
ComData.Data[1] = addr;

status = RC663_PcdComTransceive(pi);

if (status == MI_OK)
{
if (ComData.Length != 0x90)
status = MI_BITCOUNTERR;
else
memcpy(pReaddata, &ComData.Data[0], 16);
}
return status;
}

s8 RC663_PcdWrite(u8 addr,u8 *pWritedata)
{
s8 status;
struct TranSciveBuffer ComData,*pi = &ComData;

ComData.Command = RC663_Transceive;
ComData.Length  = 2;
ComData.Data[0] = PICC_WRITE;
ComData.Data[1] = addr;status = RC663_PcdComTransceive(pi);
if (status != MI_NOTAGERR)
{if(ComData.Length != 4)status=MI_BITCOUNTERR;else{ComData.Data[0] &= 0x0F;switch (ComData.Data[0]){case 0x00:status = MI_NOTAUTHERR;break;case 0x0A:status = MI_OK;break;default:status = MI_CODEERR;break;}}
}    
if (status == MI_OK)
{ComData.Command = RC663_Transceive;ComData.Length  = 16;memcpy(&ComData.Data[0], pWritedata, 16);status = RC663_PcdComTransceive(pi);if (status != MI_NOTAGERR){ComData.Data[0] &= 0x0F;switch(ComData.Data[0]){case 0x00:status = MI_WRITEERR;break;case 0x0A:status = MI_OK;break;default:status = MI_CODEERR;break;}}
}
return status;

}

void RC663_MifareClassic(void)
{
s8 status;
u8 i;
u8 M1_Data[7],RD_Data[16]; //CT:2 SN:4 SAK:1
static u8 KEY[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

RC663_PcdConfigISOType('A');
//delay_ms(10);
///mifare S50	
status = RC663_PcdRequestA(PICC_REQALL,M1_Data);

#ifdef UART_PRINT
printf(“ATQA: %d_”,status);
if(status==MI_OK)
printf(" %02X %02X",M1_Data[1],M1_Data[0]);
printf(“\n”);
#endif
if(status!=MI_OK) return;

status = RC663_PcdAnticoll(&M1_Data[2]);

#ifdef UART_PRINT
printf(“UID: %d_”,status);
if(status==MI_OK)
printf(“%02X %02X %02X %02X”,M1_Data[2],M1_Data[3],M1_Data[4],M1_Data[5]);
printf(“\n”);
#endif
if(status!=MI_OK) return;

status = RC663_PcdSelect(&M1_Data[2],&M1_Data[6]);

#ifdef UART_PRINT
printf(“SELECT: %d_”,status);
if(status==MI_OK)
printf(“%02X”,M1_Data[6]);
printf(“\n”);
#endif
if(status!=MI_OK) return;

status = RC663_CMD_LoadKey(KEY);

#ifdef UART_PRINT
printf(“LoadKey: %d\n”,status);
#endif
if(status!=MI_OK) return;
status = RC663_CMD_MfcAuthenticate(0x60,0,&M1_Data[2]);
#ifdef UART_PRINT
printf(“Auth: %d\n”,status);
#endif
if(status!=MI_OK) return;

status=RC663_PcdRead(1,RD_Data);

#ifdef UART_PRINT
printf(“READ:%d_”,status);
for(i=0;i<16;i++)
printf(" %02X",RD_Data[i]);
printf(“\n”);
#endif
if(status!=MI_OK) return;
/RD_Data[15]++;
status=RC663_PcdWrite(1,RD_Data);
#ifdef UART_PRINT
printf(“Write:%d --\n”,status);
#endif
if(status!=MI_OK) return;
status=RC663_PcdRead(1,RD_Data);
#ifdef UART_PRINT
printf(“READ:%d --”,status);
for(i=0;i<16;i++)
printf(" %2X “,RD_Data[i]);
printf(”\n");
//printf(“Please remove card!\n”);
#endif
/
//if(status!=MI_OK) return;
do
{
RC663_FieldOff();
delay_ms(10);
RC663_FieldOn();
//status = RC663_PcdHaltA();
LED_1;
delay_ms(10);
status = RC663_PcdRequestA(PICC_REQALL,M1_Data);
if(statusMI_OK)
{
LED_0;
}
else
break;
}while(status
MI_OK);
}


代码解释

首先先需要配置SPI的基本通讯,基本通讯参考STM32/GD32常规通讯即可
需要配置GPIO
1管脚
2SPI接口
3模式0或者模式3
可以配置外部触发,不过我没有配置,不影响通讯

void RC663_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;EXTI_InitTypeDef   EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;u8 temp;GPIO_InitStructure.GPIO_Pin = PDOWN;	 					//PA8GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		GPIO_Init(GPIOA, &GPIO_InitStructure);PDOWN_1;GPIO_InitStructure.GPIO_Pin = RC663_IRQ;  					//PB11	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 		 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);/* Enable AFIO clock */	/* Connect EXTI9 Line to PC.9 pin */GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);	 //IRQ/* Configure EXTI6 line */EXTI_InitStructure.EXTI_Line = EXTI_Line11; // pb11EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  	//falling edge of IRQ result interruptEXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);	//IFSEL0,IFSEL1:0 1//RCC_APB1PeriphClockCmd(	RCC_APB1Periph_SPI2,  ENABLE );GPIO_InitStructure.GPIO_Pin = RC663_NSS;	 			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		GPIO_Init(GPIOB, &GPIO_InitStructure);					 RC663_NSS_1;			             GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;//SPI_BaudRatePrescaler_64;	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	SPI_InitStructure.SPI_CRCPolynomial = 7;	SPI_Init(SPI2, &SPI_InitStructure);  SPI_Cmd(SPI2, ENABLE); PDOWN_0;	//	->RESETdelay_ms(30);temp = RC663_ReadReg(rRegVersion);
#ifdef UART_PRINTprintf("version: %X\n",temp);
#endif
}

然后就是配置SPI发送和接收函数

u8 RC663_SPIWriteByte(u8 Byte)
{while((SPI2->SR&0X02)==0);		 SPI2->DR=Byte;	 	            while((SPI2->SR&0X01)==0);     return SPI2->DR;        	  
}

然后配置写寄存器和读寄存器,包括寄存器位设置

void RC663_WriteReg(u8   Address, u8   value)
{  RC663_NSS_0;RC663_SPIWriteByte(Address<<1);RC663_SPIWriteByte(value);RC663_NSS_1;delay_ns(10);
}u8 RC663_ReadReg(u8   Address)
{u8  ucResult=0;RC663_NSS_0;RC663_SPIWriteByte((Address<<1)|0x01);ucResult = RC663_SPIWriteByte(0);RC663_NSS_1;delay_ns(10);return ucResult;
}void RC663_SetBitMask(u8   reg,u8   mask)  
{u8  tmp = RC663_ReadReg(reg);RC663_WriteReg(reg,tmp | mask);  
}void RC663_ClearBitMask(u8   reg,u8   mask)  
{u8  tmp = RC663_ReadReg(reg);RC663_WriteReg(reg, tmp & ~mask);  
}void RC663_SetRawRC(u8   reg,u8 mask,u8 set)
{u8 temp = RC663_ReadReg(reg);temp = (temp&mask)|set;RC663_WriteReg(reg,temp);
}

然后就是配置CLRC663的SPI寄存器初始化

请注意,由于13.56mhz通讯协议包括ISO14443A
ISO14443B 或者ISO15693 ,这几种的配置如下

s8 RC663_PcdConfigISOType(u8 type)
{
//	u8 temp;RC663_WriteReg(rRegT0Control,0x98); //Starts at the end of Tx. Stops after Rx of first data. Auto-reloaded. 13.56 MHz input clock.RC663_WriteReg(rRegT1Control,0x92); //Starts at the end of Tx. Stops after Rx of first data. Input clock - cascaded with Timer-0.RC663_WriteReg(rRegT2Control,0x20); //Timer used for LFO trimmingRC663_WriteReg(rRegT2ReloadHi,0x03);	//RC663_WriteReg(rRegT2ReloadLo,0xFF);	//RC663_WriteReg(rRegT3Control,0x00);	//Not started automatically. Not reloaded. Input clock 13.56 MHz	if(type=='A'){RC663_WriteReg(rRegWaterLevel,0x10);	//Set WaterLevel =(FIFO length -1)RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x80);	//Tx2Inv=1RC663_WriteReg(rRegTxAmp,0xC0);	// 0x00RC663_WriteReg(rRegDrvCon,0x09);	//01RC663_WriteReg(rRegTxl,0x05);	//RC663_WriteReg(rRegRxSofD,0x00);	//RC663_CMD_LoadProtocol(0,0);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x20); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0); // Symbol 1 and 0 burst lengths = 8 bits.RC663_WriteReg(rRegFrameCon,0xCF); // Start symbol=Symbol2, Stop symbol=Symbol3RC663_WriteReg(rRegRxCtrl,0x04); // Set Rx Baudrate 106 kBaud RC663_WriteReg(rRegRxThreshold,0x55); // Set min-levels for Rx and phase shift  //32 RC663_WriteReg(rRegRcv,0x12);	//RC663_WriteReg(rRegRxAna,0x0A); //0RC663_WriteReg(rRegDrvMod,0x81);//> MIFARE Crypto1 state is further disabled.RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x89);}else if(type=='B'){RC663_WriteReg(rRegWaterLevel,0x10);	//Set WaterLevel =(FIFO length -1)RC663_WriteReg(rRegRxBitCtrl,0x80);	//Received bit after collision are replaced with 1.RC663_WriteReg(rRegDrvMod,0x8F);	//Tx2Inv=1RC663_WriteReg(rRegTxAmp,0x0C);	// 0xCC	RC663_WriteReg(rRegDrvCon,0x01);	RC663_WriteReg(rRegTxl,0x05);	RC663_WriteReg(rRegRxSofD,0x00);	RC663_CMD_LoadProtocol(4,4);// Disable Irq 0,1 sourcesRC663_WriteReg(rRegIRQ0En,0);RC663_WriteReg(rRegIRQ1En,0);RC663_WriteReg(rRegFIFOControl,0xB0);RC663_WriteReg(rRegTxModWidth,0x0A); // Length of the pulse modulation in carrier clks+1  RC663_WriteReg(rRegTxSym10BurstLen,0); // Symbol 1 and 0 burst lengths = 8 bits.RC663_WriteReg(rRegTXWaitCtrl,1);	RC663_WriteReg(rRegFrameCon,0x05); RC663_WriteReg(rRegRxSofD,0xB2);RC663_WriteReg(rRegRxCtrl,0x34); // Set Rx Baudrate 106 kBaud RC663_WriteReg(rRegRxThreshold,0x9F); // Set min-levels for Rx and phase shift  0x7F RC663_WriteReg(rRegRcv,0x12);RC663_WriteReg(rRegRxAna,0x0a); //0x0a 0X0eRC663_WriteReg(rRegDrvMod,0x87);RC663_WriteReg(rRegStatus,0);//>  FieldOnRC663_WriteReg(rRegDrvMod,0x8F);}

然后就可以编写CLRC663轮询函数了
轮询思路
控制寄存器,使能芯片,天线工作识别芯片返回数据
检查返回数据是否正常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打破误解:走近轻度自闭症患者的真实生活

在自闭症的广阔光谱中&#xff0c;轻度自闭症是一个相对温和但又不可忽视的存在。它像是一层薄薄的雾&#xff0c;轻轻笼罩在患者的世界里&#xff0c;既不影响他们基本的生存能力&#xff0c;又在一定程度上影响着他们的社交互动、情感表达及兴趣范围。 轻度自闭症患者往往能…

【Android】Android模拟器抓包配置

从Android7.0之后开始&#xff0c;用户自行安装的证书在用户目录下&#xff0c;无法进行证书信任&#xff0c;导致Charles无法进行https抓包 方案&#xff1a; 1. 获取手机root权限 有些模拟器可以直接开启root权限&#xff1b; 有些Android手机可以直接开启root权限。 2. …

【ai】学习笔记:电影推荐1:协同过滤 TF-DF 余弦相似性

2020年之前都是用协同过滤2020年以后用深度学习、人工智能视频收费的,不完整,里面是电影推荐 这里有个视频讲解2016年大神分析了电影推荐 :MovieRecommendation github地址 看起来是基于用户的相似性和物品的相似性,向用户推荐物品: 大神的介绍: 大神的介绍: 基于Pytho…

Python3 基础语法快速入门

目录&#xff1a; 一、概述二、运行1、终端启动 Python3 交互式解释器直接执行&#xff1a;2、.py 文件运行&#xff1a;3、可执行文件运行&#xff1a; 三、基础语法1、Python 中文编码&#xff1a;2、注释&#xff1a;3、print 输出&#xff1a;4、变量赋值&#xff1a;5、行…

tcp协议下的socket函数

目录 1.socket函数 2.地址转换函数 1.字符串转in_addr的函数:​编辑 2.in_addr转字符串的函数&#xff1a;​编辑 1.关于inet_ntoa函数 3.listen函数 4.简单的Server模型 1.初步模型 1.sock函数和accept函数返回值的sockfd的区别 2.运行结果和127.0.0.1的意义 2.单进…

【游戏/社交】BFS算法评价用户核心程度or人群扩量(基于SparkGraphX)

【游戏/社交】BFS算法评价用户核心程度or人群扩量&#xff08;基于SparkGraphX&#xff09; 在游戏和社交网络领域&#xff0c;评估用户的核心程度或进行人群扩量是提升用户粘性和拓展社交圈的关键。广度优先搜索&#xff08;BFS&#xff09;算法以其在图结构中评估节点重要性…

[C/C++入门][变量和运算]9、数据类型以及占用存储空间大小

我们都知道&#xff0c;C中包含了多种数据类型 数据类型占用字节数中文名称注释char1字符型存储单个字符&#xff0c;通常为8位。signed char1有符号字符型字符型的有符号版本&#xff0c;可用于表示-128至127之间的整数。unsigned char1无符号字符型字符型的无符号版本&#…

SpringAI简单使用(本地模型+自定义知识库)

Ollama 简介 Ollama是一个开源的大型语言模型服务工具&#xff0c;它允许用户在本地机器上构建和运行语言模型&#xff0c;提供了一个简单易用的API来创建、运行和管理模型&#xff0c;同时还提供了丰富的预构建模型库&#xff0c;这些模型可以轻松地应用在多种应用场景中。O…

arm 内联汇编基础

一、 Arm架构寄存器体系熟悉 基于arm neon 实现的代码有 intrinsic 和inline assembly 两种实现。 1.1 通用寄存器 arm v7 有 16 个 32-bit 通用寄存器&#xff0c;用 r0-r15 表示。 arm v8 有 31 个 64-bit 通用寄存器&#xff0c;用 x0-x30 表示&#xff0c;和 v7 不一样…

如何在 PostgreSQL 中处理海量数据的存储和检索?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 如何在 PostgreSQL 中处理海量数据的存储和检索&#xff1f;一、优化表结构设计二、分区技术三、数据压…

ceph log内容解析

log内容构造 如osd的一条log 分别表示 时间戳 线程id 日志等级 子模块 内容实体 剖析源码实现 每条log都是由一个Entry构成 定义在src/log/entry.h中 Entry(short pr, short sub) :m_stamp(clock().now()), // 打印日志时的时间戳m_thread(pthread_self()), // 打印日志的线…

【精品资料】智慧物流园区整体架构方案(46页PPT)

引言&#xff1a;智慧物流园区整体架构方案是一个集现代信息技术、物联网、大数据、云计算及人工智能等前沿科技于一体的综合性物流园区建设蓝图。该方案旨在通过高度集成和智能化的系统&#xff0c;优化物流流程&#xff0c;提升运营效率&#xff0c;降低运营成本&#xff0c;…

智慧新零售移动端收银视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

“信息科技风险管理”和“IT审计智能辅助”两个大模块的部分功能详细介绍:

数字风险赋能中心简介 数字风险赋能中心简介 &#xff0c;时长05:13 大家好&#xff01;我是AI主播安欣&#xff0c;我给大家介绍一下数字风险赋能中心。 大家都知道当前我国政企机构的数字化转型已经进入深水区&#xff0c;数字化转型在给我们带来大量创新红利的同时&#xf…

2024年第二季度 DDoS 威胁趋势报告

2024 年上半年&#xff0c;Cloudflare 缓解了 850 万次 DDoS 攻击&#xff1a;第一季度 450 万次&#xff0c;第二季度 400 万次。总体而言&#xff0c;第二季度 DDoS 攻击数量环比下降了 11%&#xff0c;但同比增长了 20%。 DDoS 攻击分布&#xff08;按类型和手段&#xff09…

Python+Django+MySQL的新闻发布管理系统【附源码,运行简单】

PythonDjangoMySQL的新闻发布管理系统【附源码&#xff0c;运行简单】 总览 1、《新闻发布管理系统》1.1 方案设计说明书设计目标工具列表 2、详细设计2.1 登录2.2 程序主页面2.3 新闻新增界面2.4 文章编辑界面2.5 新闻详情页2.7 其他功能贴图 3、下载 总览 自己做的项目&…

破解打家劫舍:动态规划与二分查找的高效算法

目录 198. 打家劫舍 解法一:一维动态规划 解法二&#xff1a;二维动态规划 213. 打家劫舍 II 思路分析 代码实现 337. 打家劫舍 III 思路分析 代码实现 2560. 打家劫舍 IV 思路分析 参考博客 198. 打家劫舍 如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统…

【Qt】QWidget核心属性相关API

目录 一. enabled——是否可用 二. geometry——几何位置 window frame 三. windowTitle——窗口标题 四. windowIcon——窗口图标 ​qrc文件 五. windowOpacity——透明度 六. cursor——光标 自定义光标 七. font——字体 八. toolTip——提示栏 九. focusPolic…

【QT】QT 概述(背景介绍、搭建开发环境、Qt Creator、程序、项目文件解析、编程注意事项)

一、Qt 背景介绍 1、什么是 Qt Qt 是一个跨平台的 C 图形用户界面应用程序框架。 它为应用程序开发者提供了建立艺术级图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展。Qt 为开发者提供了一种基于组件的开发模式&#xff0c;开发者可以通过简单的拖拽和…

天空星LVGL移植记录

一、移植的LVGL版本8.2 下载地址&#xff1a;&#xff08;网页下个加速脚本&#xff09;GitHub - lvgl/lvgl: Embedded graphics library to create beautiful UIs for any MCU, MPU and display type.https://github.com/lvgl/lvgl 二、硬件设备 天空星STM32F407VET6 ILI9…