1. 项目概述
这个基于STM32和RFID技术的员工打卡门禁系统是我去年指导学弟完成的毕业设计项目。当时学弟找到我,说老师要求做一个既有技术含量又实用的系统,最好还能结合物联网概念。经过几次头脑风暴,我们最终确定了这个方案。
系统核心思路很简单:员工刷卡→系统识别→门禁控制→数据记录。但实现起来需要考虑很多细节问题,比如RFID的选型、通信协议的设计、数据库的搭建等。整个项目从构思到完成用了约两个月时间,硬件成本控制在200元以内,软件全部开源。
2. 硬件设计详解
2.1 主控芯片选型
我们选择了STM32F103C8T6作为主控芯片,主要考虑以下几点:
- 价格适中(约15元)
- 72MHz主频足够处理RFID数据
- 丰富的GPIO和外设接口
- 完善的开发文档和社区支持
注意:购买时要认准正版芯片,市面上有很多打磨翻新的假货,会导致各种奇怪的问题。
2.2 RFID模块选择
经过对比测试,最终选用MFRC522射频识别模块:
- 工作频率13.56MHz(ISO14443A标准)
- 有效识别距离3-5cm
- 支持Mifare系列卡片
- SPI接口,方便与STM32连接
实际使用中发现,模块天线对识别距离影响很大。我们通过调整天线匹配电路(修改C1、C2电容值),将识别距离从最初的2cm提升到5cm。
2.3 外围电路设计
完整的硬件系统包含以下模块:
- 电源电路:AMS1117稳压芯片,提供3.3V和5V输出
- 显示模块:0.96寸OLED(SSD1306驱动)
- 通信模块:ESP-01S WiFi模块
- 执行机构:5V继电器控制电磁锁
- 状态指示:RGB LED和蜂鸣器
原理图设计时特别注意了:
- 为STM32所有未使用的IO口添加了上拉电阻
- RFID模块的SPI总线加了33Ω阻抗匹配电阻
- 继电器线圈并联续流二极管
3. 软件系统实现
3.1 下位机程序设计
下位机程序采用Keil MDK开发,主要功能流程如下:
c复制void main() {
// 初始化各外设
System_Init();
while(1) {
if(RFID_CheckCard()) { // 检测到卡片
uint8_t ID[4];
RFID_ReadID(ID); // 读取卡号
OLED_ShowID(ID); // 显示卡号
WiFi_SendData(ID); // 发送到上位机
if(Receive_Response() == SUCCESS) {
Relay_Open(2000); // 开门2秒
Buzzer_Beep(1); // 提示音
} else {
Buzzer_Beep(3); // 错误提示
}
}
delay_ms(100);
}
}
3.2 上位机系统开发
上位机使用Python+PyQt5开发,核心功能包括:
- 数据库管理
- 采用SQLite存储员工信息
- 表结构设计:
sql复制CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
card_id TEXT UNIQUE NOT NULL,
status INTEGER DEFAULT 0,
last_check TIMESTAMP
);
- TCP通信服务
python复制class ServerThread(QThread):
def run(self):
with socket.socket() as s:
s.bind(('0.0.0.0', 8080))
s.listen(1)
while True:
conn, addr = s.accept()
data = conn.recv(1024).decode()
self.process_data(data)
def process_data(self, data):
# 验证卡号并返回响应
card_id = data.strip()
result = db.query("SELECT * FROM employees WHERE card_id=?", (card_id,))
if result:
name = result[0]['name']
db.execute("UPDATE employees SET status=1, last_check=CURRENT_TIMESTAMP WHERE card_id=?", (card_id,))
return f"SUCCESS,{name}"
return "FAIL"
4. 系统调试与优化
4.1 常见问题排查
在实际调试中遇到了几个典型问题:
- RFID识别不稳定
- 现象:有时能读卡,有时不能
- 排查:用逻辑分析仪抓取SPI波形
- 解决:调整SPI时钟分频(从PCLK/2改为PCLK/4)
- WiFi频繁断开
- 现象:ESP-01S工作几分钟后掉线
- 排查:测量3.3V电源纹波达300mV
- 解决:增加100μF钽电容滤波
- 数据库写入冲突
- 现象:多设备同时打卡时数据错误
- 排查:SQLite未启用事务
- 解决:添加BEGIN/COMMIT事务控制
4.2 性能优化技巧
- RFID轮询优化
原始方案是每100ms查询一次卡片,改为:
- 先检测场强变化(通过MFRC522的RFCfgReg)
- 只有检测到变化时才进行完整读卡流程
- 数据压缩传输
卡号原始传输格式为"ID:xx:xx:xx:xx",优化为:
- 将4字节卡号转为32位整数
- 使用二进制协议传输,减少75%数据量
- 数据库索引优化
为card_id字段添加索引后,查询速度从15ms降至2ms。
5. 项目扩展方向
这个基础系统还可以进一步扩展:
- 人脸识别双因素认证
- 增加OV2640摄像头模块
- 使用OpenMV实现简单人脸检测
- 必须同时刷卡和人脸匹配才开门
- 云端数据同步
- 通过MQTT协议上传数据到阿里云IoT
- 实现多网点数据汇总分析
- 增加微信小程序查询接口
- 考勤数据分析
- 使用Pandas分析打卡数据
- 自动生成月度考勤报表
- 识别异常打卡行为(如代打卡)
实际开发中发现,STM32的RAM资源比较紧张(仅20KB),如果要添加复杂功能,建议升级到STM32F4系列(192KB RAM)。
6. 开发经验分享
通过这个项目,总结了几点重要经验:
- 硬件设计
- 一定要先画框图再画原理图
- 预留足够的测试点(我们加了20个)
- 电源电路要留30%余量
- 软件开发
- 使用版本控制(Git)管理代码
- 模块化编程,方便调试
- 关键函数添加详细注释
- 调试技巧
- 善用调试器(J-Link比ST-Link好用)
- 添加丰富的状态指示灯
- 保持串口日志输出
这个项目虽然不算复杂,但完整覆盖了嵌入式系统开发的各个环节,特别适合作为毕业设计选题。学弟最后不仅顺利通过答辩,还凭借这个项目拿到了心仪公司的offer。