首页 > 其他分享 >基于cv627的非接通讯M1

基于cv627的非接通讯M1

时间:2022-10-05 14:56:13浏览次数:42  
标签:return cv627 0x00 uint8 非接 txbuff M1 WriteByte Reg

基于CV627的非接通讯系列之(一)

CV627读写M1卡

知识点:

  1. 芯片特性及通讯
  2. 14443协议
  3. 针对不同类型卡不同读写流程
  4. 卡类型区分

扩展:

PBOC协议

非接读卡技术火了多年,小熊猫最近也在研究,就准备了一期来介绍一下(只讲解开发RFID过程的大体流程及遇上的困难)。

硬件部分:我是使用的RC630(NXP)作为读卡的芯片,该芯片支持波特率101 212 424 848(kbit/s),将近100个寄存器,FIFO缓存512byte,支持NFC点对点传输。支持SPI,I2C,串口通讯方式。

我选择SPI作为硬件通讯渠道。众所周知,RFID通讯遵循14443协议。

读卡流程如下:

先寻卡——防碰撞——获取卡UID——选卡——往下就根据卡不同而不同了。如下图

这期先讲M1卡读卡,下期讲CPU卡:

上代码:

底层驱动:

#include "spi.h"

#include "MFRC630.h"

#include "stdio.h"

#define RF_RST_Write(N) HAL_GPIO_WritePin(RST_PDOWN_GPIO_Port, RST_PDOWN_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)

#define SPI2_CS_Write(N) HAL_GPIO_WritePin(SPI2_NSS_GPIO_Port, SPI2_NSS_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)

/******************************************************************************

*模拟SPI读写一个字

*******************************************************************************

static uint8_t ret;

uint8_t SPI2_RW_Byte(uint8_t byte)

{

HAL_SPI_TransmitReceive(&hspi2, &byte, &ret, 1, 10);

return ret;

}

static void WriteByte(uint8_t addr,uint8_t v)

{

SPI2_CS_Write(0);

SPI2_RW_Byte(addr << 1);

SPI2_RW_Byte(v);

SPI2_CS_Write(1);

}

static uint8_t ReadByte(uint8_t addr)

{

uint8_t data;

SPI2_CS_Write(0);

SPI2_RW_Byte((addr << 1) | 1);

data = SPI2_RW_Byte(0x00);

SPI2_CS_Write(1);

return data;

}

/*****************************************************************************

*设置寄存器的位

******************************************************************************/

void SetBitMask(uint8_t addr, uint8_t mask)

{

uint8_t temp;

temp = ReadByte(addr); //

WriteByte(addr, temp | mask);

}

/******************************************************************************

*清除寄存器的位

******************************************************************************/

void ClrBitMask(uint8_t addr, uint8_t mask)

{

uint8_t temp;

temp = ReadByte(addr); //

WriteByte(addr, temp & ~mask);

}

void MFRC630_SetIRQpin(unsigned char value)

{

WriteByte(IRQ1En_Reg,0xc0);

WriteByte(IRQ0En_Reg,value);

}

/******************************************************************************

*中间函数

******************************************************************************/

int MFRC663_Exchange1(uint8_t *pTxBuffer,uint8_t wTxLength,uint8_t *pRxBuffer,uint8_t * pRxLength,int timeout,uint8_t crc)

{

uint8_t temp;

int i,j;

WriteByte(IRQ0_Reg,0x7f);

WriteByte(IRQ0En_Reg,0x18);

 

if(crc)

{

WriteByte(TxCrcPreset_Reg,0x19);

}

ExchangeCommand(PCD_TRANSCEIVE,pTxBuffer,wTxLength);

 

HAL_Delay(5);

uint8_t cError = ReadByte(Error_Reg);

for(i = 0 ; i < timeout ; i ++)

{

if((ReadByte(IRQ0_Reg) & 0x18) == 0x18)

break;

HAL_Delay(1);

}

 

if(i == timeout)

{

//printf("printf timeout");

if(crc)

{

WriteByte(TxCrcPreset_Reg,0x18);

}

return - 1;

}

 

if(crc)

{

temp = ReadByte(FIFOLength_Reg);

uint8_t n2 = ReadByte(RxBitCtrl_Reg) & 0x07;

if (n2 != 0)

{

temp = (temp - 1) * 8 + n2;

}

else ;

 

for (j = 0; j < temp; j++)

{

pRxBuffer[j] = ReadByte(FIFOData_Reg);

}

}

 

*pRxLength = temp;

 

if(crc)

{

WriteByte(TxCrcPreset_Reg,0x18);

}

 

return 0;

}

void ExchangeCommand(uint8_t cmd,uint8_t *buff,uint8_t len)

{

uint8_t i , temp ;

 

WriteByte(Command_Reg,PCD_IDLE);

temp = ReadByte(FIFOControl_Reg);

WriteByte(FIFOControl_Reg,temp | 0x10);

 

for(i = 0 ; i < len ; i ++)

{

WriteByte(FIFOData_Reg,buff[i]);

}

 

WriteByte(Command_Reg,cmd);

}

/******************************************************************************

*寄存器初始化

******************************************************************************/

static void Reg_Init(void)

{

 

WriteByte(DrvMode_Reg,0x8e);

WriteByte(TxAmp_Reg,0x12); //12

WriteByte(DrvCon_Reg,0x39);

WriteByte(TxI_Reg,0x0a);

WriteByte(TxCrcPreset_Reg,0x18);

WriteByte(RxCrcPreset_Reg,0x18);

WriteByte(TxDataNum_Reg,0x0f);

WriteByte(TxModWidth_Reg,0x21);

WriteByte(TxSym10BurstLen_Reg,0x00);

WriteByte(TXWaitCtrl_Reg,0xc0);

WriteByte(TxWaitLo_Reg,0x12);

WriteByte(FrameCon_Reg,0xcf);

WriteByte(RxSofD_Reg,0x00);

WriteByte(RxCtrl_Reg,0x04);

WriteByte(RxWait_Reg,0x90);

WriteByte(RxThreshold_Reg,0x5c);

WriteByte(Rcv_Reg,0x12);

}

void MFRC630_Init(void)

{

/*???*/

RF_RST_Write(1);

HAL_Delay(2);

RF_RST_Write(0);

HAL_Delay(2);

}

/******************************************************************************

*PCD初始化

******************************************************************************/

void PCD_Init(void)

{

MFRC630_Init();

uint8_t txbuff[] = {PICC_REQALL, 0x00,0x00, 0x00, 0x00, 0x00, 0x00};

HAL_Delay(10);

LoadProtocol(Protocol106,Protocol106);

 

Reg_Init();

}

/******************************************************************************

*设置协议

******************************************************************************/

void LoadProtocol(uint8_t rxProtocol,uint8_t txProtocol)

{

WriteByte(IRQ0_Reg,0x7f);

WriteByte(IRQ0En_Reg,0x10);

 

WriteByte(FIFOData_Reg,rxProtocol);

WriteByte(FIFOData_Reg,txProtocol);

WriteByte(Command_Reg,PCD_LOADPROTOCOL);

 

while(!(ReadByte(IRQ0_Reg) & 0x10));

}

/******************************************************************************

*寻卡

******************************************************************************/

uint8_t FindCard(uint8_t mode)

{

uint8_t txbuff ;

uint8_t rxbuff[2];

uint8_t rxLen = 2;

 

if(mode == 0)

{

txbuff = PICC_REQIDL;

}

else

{

txbuff = PICC_REQALL;

}

WriteByte(Status_Reg,0x00);

WriteByte(TxDataNum_Reg,0x0f);

if(MFRC663_Exchange(&txbuff,1,rxbuff,&rxLen,2,0) == 0)

{

WriteByte(TxDataNum_Reg,0x08);

return rxbuff[0];

}

WriteByte(TxDataNum_Reg,0x08);

return -1;

}

/******************************************************************************

*获取卡UID

******************************************************************************/

uint8_t GetCardUid(uint8_t *uid)

{

uint8_t txbuff[] = {PICC_ANTICOLL1,0x20};

uint8_t rxbuff[5];

uint8_t rxLen = 5;

uint8_t temp;

 

temp = ReadByte(RxBitCtrl_Reg);

WriteByte(RxBitCtrl_Reg,0x00);

 

if(MFRC663_Exchange(txbuff,2,rxbuff,&rxLen,10,0) == 0)

{

WriteByte(RxBitCtrl_Reg,temp);

temp = rxbuff[0] ^ rxbuff[1] ^ rxbuff[2] ^ rxbuff[3] ;

if(rxbuff[4] == temp)

{

uid[0] = rxbuff[0];

uid[1] = rxbuff[1];

uid[2] = rxbuff[2];

uid[3] = rxbuff[3];

return 4;

}

return -1;

}

WriteByte(RxBitCtrl_Reg,temp);

return -1;

}

/******************************************************************************

*选卡

******************************************************************************/

uint8_t SelectCard(uint8_t *uid)

{

uint8_t txbuff[9];

uint8_t rxlen = 18;

uint8_t rxbuff[0x18];

uint8_t i;

 

txbuff[0] = PICC_ANTICOLL1;

txbuff[1] = 0x70;

txbuff[6] = 0;

 

for(i = 0 ; i < 4 ; i ++)

{

txbuff[i+2] = uid[i];

txbuff[6] ^= uid[i];

}

if(MFRC663_Exchange(txbuff,7,rxbuff,&rxlen,100,1) == 0)

{

return 0;

}

return -1;

}

uint8_t LoadKey(uint8_t *key)

{

WriteByte(IRQ0_Reg,0x7f);

WriteByte(IRQ0En_Reg,0x10);

ExchangeCommand(PCD_LOADKEY,key,6);

while(!(ReadByte(IRQ0_Reg) & 0x10));

return 0;

}

/******************************************************************************

*认证

******************************************************************************/

uint8_t AuthentBlock(uint8_t mode,uint8_t block,uint8_t *uid,uint8_t *key)

{

uint8_t i;

uint8_t buff[6];

 

LoadKey(key);

 

if(mode == 0)

{

buff[0] = 0x60;

}

else

{

buff[0] = 0x61;

}

buff[1] = block;

memcpy(buff + 2,uid,4);

 

WriteByte(IRQ0_Reg,0x7f);

WriteByte(IRQ0En_Reg,0x18);

 

ExchangeCommand(PCD_MFAUTHENT,buff,6);

HAL_Delay(2);

if(i == 50)

{

//return - 1;

}

 

if(ReadByte(Status_Reg) & 0x20)

return 0;

 

return -1;

}

/******************************************************************************

*写区

******************************************************************************/

uint8_t WriteSection(uint8_t addr,uint8_t *pData)

{

uint8_t txbuff[2];

uint8_t rxlen = 3;

uint8_t rxbuff[3];

 

txbuff[0] = PICC_WRITE;

txbuff[1] = addr;

 

if(MFRC663_Exchange(txbuff,2,rxbuff,&rxlen,100,1) == -1)

{

return -1;

}

 

if((rxbuff[0] & 0x0F) != 0x0A)

{

return -1;

}

rxlen = 3;

if(MFRC663_Exchange(pData,16,rxbuff,&rxlen,100,1) == -1)

{

return -1;

}

 

if((rxbuff[0] & 0x0F) != 0x0A){

return -1;

}

return 0;

}

/******************************************************************************

*读区

******************************************************************************/

uint8_t ReadSection(uint8_t addr,uint8_t *pData)

{

uint8_t txbuff[2];

uint8_t rxlen = 16;

 

txbuff[0] = PICC_READ;

txbuff[1] = addr;

 

if(MFRC663_Exchange(txbuff,2,pData,&rxlen,100,1) == -1)

{

return -1;

}

 

return 0;

}

Main调用

#include "main.h"

#include "spi.h"

#include "usart.h"

#include "gpio.h"

#include "stdio.h"

#include "MFRC630.h"

void SystemClock_Config(void);

/*=================================================================

=================================================================*/

void SetArray(uint8_t* A,uint8_t value,uint8_t length)

{

uint8_t i;

for(i=0; i<length; i++)

{

A[i] = value;

}

}

/*=================================================================

=================================================================*/

uint8_t CompareArray(uint8_t* A,uint8_t* B,uint8_t length)

{

uint8_t i;

for(i=0; i<length; i++)

{

if(A[i] != B[i])

return 0;

}

return 1;

}

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_UART4_Init();

MX_SPI2_Init();

uint8_t rfID[16] = {0x00,0x00,0x00,0x00};//

uint8_t label[17] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//

uint8_t labelW[17] = "0123456789ABCDEF";//

uint8_t myl_key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

PCD_Init();

SetArray(label,0x00,16);

while (1)

{

HAL_Delay(500);

if((FindCard(0) != -1) && (GetCardUid(rfID) != -1))

{

if((SelectCard(rfID) == 0) && (AuthentBlock(0,20,rfID,myl_key) == 0))

//写标签

if(WriteSection(4,labelW) == 0)

{

printf("WriteSectionSuccess");

}

}

}

}

//以下是测试读标签

while (1)

{

HAL_Delay(500);

if((FindCard(0) != -1) && (GetCardUid(rfID) != -1))

{

if((SelectCard(rfID) == 0) && (AuthentBlock(0,20,rfID,myl_key) == 0))

//读标签

if((ReadSection(20,label) == 0) && CompareArray(label,labelW,16)) {

printf("\n ReadSectionSuccess LabelR %s\n",label);

}

}

}

}

各位朋友你会了吗?不会可以下载工程源代码(提示:解压密码要收5元)

 链接: https://pan.baidu.com/s/1DlVZoxglz9-P5c-vNpJNaw?pwd=vgqu

提取码: vgqu 

标签:return,cv627,0x00,uint8,非接,txbuff,M1,WriteByte,Reg
From: https://www.cnblogs.com/simaSoft/p/16755543.html

相关文章