一、前几天在某宝上刚买了个RFID-RC522  ,目标是复制我的门禁卡(看样子没多大希望了)。
二、各种百度各种谷歌都没找到与Arduino的连接方式。

so,分享下我的连接方式,与大家共同进步。。。。

材料:
1、Arduino Uno R3
2、RFID-RC522
3、连接线7根

最下面一根红色为3.3v的电源。
最上面的为SDA,其它照图连接就可以了。

下面是测试代码:

 #include <SPI.h>

 #define uchar unsigned char
#define uint unsigned int //数据数组的最大长度
#define MAX_LEN 16 /////////////////////////////////////////////////////////////////////
//set the pin设置引脚
/////////////////////////////////////////////////////////////////////
const int chipSelectPin = ; //SDA引脚片选引脚
const int NRSTPD = ; //RST引脚 //MF522 命令位
#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 //CRC校验和的计算 //Mifare_One卡的命令位
#define PICC_REQIDL 0x26 //在天线区域搜索不进入睡眠模式的卡
#define PICC_REQALL 0x52 //搜索天线区域中的所有卡
#define PICC_ANTICOLL 0x93 //防止冲突
#define PICC_SElECTTAG 0x93 //选择卡
#define PICC_AUTHENT1A 0x60 //验证A密码密钥
#define PICC_AUTHENT1B 0x61 //验证B密码密钥
#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 //睡眠模式 //通信时MF522的返回值
#define MI_OK 0
#define MI_NOTAGERR 1
#define MI_ERR 2 //------------------MFRC522 注册 ---------------
//Page 0:命令和状态
#define Reserved00 0x00 //保留将来之用
#define CommandReg 0x01 //启动和停止命令的执行
#define CommIEnReg 0x02 //中断请求传递的使能和禁能控制位。
#define DivlEnReg 0x03 //中断请求传递的使能和禁能控制位。
#define CommIrqReg 0x04 //包含中断请求标志
#define DivIrqReg 0x05 //包含中断请求标志
#define ErrorReg 0x06 //错误标志,指示执行行的上个命令的错误状态
#define Status1Reg 0x07 //包含通信的状态标志
#define Status2Reg 0x08 //包含接收器和发射器的状态标志
#define FIFODataReg 0x09 //64字节FIFO缓冲器的输入输出
#define FIFOLevelReg 0x0A //指示FIFO中存储的字节数
#define WaterLevelReg 0x0B //定义FIFO下溢和上溢报警的FIFO深度。
#define ControlReg 0x0C //不同的控制寄存器
#define BitFramingReg 0x0D //面向位的帧调节
#define CollReg 0x0E //RF接口上检测到的第一个位冲突的位的位置
#define Reserved01 0x0F //保留将来之用
//Page 1:控制
#define Reserved10 0x10 //保留将来之用
#define ModeReg 0x11 //定义发射和接收的常用模式
#define TxModeReg 0x12 //定义发射过程的数据传输速率
#define RxModeReg 0x13 //定义接收过程中的数据传输速率
#define TxControlReg 0x14 //控制天线驱动管脚TX1和TX2的逻辑特征
#define TxAutoReg 0x15 //控制天线驱动的设置
#define TxSelReg 0x16 //选择天线驱动器的内部源
#define RxSelReg 0x17 //选着内部的接收器设置
#define RxThresholdReg 0x18 //选择位译码器的阀值
#define DemodReg 0x19 //定义解调器的设置
#define Reserved11 0x1A //保留将来之用
#define Reserved12 0x1B //保留将来之用
#define MifareReg 0x1C //控制ISO 14443/MIFARE 模式106kbit/s的通信
#define Reserved13 0x1D //保留将来之用
#define Reserved14 0x1E //保留将来之用
#define SerialSpeedReg 0x1F //选择串行UART接口的速率
//Page 2:发生器
#define Reserved20 0x20 //保留将来之用
#define CRCResultRegM 0x21 //显示CRC计算的实际MSB和LSB值(MSB)
#define CRCResultRegL 0x22 //显示CRC计算的实际MSB和LSB值(LSB)
#define Reserved21 0x23 //保留将来之用
#define ModWidthReg 0x24 //控制ModWidth的设置
#define Reserved22 0x25 //保留将来之用
#define RFCfgReg 0x26 //配置接受器增益
#define GsNReg 0x27 //选择天线驱动器管脚TX1和TX2的调制电导
#define CWGsPReg 0x28 //选择天线驱动器管脚TX1和TX2的调制电导
#define ModGsPReg 0x29 //选择天线驱动器管脚TX1和TX2的调制电导
#define TModeReg 0x2A //定义内部定时器的设置A
#define TPrescalerReg 0x2B //定义内部定时器的设置B
#define TReloadRegH 0x2C //描述16位长的定时器重装值(C)
#define TReloadRegL 0x2D //描述16位长的定时器重装值(D)
#define TCounterValueRegH 0x2E //显示16位长的实际定时器值(E)
#define TCounterValueRegL 0x2F //显示16位长的实际定时器值(F)
//Page 3:记录
#define Reserved30 0x30 //保留将来之用
#define TestSel1Reg 0x31 //常用测试信号的配置
#define TestSel2Reg 0x32 //常用测试信号的配置和PRBS控制
#define TestPinEnReg 0x33 //D1—D7输出驱动器的使能管脚(注:仅用于串行接口)
#define TestPinValueReg 0x34 //定义D1-D7用做I/O总线的值
#define TestBusReg 0x35 //显示内部测试总线的状态
#define AutoTestReg 0x36 //控制数字自测试
#define VersionReg 0x37 //显示版本
#define AnalogTestReg 0x38 //控制管脚AUX1和AUX2
#define TestDAC1Reg 0x39 //定义 TestDAC1的测试值
#define TestDAC2Reg 0x3A //定义 TestDAC2的测试值
#define TestADCReg 0x3B //显示 ADC I和 Q通道的实际值
#define Reserved31 0x3C //保留用于产品测试
#define Reserved32 0x3D //保留用于产品测试
#define Reserved33 0x3E //保留用于产品测试
#define Reserved34 0x3F //保留用于产品测试
//----------------------------------------------- //4字节序列号卡,5字节字节是核准
uchar serNum[]; void setup()
{
Serial.begin(); SPI.begin(); pinMode(chipSelectPin,OUTPUT); //设置数字引脚10作为输出连接到RFID/使能引脚
digitalWrite(chipSelectPin, LOW); //激活RFID阅读器(片选)
pinMode(NRSTPD,OUTPUT); //设置数字引脚5,不复位和断电(复位引脚) MFRC522_Init();
} void loop()
{ uchar status;
uchar str[MAX_LEN]; //搜索卡,返回卡类型
status = MFRC522_Request(PICC_REQIDL, str);
if (status != MI_OK)
{
return;
}
//查看卡的类型
ShowCardType(str); //防止冲突返回网卡的4字节序列号
status = MFRC522_Anticoll(str); // str[0..3]: 卡片序列号
// str[4]: XOR checksum of the SN.(SN的异或校验。)
if (status == MI_OK)
{
Serial.print("The card's number is: ");
memcpy(serNum, str, );
ShowCardID(serNum); //ID卡的相关身份验证
uchar* id = serNum;
if( id[]==0x4B && id[]==0xE6 && id[]==0xD1 && id[]==0x3B ) {
Serial.println("Hello Mary!");
} else if(id[]==0x3B && id[]==0xE6 && id[]==0xD1 && id[]==0x3B) {
Serial.println("Hello Greg!");
}else{
Serial.println("Hello unkown guy!");
}
} MFRC522_Halt(); //命令卡进入休眠模式
delay();
} /*
* Function:ShowCardID
* Description:显示卡的ID
* Input parameter:ID string
* Return:Null
*/
void ShowCardID(uchar *id)
{
int IDlen=;
for(int i=; i<IDlen; i++){
Serial.print(0x0F & (id[i]>>), HEX);
Serial.print(0x0F & id[i],HEX);
}
Serial.println("");
} /*
* Function:ShowCardType
* Description:显示卡类型
* Input parameter:Type string
* Return:Null
*/
void ShowCardType(uchar* type)
{
Serial.print("Card type: ");
if(type[]==0x04&&type[]==0x00)
Serial.println("MFOne-S50");
else if(type[]==0x02&&type[]==0x00)
Serial.println("MFOne-S70");
else if(type[]==0x44&&type[]==0x00)
Serial.println("MF-UltraLight");
else if(type[]==0x08&&type[]==0x00)
Serial.println("MF-Pro");
else if(type[]==0x44&&type[]==0x03)
Serial.println("MF Desire");
else
Serial.println("Unknown");
} /*
* Function:Write_MFRC5200
* Description:写一个字节的数据到一个登记的MR RC522
* Input parameter:addr--register address;val--the value that need to write in
* Return:Null
*/
void Write_MFRC522(uchar addr, uchar val)
{
digitalWrite(chipSelectPin, LOW); //address format:0XXXXXX0
SPI.transfer((addr<<)&0x7E);
SPI.transfer(val); digitalWrite(chipSelectPin, HIGH);
} /*
* Function:Read_MFRC522
* Description:读一个字节的数据到一个登记的MR RC522
* Input parameter:addr--register address
* Return:return the read value
*/
uchar Read_MFRC522(uchar addr)
{
uchar val; digitalWrite(chipSelectPin, LOW); //地址形式:1XXXXXX0
SPI.transfer(((addr<<)&0x7E) | 0x80);
val =SPI.transfer(0x00); digitalWrite(chipSelectPin, HIGH); return val;
} /*
* Function:SetBitMask
* Description:设置RC522寄存器位
* Input parameter:reg--register address;mask--value
* Return:null
*/
void SetBitMask(uchar reg, uchar mask)
{
uchar tmp;
tmp = Read_MFRC522(reg);
Write_MFRC522(reg, tmp | mask); //设置掩码位
} /*
* Function:ClearBitMask
* Description:清除RC522寄存器位
* Input parameter:reg--register address;mask--value
* Return:null
*/
void ClearBitMask(uchar reg, uchar mask)
{
uchar tmp;
tmp = Read_MFRC522(reg);
Write_MFRC522(reg, tmp & (~mask)); //清除掩码
} /*
* Function:AntennaOn
* Description:打开天线,每一次打开的天线所需要至少1ms
* Input parameter:null
* Return:null
*/
void AntennaOn(void)
{
uchar temp; temp = Read_MFRC522(TxControlReg);
if (!(temp & 0x03))
{
SetBitMask(TxControlReg, 0x03);
}
} /*
* Function:AntennaOff
* Description:关闭天线,每次关闭天线至少需要1ms
* Input parameter:null
* Return:null
*/
void AntennaOff(void)
{
ClearBitMask(TxControlReg, 0x03);
} /*
* Function:ResetMFRC522
* Description:重置RC522
* Input parameter:null
* Return:null
*/
void MFRC522_Reset(void)
{
Write_MFRC522(CommandReg, PCD_RESETPHASE); //重置RC522
} /*
* Function:InitMFRC522
* Description:初始化RC522
* Input parameter:null
* Return:null
*/
void MFRC522_Init(void)
{
digitalWrite(NRSTPD,HIGH); //复位引脚 MFRC522_Reset(); //重置RC522 //定时器: TPrescaler*TreloadVal/6.78MHz = 24ms
Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg
Write_MFRC522(TReloadRegL, );
Write_MFRC522(TReloadRegH, ); Write_MFRC522(TxAutoReg, 0x40); //100%ASK
Write_MFRC522(ModeReg, 0x3D); //CRC效验值0x6363 ??? //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0
//Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0]
//Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB AntennaOn(); //打开天线
} /*
* Function:MFRC522_Request
* Description:搜寻卡,读取卡的类型
* Input parameter:reqMode--搜寻方法,
* TagType--返回卡的类型
* 0x4400 = Mifare_UltraLight
* 0x0400 = Mifare_One(S50)
* 0x0200 = Mifare_One(S70)
* 0x0800 = Mifare_Pro(X)
* 0x4403 = Mifare_DESFire
* return:return MI_OK if successed
*/
uchar MFRC522_Request(uchar reqMode, uchar *TagType)
{
uchar status;
uint backBits; //接收到的数据比特 Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? TagType[] = reqMode;
status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, , TagType, &backBits); if ((status != MI_OK) || (backBits != 0x10))
{
status = MI_ERR;
} return status;
} /*
* Function:MFRC522_ToCard
* Description:RC522和ISO14443之间通信
* Input parameter:command--MF522 command bits
* sendData--send data to card via rc522
* sendLen--send data length
* backData--the return data from card
* backLen--the length of return data
* return:return MI_OK if successed
*/
uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
{
uchar status = MI_ERR;
uchar irqEn = 0x00;
uchar waitIRq = 0x00;
uchar lastBits;
uchar n;
uint i; switch (command)
{
case PCD_AUTHENT: //密码验证
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case PCD_TRANSCEIVE: //在FIFO发送数据
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
} Write_MFRC522(CommIEnReg, irqEn|0x80); //允许中断
ClearBitMask(CommIrqReg, 0x80); //清除所有的中断标志位
SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO 初始化大部分 Write_MFRC522(CommandReg, PCD_IDLE); //没有行动;取消现在的命令 //把数据持续写入FIFO
for (i=; i<sendLen; i++)
{
Write_MFRC522(FIFODataReg, sendData[i]);
} //进行下面
Write_MFRC522(CommandReg, command);
if (command == PCD_TRANSCEIVE)
{
SetBitMask(BitFramingReg, 0x80); //StartSend=1,开始传送数据
} //等待接收数据完成
i = ; //i 应根据时钟调整,等待的时间最大应该是25毫秒
do
{
//CommIrqReg[7..0]
//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
n = Read_MFRC522(CommIrqReg);
i--;
}
while ((i!=) && !(n&0x01) && !(n&waitIRq)); ClearBitMask(BitFramingReg, 0x80); //StartSend=0 if (i != )
{
if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = MI_OK;
if (n & irqEn & 0x01)
{
status = MI_NOTAGERR; //??
} if (command == PCD_TRANSCEIVE)
{
n = Read_MFRC522(FIFOLevelReg);
lastBits = Read_MFRC522(ControlReg) & 0x07;
if (lastBits)
{
*backLen = (n-)* + lastBits;
}
else
{
*backLen = n*;
} if (n == )
{
n = ;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
} //读取FIFO数据
for (i=; i<n; i++)
{
backData[i] = Read_MFRC522(FIFODataReg);
}
}
}
else
{
status = MI_ERR;
} } //SetBitMask(ControlReg,0x80); //关闭定时器
//Write_MFRC522(CommandReg, PCD_IDLE); return status;
} /*
* Function:MFRC522_Anticoll
* Description:防冲撞,读取卡的连续数据
* Input parameter:serNum--return the 4 bytes card serial number, the 5th byte is recheck byte
* return:return MI_OK if successed
*/
uchar MFRC522_Anticoll(uchar *serNum)
{
uchar status;
uchar i;
uchar serNumCheck=;
uint unLen; //ClearBitMask(Status2Reg, 0x08); //strSensclear
//ClearBitMask(CollReg,0x80); //ValuesAfterColl
Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0] serNum[] = PICC_ANTICOLL;
serNum[] = 0x20;
status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, , serNum, &unLen); if (status == MI_OK)
{
//验证卡的连续数据
for (i=; i<; i++)
{
serNumCheck ^= serNum[i];
}
if (serNumCheck != serNum[i])
{
status = MI_ERR;
}
} //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 return status;
} /*
* Function:CalulateCRC
* Description:使用mf522计算CRC
* Input parameter:pIndata--the CRC data need to be read,len--data length,pOutData-- the caculated result of CRC
* return:Null
*/
void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
{
uchar i, n; ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0
SetBitMask(FIFOLevelReg, 0x80); //清除FIFO指针
//Write_MFRC522(CommandReg, PCD_IDLE); //Write data into FIFO
for (i=; i<len; i++)
{
Write_MFRC522(FIFODataReg, *(pIndata+i));
}
Write_MFRC522(CommandReg, PCD_CALCCRC); //等待CRC计算完成
i = 0xFF;
do
{
n = Read_MFRC522(DivIrqReg);
i--;
}
while ((i!=) && !(n&0x04)); //CRCIrq = 1 //读出CRC校验结果
pOutData[] = Read_MFRC522(CRCResultRegL);
pOutData[] = Read_MFRC522(CRCResultRegM);
} /*
* Function:MFRC522_Write
* Description:写数据块
* Input parameters:blockAddr--block address;writeData--Write 16 bytes data into block
* return:return MI_OK if successed
*/
uchar MFRC522_Write(uchar blockAddr, uchar *writeData)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[]; buff[] = PICC_WRITE;
buff[] = blockAddr;
CalulateCRC(buff, , &buff[]);
status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, , buff, &recvBits); if ((status != MI_OK) || (recvBits != ) || ((buff[] & 0x0F) != 0x0A))
{
status = MI_ERR;
} if (status == MI_OK)
{
for (i=; i<; i++) //16字节的数据写入到FIFO
{
buff[i] = *(writeData+i);
}
CalulateCRC(buff, , &buff[]);
status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, , buff, &recvBits); if ((status != MI_OK) || (recvBits != ) || ((buff[] & 0x0F) != 0x0A))
{
status = MI_ERR;
}
} return status;
} /*
* Function:MFRC522_Halt
* Description:命令卡进入睡眠模式
* Input parameters:null
* return:null
*/
void MFRC522_Halt(void)
{
uchar status;
uint unLen;
uchar buff[]; buff[] = PICC_HALT;
buff[] = ;
CalulateCRC(buff, , &buff[]); status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, , buff,&unLen);
}

RFID-RC522 与Arduino的连接的更多相关文章

  1. Arduino+RFID RC522 +继电器

    博客园的第一篇博文就献给Arduino了.不知道能不能坚持自己喜欢的并且记录下来. 起码是个好的开始. 想实现一卡通代替钥匙开启电动车. 简单的原理,通过RC522模块读取一卡通的序列号,在程序中进行 ...

  2. LabVIEW与Arduino的连接

    labVIEW和Arduino的连接有两种方法: 第一种方法是用Arduino的IDE去打开位于labVIEW文件目录下面的(C:\Program Files (x86)\National Instr ...

  3. Annikken Andee–Arduino与Android间的简易连接

    一个Arduino的兼容板,允许你显示并控制来自Android设备的Arduino应用.无需Anroid APP开发. 点击:观看视频 什么是Annikken Andee? Annikken Ande ...

  4. ROS Learning-016 Arduino-For-ROS-001 搭建 Arduino 和 ROS 之间相连接的开发环境

    Arduino For ROS-001 - 搭建 ROS 和 Arduino 相连接的开发环境 我的Ubuntu系统:Ubuntu 14.04.10 TLS 32位 Arduino的版本:Arduin ...

  5. Arduino连接SHT10温湿度传感器--返回值不正常解决办法

    如题目,arduino中连接温湿度传感器,用的是一个github开源项目,地址:点击打开,其实这个就是一个封装好的库,下载后把解压的文件夹复制到Arduino目录下的librarys文件夹内,重启Ar ...

  6. 使用Arduino开发板连接干簧管(Reed Switch)的方法

    在现实生活中,干簧管(Reed Switch)有许多重要的应用,如磁性门开关.笔记本电脑.智能手机等.在本篇文章中,我们将了解一些干簧管的知识,并介绍如何使用Arduino开发板连接干簧管. 干簧管( ...

  7. nodejs操作arduino入门(javascript操作底层硬件)

    用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...

  8. Arduino I2C + 三轴加速度计LIS3DH

    LIS3DH是ST公司生产的MEMS三轴加速度计芯片,实现运动传感的功能.主要特性有: 宽工作电压范围:1.71 ~ 3.6V 功耗:低功耗模式2μA:正常工作模式.ODR = 50Hz时功耗11μA ...

  9. Arduino周边模块:执行部件(舵机、直流电机、步进电机)

    Arduino周边模块:执行部件 Arduino周边模块:执行部件 嵌入式系统的构成 如今已经有各种各样的基于Arduino的嵌入式系统, 比如:智能小车.3D打印机.机器人,甚至还有基于Arduin ...

随机推荐

  1. Deep Learning 教程(斯坦福深度学习研究团队)

    http://www.zhizihua.com/blog/post/602.html 说明:本教程将阐述无监督特征学习和深度学习的主要观点.通过学习,你也将实现多个功能学习/深度学习算法,能看到它们为 ...

  2. Java-JUC(五):闭锁(CountDownLatch)

    闭锁(CountDownLatch) jdk5.0在java.util.concurrent包中提供了CountDownLatch,它是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一 ...

  3. 安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台

    安装logstash+kibana+elasticsearch+redis搭建集中式日志分析平台 2014-01-16 19:40:57|  分类: logstash |  标签:logstash   ...

  4. spring boot与spring mvc的区别是什么?

    Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面 ...

  5. archivedDataWithRootObject NSUserDefaults

    archivedDataWithRootObject 存储 BusinessCard *bc = [[BusinessCard alloc] init];   NSUserDefaults *ud = ...

  6. openfiler在esxi下的安装配置

    注意分区的时候如果硬盘太小自动分区会导致分配的卷大小不够用 后改为如下: 以root登录: 应该以openfiler登录,口令是password 也可以导入虚拟机安装 升级虚拟机硬件版本 终端登录用户 ...

  7. Linux内核配置.config文件

    在命令行中,进入顶层内核目录,并输入命令make menuconfig,就可以启动一个基于菜单的内核配置编辑器.从这里开始,你可以访问每个可用的配置参数,并生成一个定制的内核配置. 当你退出配置编辑器 ...

  8. JAVA设计模式——第 2 章 代理模式【Proxy Pattern】(转)

    什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被代理的人能干活呀. ...

  9. spring Ioc 实践

    了解过IoC的概念,没有真正实践,感觉还是会比较模糊.自己的实践虽然简单,但还是记录下呀~ 1. 通过注解的方式注入service 1.1 controller中创建对象 @Controller @R ...

  10. MongoDB副本集配置系列一:安装MongoDB

    1:下载MongoDB 2.6版本 https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-2.6.9.zip 2:解压 tar ...