1. 项目概述
这个基于STM32的RFID员工打卡门禁系统是我指导过的一个典型毕业设计案例。在当前企业数字化转型背景下,传统纸质考勤方式已经无法满足现代化管理需求。这个系统通过射频识别技术实现员工身份自动识别,结合数据库管理完成考勤统计,是一个将嵌入式开发与实际应用场景结合的典型案例。
系统采用模块化设计思路,硬件部分以STM32F103C8T6为主控芯片,搭配RC522 RFID模块、ESP-01S WiFi模块、OLED显示屏和继电器模块;软件部分则实现了上位机数据库管理、TCP通信协议和下位机RFID识别功能。整套系统开发周期约2个月,物料成本控制在200元以内,非常适合作为电子类专业学生的综合实践项目。
2. 硬件设计详解
2.1 主控模块选型
选择STM32F103C8T6作为主控芯片主要基于以下考虑:
- 72MHz主频的Cortex-M3内核,性能足够处理RFID数据解析和通信任务
- 64KB Flash和20KB SRAM满足程序存储和运行时数据需求
- 丰富的外设接口(USART、SPI、I2C等)方便连接各类传感器
- 价格低廉(约15元)且开发资料丰富
实际开发中发现,使用HAL库可以显著降低开发难度。建议初学者避免直接操作寄存器,先用CubeMX生成基础代码框架。
2.2 RFID模块电路设计
RC522射频模块通过SPI接口与主控通信,典型连接方式如下:
| STM32引脚 | RC522引脚 | 功能说明 |
|---|---|---|
| PA4 | NSS | 片选信号 |
| PA5 | SCK | 时钟线 |
| PA6 | MISO | 主入从出 |
| PA7 | MOSI | 主出从入 |
| 3.3V | VCC | 电源 |
| GND | GND | 地线 |
| - | RST | 接10K上拉电阻 |
| - | IRQ | 悬空 |
电路设计注意事项:
- 天线部分需要保留足够净空区,周围避免放置金属元件
- 电源端需加0.1μF去耦电容
- 通信线长度不宜超过10cm,必要时加22Ω串联电阻匹配阻抗
2.3 电源管理设计
系统采用AMS1117-3.3稳压芯片为各模块供电,典型电路参数:
- 输入电容:10μF钽电容
- 输出电容:10μF+0.1μF并联
- 最大负载电流:800mA(需考虑继电器吸合电流)
实测表明,当使用18650锂电池供电时,系统待机电流约15mA,工作峰值电流不超过200mA,单次充电可支持连续工作8小时以上。
3. 软件系统实现
3.1 下位机程序设计
RFID识别流程采用状态机设计,主要状态转换如下:
c复制typedef enum {
IDLE_STATE,
CARD_DETECT_STATE,
DATA_READ_STATE,
DATA_SEND_STATE,
DOOR_CTRL_STATE
} SystemState;
void RFID_Task(void) {
static SystemState state = IDLE_STATE;
static uint8_t cardID[4];
switch(state) {
case IDLE_STATE:
if(PCD_CheckCard()) {
state = CARD_DETECT_STATE;
}
break;
case CARD_DETECT_STATE:
if(PCD_ReadCardSerial(cardID) == MI_OK) {
state = DATA_SEND_STATE;
}
break;
case DATA_SEND_STATE:
if(WIFI_SendData(cardID)) {
state = DOOR_CTRL_STATE;
}
break;
case DOOR_CTRL_STATE:
Door_Control(DOOR_OPEN);
HAL_Delay(3000);
Door_Control(DOOR_CLOSE);
state = IDLE_STATE;
break;
}
}
关键点说明:
- 使用HAL库的硬件SPI接口,时钟配置为4.5MHz
- 卡号读取采用ISO14443A标准,每次读取需要约120ms
- 状态机设计避免了阻塞式等待,提高系统响应速度
3.2 上位机数据库设计
采用SQLite3作为本地数据库,表结构设计如下:
python复制def init_database():
conn = sqlite3.connect('attendance.db')
c = conn.cursor()
# 员工信息表
c.execute('''CREATE TABLE IF NOT EXISTS employees
(id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
card_id TEXT UNIQUE NOT NULL,
department TEXT)''')
# 考勤记录表
c.execute('''CREATE TABLE IF NOT EXISTS records
(id INTEGER PRIMARY KEY AUTOINCREMENT,
card_id TEXT NOT NULL,
check_time DATETIME NOT NULL,
status INTEGER DEFAULT 1,
FOREIGN KEY(card_id) REFERENCES employees(card_id))''')
conn.commit()
conn.close()
数据库操作优化建议:
- 为card_id字段建立索引加速查询
- 使用事务批量插入考勤记录
- 定期执行VACUUM命令压缩数据库
3.3 TCP通信协议设计
自定义的简单通信协议格式如下:
| 字段 | 长度(字节) | 说明 |
|---|---|---|
| 头标识 | 2 | 固定为0xAA55 |
| 数据长度 | 1 | 有效数据长度 |
| 命令字 | 1 | 0x01:打卡数据 0x02:控制指令 |
| 数据区 | N | 变长数据 |
| 校验和 | 1 | 前面所有字节的累加和 |
典型数据包示例:
- 下位机→上位机:AA55 04 01 01 02 03 04 0F
- 上位机→下位机:AA55 05 02 4A 6F 68 6E 00 C6
4. 系统调试与优化
4.1 RFID识别距离优化
通过实验测得不同天线参数下的识别距离:
| 天线匹配电容(pF) | 识别距离(cm) |
|---|---|
| 18 | 2.5 |
| 22 | 3.8 |
| 27 | 4.2 |
| 33 | 3.5 |
| 39 | 2.1 |
优化措施:
- 最终选用27pF匹配电容
- 在天线外围增加5mm宽铜箔作为屏蔽环
- 调整Q值设置寄存器值为0x3F
4.2 抗干扰处理
实际测试中发现的干扰问题及解决方案:
-
继电器动作导致系统复位
- 在继电器线圈两端并联1N4148续流二极管
- 电源走线加粗至0.5mm以上
-
多卡同时出现时的冲突
- 软件增加防冲突算法
- 设置最小识别间隔为500ms
-
金属环境下的识别失败
- 在天线背面粘贴3mm厚磁性吸波材料
- 调整发射功率为0x7F
5. 项目扩展方向
在实际部署中,可以考虑以下功能增强:
-
人脸识别双因素认证
- 增加OV2640摄像头模块
- 移植OpenMV固件实现简单人脸检测
- 与RFID信息进行比对验证
-
云端数据同步
- 使用ESP32替代ESP8266
- 通过MQTT协议上传数据至阿里云IoT平台
- 开发微信小程序查询考勤记录
-
考勤数据分析
- 基于Python的pandas库进行迟到早退统计
- 使用matplotlib生成月度考勤报表
- 实现异常打卡行为检测算法
这个项目最让我印象深刻的是调试RFID识别距离的过程。通过反复调整天线匹配电路,最终将识别距离从最初的1.5cm提升到4.2cm,这个经验告诉我硬件调试需要极大的耐心。建议后续开发者在设计PCB时,预留天线匹配电路的可调空间,方便后期优化。