STM32智能刷卡消费系统(uC/OS-III)
一、项目概述与开发背景
本系统是一款基于STM32微控制器的智能刷卡消费终端,集成RFID识别、OLED显示、Flash存储、蓝牙通信等核心模块。项目采用uC/OS-III实时操作系统实现多任务并发处理,适用于校园一卡通、企业食堂等小额支付场景。系统支持定额扣款、按次消费、时段消费等多种模式,并通过W25Qxx Flash芯片实现交易记录的持久化存储。
核心功能:
- RFID卡识别与用户信息管理
- 多模式消费扣款逻辑
- OLED交互界面显示
- 蓝牙远程指令控制
- 交易数据Flash存储
- 独立看门狗系统监控
二、系统架构设计
2.1 硬件架构
https://img-blog.csdnimg.cn/20210731165823593.png
关键硬件组成:
- 主控芯片:STM32F4系列(Cortex-M4内核)
- RFID模块:MFRC522非接触式读卡器
- 存储模块:W25Q128FV SPI Flash(16MB)
- 显示模块:0.96寸OLED(SSD1306驱动)
- 输入设备:4x4矩阵键盘
- 通信模块:HC-05蓝牙模块
- 辅助模块:蜂鸣器、LED状态灯、RTC时钟
2.2 软件架构
plaintext
Copy
应用层
├── 用户界面任务
├── RFID处理任务
├── 蓝牙通信任务
├── 键盘输入任务
└── 数据存储任务系统层
├── uC/OS-III实时内核
├── 硬件抽象层(HAL)
│ ├── SPI
│ ├── I2C
│ ├── GPIO
│ └── USART
└── 驱动程序├── OLED显示├── W25Qxx存储└── MFRC522驱动
三、开发环境搭建
3.1 工具准备
- IDE:Keil MDK-ARM V5
- 调试工具:J-Link/J-Trace
- 源码管理:Git + VS Code
- 串口工具:SecureCRT
3.2 工程配置要点
-
配置系统时钟树(主频168MHz)
-
启用FPU浮点运算单元
-
设置正确的Flash下载算法
-
配置uC/OS-III内核参数:
c
Copy
#define OS_CFG_PRIO_MAX 32u #define OS_CFG_TICK_RATE_HZ 1000u
-
优化编译选项:
- 启用-O2优化等级
- 勾选"Use MicroLIB"
四、关键模块实现解析
4.1 uC/OS-III任务设计
任务创建模板:
c
Copy
void Task_Function(void *p_arg)
{OS_ERR err;while(1) {// 任务主体代码OSTimeDlyHMSM(0, 0, 0, 100, OS_OPT_TIME_HMSM_STRICT, &err);}
}// 任务控制块定义
OS_TCB Task_TCB;
CPU_STK Task_STK[512];// 任务创建
OSTaskCreate(&Task_TCB,"Task_Name",Task_Function,0,6, // 优先级Task_STK,512/10,512,0,0,0,OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,&err);
典型任务划分:
- 主控任务(优先级6):系统初始化、资源创建
- RFID扫描任务(优先级7):实时检测卡片
- 蓝牙处理任务(优先级8):处理AT指令
- 显示刷新任务(优先级9):OLED界面更新
4.2 RFID模块驱动
MFRC522工作流程:
Image
Code
MFRC522MCUMFRC522MCU发送寻卡指令(0x26)返回卡类型防冲突指令(0x93)返回卡UID选择卡片(0x70)认证指令(0x60)读写数据块
关键代码片段:
c
Copy
uint8_t MFRC522_Auth(uint8_t authMode, uint8_t blockAddr, uint8_t *sectorKey, uint8_t *serNum)
{uint8_t buff[12];buff[0] = authMode;buff[1] = blockAddr;memcpy(&buff[2], sectorKey, 6);memcpy(&buff[8], serNum, 4);return MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
}
4.3 Flash存储设计
存储结构规划:
c
Copy
#define W25QXX_MSG_SIZE 64 // 每条记录64字节
#define W25QXX_MSG_ADDR (W25QXX_Block(0)+W25QXX_Sector(1))typedef struct {uint8_t cardUID[8]; // 卡号float balance; // 余额uint32_t timestamp; // RTC时间戳uint8_t type; // 消费类型
} TransactionRecord;
写入流程:
- 获取写信号量
- 擦除目标扇区
- 按页写入数据
- 校验写入结果
- 释放信号量
c
Copy
void Write_Transaction(TransactionRecord *record)
{OS_ERR err;OSSemPend(&Flash_Sem, 0, OS_OPT_PEND_BLOCKING, 0, &err);uint8_t buffer[W25QXX_MSG_SIZE];memset(buffer, 0, sizeof(buffer));memcpy(buffer, record, sizeof(TransactionRecord));W25Qxx_Erase_Sector(W25QXX_MSG_ADDR);W25Qxx_Page_Write(buffer, W25QXX_MSG_ADDR, W25QXX_MSG_SIZE);OSSemPost(&Flash_Sem, OS_OPT_POST_1, &err);
}
五、系统资源管理策略
5.1 同步机制设计
-
互斥锁应用场景:
mutex_oled
:保证OLED刷新原子性mutex_rc522
:防止多任务同时访问RFID模块
-
信号量使用:
RC522_ONLINE_SEM
:卡检测事件通知w25qxx_print_sem
:Flash操作完成信号
-
消息队列示例:
c
Copy
OS_Q keyboard_q; // 键盘输入队列 void Key_Scan_Task(void) {char key = Key_GetNum();OSQPost(&keyboard_q, &key, sizeof(char), OS_OPT_POST_FIFO, &err); }
5.2 内存管理优化
- 使用uC/OS-III内置内存池
- 关键数据结构静态分配
- 避免在中断服务程序中动态分配内存
c
Copy
OS_MEM *MemPool;
uint8_t MemBuff[10][64]; // 预分配内存池void Mem_Init(void)
{OSMemCreate(MemPool, "Memory Pool", MemBuff, 10, 64, &err);
}
六、开发调试技巧
6.1 调试手段
-
LED状态指示:关键流程添加LED闪烁
c
Copy
LED1_ON(); // 关键操作 LED1_OFF();
-
串口调试日志:
c
Copy
#define DEBUG_LOG(fmt, ...) \printf("[%s] "fmt"\r\n", __func__, ##__VA_ARGS__)
-
uC/OS-III性能监控:
c
Copy
CPU_SR_ALLOC(); OS_CPU_SysTickInit(SystemCoreClock / OSCfg_TickRate_Hz);
6.2 常见问题解决
问题1:OLED显示乱码
- 检查I2C地址是否正确(0x78/0x7A)
- 验证字库编码格式(GB2312/Unicode)
- 测量电源电压是否稳定(3.3V±5%)
问题2:Flash写入失败
- 确认写保护引脚状态
- 增加写操作超时检测
- 添加CRC校验机制
问题3:多任务优先级反转
-
使用互斥锁的优先级继承策略
c
Copy
OSMutexCreate(&mutex, "Mutex", OS_OPT_PRIO_INHERIT, &err);
七、项目扩展方向
- 安全增强:
- 添加AES-128数据加密
- 实现双向认证流程
- 加入防拆机检测电路
- 功能扩展:
- 支持NFC手机支付
- 添加热敏小票打印
- 集成4G联网功能
- 性能优化:
- 启用DMA加速SPI传输
- 实现Flash磨损均衡算法
- 采用RT-Thread等更轻量级OS
结语
通过本项目的开发实践,读者可以掌握基于实时操作系统的嵌入式开发全流程。重点理解多任务间的资源协调、底层驱动的封装优化、以及系统级调试方法。建议在完成基础功能后,逐步尝试扩展模块的开发,以全面提升嵌入式系统设计能力。