日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F103+RTT从零开始(三)—— S50门禁卡复制

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F103+RTT从零开始(三)—— S50门禁卡复制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近期因為各種原因,重新租了個房子住,小區外面有門禁系統,樓下也有個門禁系統。房東只給了一套門禁卡,而我家人也需要門禁卡,所以我就去小區物業那里補卡,結果小區物業那里只能補小區的門禁卡,樓下的門禁卡需要在另外個地方補。物業工作人員給說了下地方,我找了下沒找到,又想起了我一年前買了個RFID模塊和十幾個空白門禁卡,還沒開封。又正好時值國慶,空閑時間比較多,不如自己來復制吧。

基礎知識

一兩個月前,我寫了兩篇STM32F103+RTT的入門博客。那兩篇是非常基礎的,到這里直接就是復制門禁卡,看起來好像不是循序漸進。不過也是沒法子,畢竟現在從事的工作和這些完全不沾邊,工作又忙,所以沒太多時間來一步一步學習并且寫博客,只能玩到哪是哪了。
先看了下門禁卡的分類和一些基礎資料,了解到我新租住的房子所在的小區用的門禁卡是S50類型的。它具有16個 扇區,每個扇區具有四個Block,分別為0、1、2、3,每個Block可以存儲16字節的數據。其中每個扇區的Block3存儲的為6字節A密碼+4字節控制位+6字節B密碼。另外第一扇區的Block0存儲的為卡號以及廠商的基本信息。卡就是下面的這個鬼樣子:

一般來說,第一扇區的Block0下內容是不能更改的,我原以為小區門禁卡是通過其他扇區的數據來做驗證的,后面寫好了讀數據的代碼,發現從門禁卡中從數據塊中讀取的數據都是0,只有密碼區、控制區及ID下第一扇區的Block0中有數據。所以我們的那個小區中的門禁卡應該是通過卡的第一扇區的Block0中的信息來驗證的。也就是說我們要做的是復制整個卡,包括第一扇區的Block0。
要復制第一扇區的Block0,普通的IC卡就不行了,我之前買的卡就是普通的IC卡,鼓搗了很久,一直以為是程序寫的有問題,后來才發現是卡不行。沒辦法,只能重新買卡了。
選卡也要選擇合適的卡,查了下資料,能夠修改第一扇區Block0的兼容S50類型的卡,有UID卡(可以使用后門指令無限制重復修改第一扇區Block0,會響應后門指令)、CUID卡(可以使用后門指令無限制重復修改第一扇區的Block0,不會響應后門指令)、FUID卡(使用普通指令,只能修改一次第一扇區的Block0)等。根據上面的說明,可以知道,UID卡可以無限制修改,但是由于會響應后門指令,所以如果門禁系統有檢測后門指令并且禁用,那就不能用了。CUID不響應后門指令,但是由于可以用后面指令修改,門禁系統如果先去修改一下,確認不能修改,再進行門禁驗證,那么CUID的卡就也不能用了。FUID顯然是最保險的,但是從價格來說,FUID(2.2元) > CUID(1.3元) > UID(0.78元)。
所以我先試了下房東給的門禁卡,發現它是可以被修改的,而且也會響應后門指令,那么考慮性價比,當然是買UID卡了。10塊錢13個還包郵,加上8塊錢不到的一個RFID-RC522,一共18塊錢(PS : 物業那里20塊錢一個門禁卡,真坑)。

門禁卡復制實現

上面提到修改門禁卡第一扇區Block0是需要使用后門指令的,直接按照普通的寫數據的方式進行修改,是無法修改的。既然主要目的是復制門禁卡,懶得重復去造輪子了。我之前買的RFID-RC522模塊,使用的是SPI的通信模式,淘寶上搜索,應該很多都是這樣的,如下圖所示:

對,買的就是這樣沒焊腳的,然后我又買了個電烙鐵套裝。。。

然后上位機還是使用之前的那個STM32F103C8T6。

RC522驅動程序

然后再網上找了下STM32F103下RC522的驅動程序,并增加利用后門指令寫第一扇區block0的代碼如下:
驅動頭文件rc522.h

#ifndef __RC522_H #define __RC522_H#define MF522_RST_PIN GPIO_Pin_0 #define MF522_RST_PORT GPIOB #define MF522_RST_CLK RCC_APB2Periph_GPIOB#define MF522_MISO_PIN GPIO_Pin_6 #define MF522_MISO_PORT GPIOA #define MF522_MISO_CLK RCC_APB2Periph_GPIOA#define MF522_MOSI_PIN GPIO_Pin_7 #define MF522_MOSI_PORT GPIOA #define MF522_MOSI_CLK RCC_APB2Periph_GPIOA#define MF522_SCK_PIN GPIO_Pin_5 #define MF522_SCK_PORT GPIOA #define MF522_SCK_CLK RCC_APB2Periph_GPIOA#define MF522_NSS_PIN GPIO_Pin_4 #define MF522_NSS_PORT GPIOA #define MF522_NSS_CLK RCC_APB2Periph_GPIOA#define RST_H GPIO_SetBits(MF522_RST_PORT, MF522_RST_PIN) #define RST_L GPIO_ResetBits(MF522_RST_PORT, MF522_RST_PIN) #define MOSI_H GPIO_SetBits(MF522_MOSI_PORT, MF522_MOSI_PIN) #define MOSI_L GPIO_ResetBits(MF522_MOSI_PORT, MF522_MOSI_PIN) #define SCK_H GPIO_SetBits(MF522_SCK_PORT, MF522_SCK_PIN) #define SCK_L GPIO_ResetBits(MF522_SCK_PORT, MF522_SCK_PIN) #define NSS_H GPIO_SetBits(MF522_NSS_PORT, MF522_NSS_PIN) #define NSS_L GPIO_ResetBits(MF522_NSS_PORT, MF522_NSS_PIN) #define READ_MISO GPIO_ReadInputDataBit(MF522_MISO_PORT, MF522_MISO_PIN)// ???? void PcdInit(void); char PcdReset(void); void PcdAntennaOn(void); void PcdAntennaOff(void); char PcdRequest(unsigned char req_code,unsigned char *pTagType); char PcdAnticoll(unsigned char *pSnr); char PcdSelect(unsigned char *pSnr); char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr); char PcdRead(unsigned char addr,unsigned char *pData); char PcdWrite(unsigned char addr,unsigned char *pData); char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue); char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr); char PcdHalt(void); char PcdComMF522(unsigned char Command,unsigned char *pInData, unsigned char InLenByte,unsigned char *pOutData, unsigned int *pOutLenBit); void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData); void WriteRawRC(unsigned char Address,unsigned char value); unsigned char ReadRawRC(unsigned char Address); void SetBitMask(unsigned char reg,unsigned char mask); void ClearBitMask(unsigned char reg,unsigned char mask); char M500PcdConfigISOType(unsigned char type); void delay_10ms(unsigned int _10ms); void WaitCardOff(void); char PcdSpicelWrite(unsigned char *pData);#define PCD_IDLE 0x00 #define PCD_AUTHENT 0x0E #define PCD_RECEIVE 0x08 #define PCD_TRANSMIT 0x04 #define PCD_TRANSCEIVE 0x0C #define PCD_RESETPHASE 0x0F #define PCD_CALCCRC 0x03 #define PICC_REQIDL 0x26 #define PICC_REQALL 0x52 #define PICC_ANTICOLL1 0x93 #define PICC_ANTICOLL2 0x95 #define PICC_AUTHENT1A 0x60 #define PICC_AUTHENT1B 0x61 #define PICC_READ 0x30 #define PICC_WRITE 0xA0 #define PICC_DECREMENT 0xC0 #define PICC_INCREMENT 0xC1 #define PICC_RESTORE 0xC2 #define PICC_TRANSFER 0xB0 #define PICC_HALT 0x50 #define PCD_SPECIAL_COPY 0x43#define DEF_FIFO_LENGTH 64 #define RFU00 0x00 #define CommandReg 0x01 #define ComIEnReg 0x02 #define DivlEnReg 0x03 #define ComIrqReg 0x04 #define DivIrqReg 0x05 #define ErrorReg 0x06 #define Status1Reg 0x07 #define Status2Reg 0x08 #define FIFODataReg 0x09 #define FIFOLevelReg 0x0A #define WaterLevelReg 0x0B #define ControlReg 0x0C #define BitFramingReg 0x0D #define CollReg 0x0E #define RFU0F 0x0F // PAGE 1 #define RFU10 0x10 #define ModeReg 0x11 #define TxModeReg 0x12 #define RxModeReg 0x13 #define TxControlReg 0x14 #define TxAutoReg 0x15 #define TxSelReg 0x16 #define RxSelReg 0x17 #define RxThresholdReg 0x18 #define DemodReg 0x19 #define RFU1A 0x1A #define RFU1B 0x1B #define MifareReg 0x1C #define RFU1D 0x1D #define RFU1E 0x1E #define SerialSpeedReg 0x1F // PAGE 2 #define RFU20 0x20 #define CRCResultRegM 0x21 #define CRCResultRegL 0x22 #define RFU23 0x23 #define ModWidthReg 0x24 #define RFU25 0x25 #define RFCfgReg 0x26 #define GsNReg 0x27 #define CWGsCfgReg 0x28 #define ModGsCfgReg 0x29 #define TModeReg 0x2A #define TPrescalerReg 0x2B #define TReloadRegH 0x2C #define TReloadRegL 0x2D #define TCounterValueRegH 0x2E #define TCounterValueRegL 0x2F // PAGE 3 #define RFU30 0x30 #define TestSel1Reg 0x31 #define TestSel2Reg 0x32 #define TestPinEnReg 0x33 #define TestPinValueReg 0x34 #define TestBusReg 0x35 #define AutoTestReg 0x36 #define VersionReg 0x37 #define AnalogTestReg 0x38 #define TestDAC1Reg 0x39 #define TestDAC2Reg 0x3A #define TestADCReg 0x3B #define RFU3C 0x3C #define RFU3D 0x3D #define RFU3E 0x3E #define RFU3F 0x3F#define REQ_ALL 0x52 #define KEYA 0x60 #define KEYB 0x61#define MI_OK (char)0 #define MI_NOTAGERR (char)(-1) #define MI_ERR (char)(-2)#endif

驅動實現rc522.c

#include "rc522.h" #include "stm32f10x_gpio.h"#define MAXRLEN 18 void PcdInit() {GPIO_InitTypeDef GPIO_InitStructure;/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_RST_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin = MF522_RST_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(MF522_RST_PORT, &GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_MISO_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin = MF522_MISO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(MF522_MISO_PORT, &GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_MOSI_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin = MF522_MOSI_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(MF522_MOSI_PORT, &GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_SCK_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin = MF522_SCK_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(MF522_SCK_PORT, &GPIO_InitStructure);/* Enable the GPIO Clock */RCC_APB2PeriphClockCmd(MF522_NSS_CLK, ENABLE);/* Configure the GPIO pin */GPIO_InitStructure.GPIO_Pin = MF522_NSS_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(MF522_NSS_PORT, &GPIO_InitStructure); }char PcdRequest(unsigned char req_code,unsigned char *pTagType) {char status; unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x07);SetBitMask(TxControlReg,0x03);ucComMF522Buf[0] = req_code;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen); // if(status == MI_OK ) // { LED_GREEN =0 ;} // else {LED_GREEN =1 ;}if ((status == MI_OK) && (unLen == 0x10)){ *pTagType = ucComMF522Buf[0];*(pTagType+1) = ucComMF522Buf[1];}else{ status = MI_ERR; }return status; }char PcdAnticoll(unsigned char *pSnr) {char status;unsigned char i,snr_check=0;unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08);WriteRawRC(BitFramingReg,0x00);ClearBitMask(CollReg,0x80);ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x20;status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);if (status == MI_OK){for (i=0; i<4; i++){ *(pSnr+i) = ucComMF522Buf[i];snr_check ^= ucComMF522Buf[i];}if (snr_check != ucComMF522Buf[i]){ status = MI_ERR; }}SetBitMask(CollReg,0x80);return status; }char PcdSelect(unsigned char *pSnr) {char status;unsigned char i;unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_ANTICOLL1;ucComMF522Buf[1] = 0x70;ucComMF522Buf[6] = 0;for (i=0; i<4; i++){ucComMF522Buf[i+2] = *(pSnr+i);ucComMF522Buf[6] ^= *(pSnr+i);}CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);ClearBitMask(Status2Reg,0x08);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x18)){ status = MI_OK; }else{ status = MI_ERR; }return status; }char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) {char status;unsigned int unLen;unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode;ucComMF522Buf[1] = addr;for (i=0; i<6; i++){ ucComMF522Buf[i+2] = *(pKey+i); }for (i=0; i<6; i++){ ucComMF522Buf[i+8] = *(pSnr+i); }// memcpy(&ucComMF522Buf[2], pKey, 6); // memcpy(&ucComMF522Buf[8], pSnr, 4); status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))){ status = MI_ERR; }return status; }char PcdRead(unsigned char addr,unsigned char *pData) {char status;unsigned int unLen;unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_READ;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status == MI_OK) && (unLen == 0x90))// { memcpy(pData, ucComMF522Buf, 16); }{for (i=0; i<16; i++){ *(pData+i) = ucComMF522Buf[i]; }}else{ status = MI_ERR; }return status; }char PcdWrite(unsigned char addr,unsigned char *pData) {char status;unsigned int unLen;unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_WRITE;ucComMF522Buf[1] = addr;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }if (status == MI_OK){//memcpy(ucComMF522Buf, pData, 16);for (i=0; i<16; i++){ ucComMF522Buf[i] = *(pData+i); }CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)){ status = MI_ERR; }}return status; }//這個是寫第一扇區Block0的代碼 char PcdSpicelWrite(unsigned char *pData) {char status;unsigned int unLen;unsigned char i,ucComMF522Buf[MAXRLEN]; //需要使用以下步驟開啟后門PcdHalt();WriteRawRC(BitFramingReg, 0x07);//WriteRawRC(CommandReg, 0x40);ucComMF522Buf[0] = 0x40;PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);WriteRawRC(BitFramingReg, 0x00);ucComMF522Buf[0] = 0x43;PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);return PcdWrite(0, pData); }char PcdHalt(void) {unsigned int unLen;unsigned char ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_HALT;ucComMF522Buf[1] = 0;CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);return MI_OK; }//?MF522??CRC16?? void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData) {unsigned char i,n;ClearBitMask(DivIrqReg,0x04);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<len; i++){ WriteRawRC(FIFODataReg, *(pIndata+i)); }WriteRawRC(CommandReg, PCD_CALCCRC);i = 0xFF;do {n = ReadRawRC(DivIrqReg);i--;}while ((i!=0) && !(n&0x04));pOutData[0] = ReadRawRC(CRCResultRegL);pOutData[1] = ReadRawRC(CRCResultRegM); }char PcdReset(void) {RST_H;delay_10ms(1);RST_L;delay_10ms(1);RST_H;delay_10ms(10);if(ReadRawRC(0x02) == 0x80){}WriteRawRC(CommandReg,PCD_RESETPHASE);WriteRawRC(ModeReg,0x3D); WriteRawRC(TReloadRegL,30); WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);WriteRawRC(TxAutoReg,0x40); return MI_OK; }char M500PcdConfigISOType(unsigned char type) {if (type == 'A'){ ClearBitMask(Status2Reg,0x08);WriteRawRC(ModeReg,0x3D);//3FWriteRawRC(RxSelReg,0x86);//84WriteRawRC(RFCfgReg,0x7F); //4FWriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0);WriteRawRC(TModeReg,0x8D);WriteRawRC(TPrescalerReg,0x3E);delay_10ms(1);PcdAntennaOn();}else{ return (char)-1; }return MI_OK; }unsigned char ReadRawRC(unsigned char Address) {unsigned char i, ucAddr;unsigned char ucResult=0;NSS_L;ucAddr = ((Address<<1)&0x7E)|0x80;for(i=8;i>0;i--){SCK_L;if(ucAddr&0x80)MOSI_H;elseMOSI_L;SCK_H;ucAddr <<= 1;}for(i=8;i>0;i--){SCK_L;ucResult <<= 1;SCK_H;if(READ_MISO == 1)ucResult |= 1;}NSS_H;SCK_H;return ucResult; }void WriteRawRC(unsigned char Address, unsigned char value) { unsigned char i, ucAddr;SCK_L;NSS_L;ucAddr = ((Address<<1)&0x7E);for(i=8;i>0;i--){if(ucAddr&0x80)MOSI_H;elseMOSI_L;SCK_H;ucAddr <<= 1;SCK_L;}for(i=8;i>0;i--){if(value&0x80)MOSI_H;elseMOSI_L;SCK_H;value <<= 1;SCK_L;}NSS_H;SCK_H; }void SetBitMask(unsigned char reg,unsigned char mask) {char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg,tmp | mask); // set bit mask }void ClearBitMask(unsigned char reg,unsigned char mask) {char tmp = 0x0;tmp = ReadRawRC(reg);WriteRawRC(reg, tmp & ~mask); // clear bit mask } char PcdComMF522(unsigned char Command, unsigned char *pInData, unsigned char InLenByte,unsigned char *pOutData, unsigned int *pOutLenBit) {char status = MI_ERR;unsigned char irqEn = 0x00;unsigned char waitFor = 0x00;unsigned char lastBits;unsigned char n;unsigned int i;switch (Command){case PCD_AUTHENT:irqEn = 0x12;waitFor = 0x10;break;case PCD_TRANSCEIVE:case PCD_SPECIAL_COPY:irqEn = 0x77;waitFor = 0x30;break;default:break;}WriteRawRC(ComIEnReg,irqEn|0x80);ClearBitMask(ComIrqReg,0x80);WriteRawRC(CommandReg,PCD_IDLE);SetBitMask(FIFOLevelReg,0x80);for (i=0; i<InLenByte; i++){ WriteRawRC(FIFODataReg, pInData[i]); }WriteRawRC(CommandReg, Command);if (Command == PCD_TRANSCEIVE){ SetBitMask(BitFramingReg,0x80); }i = 2000;do {n = ReadRawRC(ComIrqReg);i--;}while ((i!=0) && !(n&0x01) && !(n&waitFor));ClearBitMask(BitFramingReg,0x80);if (i!=0){ if(!(ReadRawRC(ErrorReg)&0x1B)){status = MI_OK;if (n & irqEn & 0x01){ status = MI_NOTAGERR; }if (Command == PCD_TRANSCEIVE){n = ReadRawRC(FIFOLevelReg);lastBits = ReadRawRC(ControlReg) & 0x07;if (lastBits){ *pOutLenBit = (n-1)*8 + lastBits; }else{ *pOutLenBit = n*8; }if (n == 0){ n = 1; }if (n > MAXRLEN){ n = MAXRLEN; }for (i=0; i<n; i++){ pOutData[i] = ReadRawRC(FIFODataReg); }}}else{ status = MI_ERR; }}SetBitMask(ControlReg,0x80); // stop timer nowWriteRawRC(CommandReg,PCD_IDLE); return status; }void PcdAntennaOn() {unsigned char i;i = ReadRawRC(TxControlReg);if (!(i & 0x03)){SetBitMask(TxControlReg, 0x03);} }void PcdAntennaOff() {ClearBitMask(TxControlReg, 0x03); }void WaitCardOff(void) {char status;unsigned char TagType[2];while(1){status = PcdRequest(REQ_ALL, TagType);if(status){status = PcdRequest(REQ_ALL, TagType);if(status){status = PcdRequest(REQ_ALL, TagType);if(status){return;}}}delay_10ms(10);} }void delay_10ms(unsigned int _10ms) {unsigned int i, j;for(i=0; i<_10ms; i++){for(j=0; j<60000; j++);} }

后門代碼實現依據來源于這篇博客,RC522驅動代碼來源于這篇博客,在此表示感謝。

主要控制邏輯

按照之前點亮LED的經驗,我們使用RTthread來進行進行門禁卡的檢測和復制。主要代碼如下:
復制代碼被注釋了,我們先使用檢測并讀取的代碼,讀取出原卡的內容,然后把讀取內容記錄下來,復制到新卡上去。正確的做法應該是使用完整邏輯來實現這個流程,這里為了方便,直接手動記錄,然后修改代碼重新編譯來進行卡的復制,有興趣有需要的朋友可在此基礎上自行補充完成。

#include <board.h> #include <rtthread.h> #include "led.h" #include "rc522.h"ALIGN(RT_ALIGN_SIZE) static rt_uint8_t led_stack[ 512 ]; static struct rt_thread led_thread; static void led_thread_entry(void* parameter) {unsigned int count=0;rt_hw_led_init();while (1){count++;rt_hw_led_on(0);rt_thread_delay( RT_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */rt_hw_led_off(0);rt_thread_delay( RT_TICK_PER_SECOND/2 );} }static void ShowID(u8 *p) {u8 num[9];u8 i;for(i=0; i<4; i++){num[i*2]=p[i]/16;num[i*2]>9?(num[i*2]+='7'):(num[i*2]+='0');num[i*2+1]=p[i]%16;num[i*2+1]>9?(num[i*2+1]+='7'):(num[i*2+1]+='0');}num[8]=0;rt_kprintf("ID>>>%s\r\n", num); }static rt_uint8_t rfid_stack[ 512 ]; static struct rt_thread rfid_thread; static void rfid_thread_entry(void* parameter) {unsigned int count=0;char status;unsigned char snr, buf[16], TagType[2], SelectedSnr[4], DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};PcdInit();PcdReset();PcdAntennaOff();PcdAntennaOn();M500PcdConfigISOType( 'A' );rt_kprintf( "rc522 init over!\n" );while(1){status= PcdRequest( REQ_ALL , TagType );if(!status) {status = PcdAnticoll(SelectedSnr);if(!status){status=PcdSelect(SelectedSnr);if(!status){ShowID(SelectedSnr);/*unsigned char inDoor[16] = {0x91, 0x94, 0x09, 0xa5, 0xa9, 0x88, 0x04, 0x00, 0x85, 0x00, 0xb4, 0x2e, 0xf0, 0xbb, 0x6a, 0xa8};unsigned char outDoor[16] = {0x1c, 0x6a, 0xa0, 0xa5, 0x73, 0x88, 0x04, 0x00,0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};status = PcdSpicelWrite(inDoor);*/if(!status){for(int i = 0;i < 16 ;i++){snr = i;status = PcdAuthState(KEYB, (snr*4+3), DefaultKey, SelectedSnr);for(int j = 0; j < 4; j++){status = PcdRead((snr*4+j), buf);//status = PcdWrite((snr*4+0), "way2"); if(!status){uint16_t * e = 0;e = (uint16_t *)TagType;//rt_kprintf("Snr Index : %d, type = %x \n", snr * 4 + j, *e);for(int n = 0; n < 16; n++){rt_kprintf("%x ", (uint16_t)buf[n]);} rt_kprintf("\n"); }}}}rt_kprintf("operate finished! %x \n", status);WaitCardOff();}}}} }void rt_init_thread_entry(void* parameter) { #ifdef RT_USING_COMPONENTS_INIT/* initialization RT-Thread Components */rt_components_init(); #endif }int rt_application_init(void) {rt_thread_t init_thread;rt_err_t result;/* init led thread */result = rt_thread_init(&led_thread,"led",led_thread_entry,RT_NULL,(rt_uint8_t*)&led_stack[0],sizeof(led_stack),20,5);if (result == RT_EOK){rt_thread_startup(&led_thread);}result = rt_thread_init(&rfid_thread,"rfid",rfid_thread_entry,RT_NULL,(rt_uint8_t*)&rfid_stack[0],sizeof(rfid_stack),22,5);if (result == RT_EOK){rt_thread_startup(&rfid_thread);}#if (RT_THREAD_PRIORITY_MAX == 32)init_thread = rt_thread_create("init",rt_init_thread_entry, RT_NULL,2048, 8, 20); #elseinit_thread = rt_thread_create("init",rt_init_thread_entry, RT_NULL,2048, 80, 20); #endifif (init_thread != RT_NULL)rt_thread_startup(init_thread);return 0; }/*@}*/

工程源碼

工程源碼掛載在CSDN下載頻道,攢點下載分備用。歡迎轉載,轉載博客請注明出處湖廣午王的博客。

總結

以上是生活随笔為你收集整理的STM32F103+RTT从零开始(三)—— S50门禁卡复制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。