一、項目概述與開發背景
本系統是一款基于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
結語
通過本項目的開發實踐,讀者可以掌握基于實時操作系統的嵌入式開發全流程。重點理解多任務間的資源協調、底層驅動的封裝優化、以及系統級調試方法。建議在完成基礎功能后,逐步嘗試擴展模塊的開發,以全面提升嵌入式系統設計能力。