STM32智能刷卡消费系统基于uC/OS-III操作系统的设计与实现


一、项目概述与开发背景

本系统是一款基于STM32微控制器的智能刷卡消费终端,集成RFID识别、OLED显示、Flash存储、蓝牙通信等核心模块。项目采用uC/OS-III实时操作系统实现多任务并发处理,适用于校园一卡通、企业食堂等小额支付场景。系统支持定额扣款、按次消费、时段消费等多种模式,并通过W25Qxx Flash芯片实现交易记录的持久化存储。

核心功能:

  1. RFID卡识别与用户信息管理
  2. 多模式消费扣款逻辑
  3. OLED交互界面显示
  4. 蓝牙远程指令控制
  5. 交易数据Flash存储
  6. 独立看门狗系统监控

二、系统架构设计
2.1 硬件架构

https://i3.wp.com/img-blog.csdnimg.cn/20210731165823593.png

关键硬件组成:

  • 主控芯片:STM32F4系列(Cortex-M4内核)
  • RFID模块:MFRC522非接触式读卡器
  • 存储模块:W25Q128FV SPI Flash(16MB)
  • 显示模块:0.96寸OLED(SSD1306驱动)
  • 输入设备:4×4矩阵键盘
  • 通信模块: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 工程配置要点
    1. 配置系统时钟树(主频168MHz)

    2. 启用FPU浮点运算单元

    3. 设置正确的Flash下载算法

    4. 配置uC/OS-III内核参数:

      c

      Copy

      #define OS_CFG_PRIO_MAX       32u
      #define OS_CFG_TICK_RATE_HZ  1000u
      
    5. 优化编译选项:

    6. 启用-O2优化等级
    7. 勾选"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);
    

    典型任务划分:

    1. 主控任务(优先级6):系统初始化、资源创建
    2. RFID扫描任务(优先级7):实时检测卡片
    3. 蓝牙处理任务(优先级8):处理AT指令
    4. 显示刷新任务(优先级9):OLED界面更新
    4.2 RFID模块驱动

    MFRC522工作流程:

    Image

    Code

    MCU

    MFRC522

    发送寻卡指令(0x26)

    返回卡类型

    防冲突指令(0x93)

    返回卡UID

    选择卡片(0x70)

    认证指令(0x60)

    读写数据块

    MCU

    MFRC522

    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;
    

    写入流程:

    1. 获取写信号量
    2. 擦除目标扇区
    3. 按页写入数据
    4. 校验写入结果
    5. 释放信号量

    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 同步机制设计
    1. 互斥锁应用场景

    2. mutex_oled:保证OLED刷新原子性
    3. mutex_rc522:防止多任务同时访问RFID模块
    4. 信号量使用

    5. RC522_ONLINE_SEM:卡检测事件通知
    6. w25qxx_print_sem:Flash操作完成信号
    7. 消息队列示例

      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 调试手段
    1. LED状态指示:关键流程添加LED闪烁

      c

      Copy

      LED1_ON();
      // 关键操作
      LED1_OFF();
      
    2. 串口调试日志

      c

      Copy

      #define DEBUG_LOG(fmt, ...) \
          printf("[%s] "fmt"\r\n", __func__, ##__VA_ARGS__)
      
    3. 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);
    

  • 七、项目扩展方向
    1. 安全增强
    2. 添加AES-128数据加密
    3. 实现双向认证流程
    4. 加入防拆机检测电路
    5. 功能扩展
    6. 支持NFC手机支付
    7. 添加热敏小票打印
    8. 集成4G联网功能
    9. 性能优化
    10. 启用DMA加速SPI传输
    11. 实现Flash磨损均衡算法
    12. 采用RT-Thread等更轻量级OS

    结语

    通过本项目的开发实践,读者可以掌握基于实时操作系统的嵌入式开发全流程。重点理解多任务间的资源协调、底层驱动的封装优化、以及系统级调试方法。建议在完成基础功能后,逐步尝试扩展模块的开发,以全面提升嵌入式系统设计能力。

    作者:四代目 水门

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32智能刷卡消费系统基于uC/OS-III操作系统的设计与实现

    发表回复