1. 项目概述
最近完成了一个基于STM32的RFID刷卡识别系统,这个项目将多种实用功能整合在一起,形成了一个小型智能门禁系统的雏形。系统核心功能包括RFID卡识别、状态显示、电机控制、卡片管理和温度检测等模块。通过这个项目,我不仅巩固了STM32开发的基础知识,还深入理解了嵌入式系统中多模块协同工作的实现方式。
这个系统最吸引人的地方在于它的实用性和扩展性。虽然看起来是个简单的刷卡系统,但通过合理的模块组合和逻辑设计,可以实现类似智能门禁的功能。我在开发过程中遇到了不少挑战,比如如何确保RFID识别的稳定性、步进电机控制的精确性以及多任务处理的协调性等。
2. 硬件选型与电路设计
2.1 主控芯片选择
我选择了STM32F103C8T6作为主控芯片,这款芯片具有以下优势:
- 72MHz主频,性能足够处理本项目的所有任务
- 64KB Flash和20KB SRAM,满足程序存储和运行需求
- 丰富的外设接口,包括GPIO、USART、SPI、I2C等
- 价格实惠,开发资源丰富,适合学习和项目开发
在实际使用中,这款芯片表现稳定,能够很好地协调各个外设模块的工作。需要注意的是,在使用前要正确配置时钟树,确保各外设工作在合适的频率下。
2.2 RFID模块选型与连接
我选用的是MFRC522 RFID模块,这是目前市面上最常见的13.56MHz RFID读卡器模块。它具有以下特点:
- 支持ISO14443A/MIFARE协议
- 最大通信距离约5cm(视卡片类型而定)
- 通过SPI接口与主控通信
- 工作电压3.3V,与STM32兼容
连接方式如下:
code复制MFRC522 STM32
SDA(SS) -> PA4
SCK -> PA5
MOSI -> PA7
MISO -> PA6
IRQ -> 不接
GND -> GND
RST -> PB0
3.3V -> 3.3V
在实际使用中发现,模块的天线部分对识别距离影响很大。为了提高识别成功率,我做了以下优化:
- 确保天线线圈完好无损,没有短路或断路
- 在天线周围避免放置金属物体
- 适当调整匹配电容的值(通常为27pF)
2.3 OLED显示模块
选用的是0.96寸SSD1306驱动的OLED屏幕,分辨率为128x64。这种屏幕有以下优点:
- 自发光,无需背光
- 对比度高,可视角度大
- 通过I2C接口通信,接线简单
- 功耗低,适合嵌入式应用
连接方式:
code复制OLED STM32
GND -> GND
VCC -> 3.3V
SCL -> PB6
SDA -> PB7
在实际使用中,我发现SSD1306的驱动库占用资源较多,如果系统出现卡顿,可以考虑优化显示刷新逻辑,比如只刷新变化的部分而非全屏刷新。
3. 系统功能实现
3.1 RFID卡识别与处理
RFID卡识别是整个系统的核心功能。我使用MFRC522库来实现卡片的检测和读取。主要流程如下:
- 初始化MFRC522模块
- 定期检测是否有卡片靠近
- 读取卡片UID
- 验证卡片是否在授权列表中
- 根据验证结果执行相应操作
关键代码实现:
c复制// 初始化RFID模块
void RFID_Init(void) {
MFRC522_Init();
}
// 检测并处理卡片
void RFID_Process(void) {
if (MFRC522_CheckCard()) {
uint32_t card_id = MFRC522_ReadCardSerial();
if (CheckCardValid(card_id)) {
Card_Success();
if (Temperature_Normal(Read_Temperature())) {
Stepper_Rotate(200); // 开锁
}
} else {
Card_Fail();
}
}
}
在实际测试中发现,连续快速刷卡可能会导致系统响应不及时。为了解决这个问题,我增加了防抖处理,设置了一个最小刷卡间隔时间(如500ms)。
3.2 状态显示与用户反馈
系统通过OLED和LED灯提供用户反馈。OLED显示卡片ID和系统状态,LED灯指示刷卡结果(绿灯成功,红灯失败)。
显示优化技巧:
- 使用大字体显示卡片ID,方便用户查看
- 添加系统状态栏,显示温度、时间等信息
- 使用图标和文字结合的方式,提高可读性
- 实现简单的动画效果,提升用户体验
LED控制注意事项:
- 使用限流电阻保护LED
- 对于高亮度LED,可以考虑PWM调光
- 添加LED状态说明,避免用户混淆
3.3 步进电机控制
使用28BYJ-48步进电机模拟门锁开关。这款电机具有以下特点:
- 5V供电
- 减速比为1:64
- 步距角5.625°,64步/转
- 四相八拍工作方式
控制要点:
- 使用ULN2003驱动芯片
- 按照正确的相序通电
- 控制脉冲间隔时间调节转速
- 添加限位开关或位置反馈更可靠
改进后的电机控制代码:
c复制// 步进电机相序表
const uint8_t phase_table[8] = {
0x01, // 0001
0x03, // 0011
0x02, // 0010
0x06, // 0110
0x04, // 0100
0x0C, // 1100
0x08, // 1000
0x09 // 1001
};
void Stepper_Rotate(int steps) {
int direction = steps > 0 ? 1 : -1;
steps = abs(steps);
for (int i = 0; i < steps; i++) {
static uint8_t phase = 0;
phase = (phase + direction + 8) % 8;
GPIO_Write(GPIOB, phase_table[phase] << 4); // 假设接在PB4-PB7
delay(2); // 控制转速
}
}
4. 系统安全与扩展功能
4.1 卡片管理机制
系统实现了安全的卡片添加机制:
- 必须刷一张已授权卡片才能进入添加模式
- 新卡片需要二次确认
- 卡片信息存储在Flash中,掉电不丢失
- 可设置管理员卡片,拥有特殊权限
卡片存储优化:
- 使用结构体存储卡片信息
- 添加卡片有效期字段
- 实现卡片删除功能
- 添加卡片使用记录
4.2 温度检测与安全控制
使用DS18B20数字温度传感器检测人体温度:
- 单总线接口,接线简单
- 精度±0.5℃
- 测量范围-55℃~+125℃
- 无需外部元件
温度检测实现要点:
- 严格的时序控制
- CRC校验确保数据正确
- 多次测量取平均值
- 异常温度报警
温度检测代码优化:
c复制#define TEMP_NORMAL_MIN 36.0f
#define TEMP_NORMAL_MAX 37.5f
#define TEMP_SAMPLE_TIMES 3
float Get_Stable_Temperature(void) {
float sum = 0;
for (int i = 0; i < TEMP_SAMPLE_TIMES; i++) {
sum += DS18B20_GetTemp();
delay(200);
}
return sum / TEMP_SAMPLE_TIMES;
}
int Is_Temperature_Normal(void) {
float temp = Get_Stable_Temperature();
return temp >= TEMP_NORMAL_MIN && temp <= TEMP_NORMAL_MAX;
}
4.3 系统安全考虑
- RFID通信加密:虽然MIFARE Classic卡片有安全隐患,但对于一般应用足够
- 温度异常记录:记录异常温度事件,便于追溯
- 防拆机保护:检测外壳是否被打开
- 看门狗定时器:防止程序跑飞
5. 系统优化与问题排查
5.1 性能优化技巧
- 合理分配任务优先级
- 使用中断处理紧急事件
- 优化显示刷新策略
- 减少不必要的延时
- 使用DMA传输数据
5.2 常见问题与解决方法
-
RFID识别不稳定:
- 检查天线连接
- 调整匹配电容
- 确保供电稳定
- 避免金属干扰
-
步进电机不转或抖动:
- 检查相序是否正确
- 确认供电充足
- 调整脉冲间隔时间
- 检查机械结构是否卡住
-
温度读数异常:
- 检查传感器接线
- 确保时序正确
- 添加CRC校验
- 更换传感器测试
-
OLED显示异常:
- 检查I2C地址
- 确认初始化顺序
- 调整对比度值
- 检查电源稳定性
5.3 系统扩展思路
- 添加无线通信模块(如ESP8266)实现远程控制
- 增加指纹识别模块,实现多因素认证
- 添加摄像头模块,记录开门事件
- 实现数据记录和查询功能
- 开发手机APP进行系统管理
在完成这个项目的过程中,我深刻体会到嵌入式系统开发的乐趣和挑战。每个模块单独测试时可能工作正常,但整合在一起时就会出现各种意想不到的问题。通过不断的调试和优化,最终实现了一个稳定可靠的RFID刷卡识别系统。这个项目还有很多可以改进和扩展的地方,后续我计划添加网络功能和更高级的安全特性。
