请求解读Arduino读取RFID标签UID的代码并逐行注释,重点解析三元运算符
Breakdown of RFID UID Reading Code (Line-by-Line Explanation)
Hey there! Let’s walk through this Arduino RFID code step by step so you fully grasp every part—including that ternary operator you’re curious about. I’ll add detailed comments to the code and explain the entire workflow clearly.
Full Annotated Code
#include <SPI.h> // 引入SPI库:MFRC522模块通过SPI协议与Arduino通信 #include <MFRC522.h> // 引入MFRC522库:专门用于控制MFRC522 RFID读写模块 #define SS_PIN 10 // 定义MFRC522的片选(SS)引脚为Arduino引脚10 #define RST_PIN 9 // 定义MFRC522的复位(RST)引脚为Arduino引脚9 MFRC522 rfid(SS_PIN, RST_PIN); // 创建MFRC522类实例,命名为rfid,传入引脚参数 MFRC522::MIFARE_Key key; // 创建MIFARE密钥对象(用于加密操作,此处仅初始化) byte nuidPICC[4]; // 字节数组:存储读取到的RFID卡UID(通常为4字节) void setup() { Serial.begin(9600); // 初始化串口通信,波特率9600,用于在串口监视器输出信息 SPI.begin(); // 初始化SPI总线:MFRC522依赖SPI协议通信 rfid.PCD_Init(); // 初始化MFRC522模块(PCD指读写器设备本身) // 初始化MIFARE默认密钥(全部设为0xFF,这是MIFARE卡的通用默认密钥) for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } } void loop() { // 检查是否有新RFID卡靠近模块 // 如果没有新卡,直接返回,继续循环等待 if (!rfid.PICC_IsNewCardPresent()) return; // 尝试读取卡的UID(序列号) // 如果读取失败,直接返回,继续循环等待 if (!rfid.PICC_ReadCardSerial()) return; // 将读取到的UID复制到自定义数组nuidPICC(此处为备份,代码后续未直接使用) for (byte i = 0; i < 4; i++) { nuidPICC[i] = rfid.uid.uidByte[i]; } // 调用自定义函数,将UID以十六进制格式打印到串口 printHex(rfid.uid.uidByte, rfid.uid.size); Serial.println(); // 打印换行,让每次读取的UID单独成行 rfid.PICC_HaltA(); // 让RFID卡进入休眠状态,节省电量并结束当前通信 rfid.PCD_StopCrypto1();// 停止加密通信(清理操作,避免影响下一次读取) } // 自定义函数:将字节数组内容格式化为十六进制字符串并打印 void printHex(byte *buffer, byte bufferSize) { // 遍历数组的每个元素(bufferSize为数组长度,即UID的字节数) for (byte i = 0; i < bufferSize; i++) { // 重点:三元运算符解析 // 格式:条件 ? 真时执行内容 : 假时执行内容 // 条件:buffer[i] < 0x10(当前字节值小于16,即十六进制的一位数) // 为真:打印" 0",给一位数的十六进制补零,保证格式对齐(比如0x05→" 05") // 为假:打印" "(空格),两位数的十六进制直接加空格(比如0xAB→" AB") Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); // 将当前字节以十六进制格式输出 } }
Complete Workflow Explanation
1. Initialization (setup() function)
- Serial.begin(9600):Starts serial communication at 9600 baud rate, so we can view output in the Arduino Serial Monitor.
- SPI.begin():Initializes the SPI bus, which is the communication protocol the MFRC522 module uses to talk to the Arduino.
- rfid.PCD_Init():Sets up the MFRC522 module, getting it ready to detect and read RFID cards.
- Key initialization loop:Sets up the default MIFARE card key (all 0xFF), which is a standard default for most MIFARE cards—this code doesn’t use encryption, but it’s a common setup step for the library.
2. Main Loop (loop() function)
- Check for new cards:
rfid.PICC_IsNewCardPresent()checks if an RFID card is close enough to be detected. If not, the loop skips the rest of the code and waits again. - Read the UID:
rfid.PICC_ReadCardSerial()attempts to read the card’s unique identifier (UID). If reading fails (e.g., the card moves away mid-read), the loop resets. - Backup UID:Copies the read UID into a custom array (
nuidPICC)—this is optional, but useful if you want to store or manipulate the UID later. - Print formatted UID:Calls
printHex()to output the UID as a clean, aligned hexadecimal string. - Cleanup:
rfid.PICC_HaltA()puts the RFID card into a low-power sleep state, ending its communication with the reader.rfid.PCD_StopCrypto1()stops any active encryption sessions, ensuring the reader is ready for the next card.
3. The Tricky Ternary Operator
The line Serial.print(buffer[i] < 0x10 ? " 0" : " "); is all about formatting:
- Hexadecimal values can be 1 or 2 digits (e.g.,
0x5is one digit,0x2Ais two). - The ternary operator checks if the current byte is less than
0x10(decimal 16). If yes, it adds a leading zero to make it two digits (so0x5becomes05). If not, it just adds a space for alignment. - This ensures the UID output looks consistent (e.g.,
01 23 AB CDinstead of1 23 AB CD), making it easier to read.
内容的提问来源于stack exchange,提问作者Angelo Juanico




