#include <SPI.h>
#include <Servo.h>
#define RST_PIN 9
#define SS_PIN 10
#define SERVO_PIN 2
Servo gate;
#define REG_COMMAND 0x01
#define REG_FIFODATA 0x09
#define REG_FIFOLEN 0x0A
#define REG_BITFRAMING 0x0D
#define REG_MODE 0x11
#define REG_TXCONTROL 0x14
#define CMD_TRANSCEIVE 0x0C
#define CMD_SOFTRESET 0x0F
#define CMD_REQALL 0x52
#define CMD_ANTICOLL 0x93
byte authorizedUID[4] = {0x01, 0x02, 0x03, 0x04};
bool isGateOpen = false;
unsigned long gateOpenTime = 0;
void mfrc522_writeReg(byte reg, byte value) {
digitalWrite(SS_PIN, LOW);
SPI.transfer((reg << 1) & 0x7E);
SPI.transfer(value);
digitalWrite(SS_PIN, HIGH);
}
byte mfrc522_readReg(byte reg) {
digitalWrite(SS_PIN, LOW);
SPI.transfer(((reg << 1) & 0x7E) | 0x80);
byte res = SPI.transfer(0x00);
digitalWrite(SS_PIN, HIGH);
return res;
}
void mfrc522_clearFIFO(){
mfrc522_writeReg(REG_FIFOLEN,0x80);
}
bool mfrc522_init() {
pinMode(SS_PIN, OUTPUT);pinMode(RST_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);digitalWrite(RST_PIN, HIGH);delay(50);
mfrc522_writeReg(REG_COMMAND, CMD_SOFTRESET);delay(80);
mfrc522_writeReg(REG_MODE, 0x3D);
mfrc522_writeReg(REG_TXCONTROL, 0x40);
mfrc522_clearFIFO();
byte ver = mfrc522_readReg(0x37);
return !(ver==0x00||ver==0xFF);
}
bool mfrc522_request(byte cmd){
mfrc522_clearFIFO();
mfrc522_writeReg(REG_BITFRAMING,0x07);
mfrc522_writeReg(REG_FIFODATA,cmd);
mfrc522_writeReg(REG_COMMAND,CMD_TRANSCEIVE);
delay(60);
byte len = mfrc522_readReg(REG_FIFOLEN);
return len==2;
}
bool mfrc522_anticoll(byte* uid){
mfrc522_clearFIFO();
mfrc522_writeReg(REG_BITFRAMING,0x00);
mfrc522_writeReg(REG_FIFODATA,CMD_ANTICOLL);
mfrc522_writeReg(REG_FIFODATA,0x20);
mfrc522_writeReg(REG_COMMAND,CMD_TRANSCEIVE);
delay(60);
byte len=mfrc522_readReg(REG_FIFOLEN);
if(len!=5)return false;
for(byte i=0;i<4;i++)uid[i]=mfrc522_readReg(REG_FIFODATA);
return true;
}
bool compareUID(byte*u1,byte*u2){
for(byte i=0;i<4;i++)if(u1[i]!=u2[i])return false;
return true;
}
void openGate(){
if(isGateOpen)return;
Serial.println(">>>开闸放行<<<");
gate.write(0);
isGateOpen=true;gateOpenTime=millis();
Serial.println("闸门抬起✅");
}
void closeGate(){
if(!isGateOpen)return;
Serial.println(">>>关闸<<<");
gate.write(90);
isGateOpen=false;
Serial.println("闸门落下❌");
}
void readCard(){
if(!mfrc522_request(CMD_REQALL))return;
byte uid[4];
if(!mfrc522_anticoll(uid))return;
Serial.print("检测卡片UID:");
for(byte i=0;i<4;i++){
if(uid[i]<0x10)Serial.print("0");
Serial.print(uid[i],HEX);Serial.print(" ");
}
Serial.println();
if(compareUID(uid,authorizedUID)){
Serial.println("✅授权通过,抬杆");
openGate();
}else{
Serial.println("❌未授权,禁止通行");
}
}
void setup() {
Serial.begin(115200);
SPI.begin();
gate.attach(SERVO_PIN);gate.write(90);
if(!mfrc522_init()){
Serial.println("MFRC522初始化失败");while(1);
}
Serial.println("====ETC车道就绪====");
Serial.print("授权卡UID:01 02 03 04\n");
}
void loop() {
readCard();
if(isGateOpen && millis()-gateOpenTime>5000)closeGate();
delay(200);
}