基于STM32F103微控制器與復旦微電子FM1702SL射頻讀卡芯片的驅動開發方案,整合了硬件配置、寄存器操作和通信協議實現:
一、硬件連接設計
1. 管腳映射表
FM1702SL引腳 | STM32F103引腳 | 功能說明 |
---|
VDD | 3.3V | 電源輸入 |
GND | GND | 地線 |
SCK | PA5(SPI1_SCK) | SPI時鐘 |
MISO | PA6(SPI1_MISO) | 主入從出 |
MOSI | PA7(SPI1_MOSI) | 主出從入 |
CS | PA4(GPIO) | 片選控制 |
RST | PA3(GPIO) | 復位信號 |
IRQ | PA2(GPIO) | 中斷輸入 |
2. 電路設計要點
- 電源濾波:在VDD和GND間并聯104陶瓷電容+10μF電解電容
- 天線匹配:采用1.35μH電感+27pF電容的LC諧振電路(參考)
- ESD防護:在RST和CS引腳串聯1kΩ電阻并聯TVS管
二、軟件架構設計
1. 驅動層結構
// 文件結構
fm1702_driver/
├── hal/
│ ├── spi.c # SPI底層驅動
│ └── gpio.c # GPIO控制
├── src/
│ ├── fm1702.c # 核心驅動
│ └── fm1702.h # 寄存器定義
└── example/└── read_card.c # 示例應用
2. 關鍵數據結構
typedef struct {uint8_t version; // 固件版本uint16_t atqa; // ATS響應uint8_t sak; // SEL_RESuint8_t uid[4]; // UID存儲
} FM1702_CardInfo;typedef enum {FM1702_STATE_IDLE,FM1702_STATE_SELECTED,FM1702_STATE_AUTHENTICATED
} FM1702_State;
三、核心功能實現
1. SPI初始化(HAL庫)
void FM1702_SPI_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};// 使能時鐘__HAL_RCC_SPI1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();// 配置SPI引腳GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// SPI參數配置SPI_HandleTypeDef hspi1;hspi1.Instance = SPI1;hspi1.Init.Mode = SPI_MODE_MASTER;hspi1.Init.Direction = SPI_DIRECTION_2LINES;hspi1.Init.DataSize = SPI_DATASIZE_8BIT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;HAL_SPI_Init(&hspi1);
}
2. 寄存器操作
// 讀寄存器函數
uint8_t FM1702_ReadReg(uint8_t addr) {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS拉低SPI_SendByte(addr & 0x7F); // 發送地址(低電平有效)uint8_t data = SPI_ReceiveByte();HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS拉高return data;
}// 寫寄存器函數
void FM1702_WriteReg(uint8_t addr, uint8_t data) {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);SPI_SendByte(addr | 0x80); // 地址最高位設1表示寫操作SPI_SendByte(data);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
3. 射頻卡檢測流程
FM1702_State FM1702_DetectCard(void) {FM1702_WriteReg(0x0D, 0x07); // 設置射頻場強度// 發送請求命令FM1702_WriteReg(0x0A, 0x52); // Request命令HAL_Delay(10);if(FM1702_ReadReg(0x0A) & 0x01) { // 檢測到卡片uint8_t uid[4];FM1702_ReadUID(uid); // 讀取UIDreturn FM1702_STATE_SELECTED;}return FM1702_STATE_IDLE;
}
四、中斷處理機制
1. 中斷服務例程
void EXTI0_IRQHandler(void) {if(EXTI_GetITStatus(EXTI_LINE0) != RESET) {FM1702_ClearIRQFlag(); // 清除中斷標志// 處理卡片插入/移除事件HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); // LED狀態翻轉}EXTI_ClearITPendingBit(EXTI_LINE0);
}
2. 中斷配置
void FM1702_EnableIRQ(void) {EXTI_InitTypeDef EXTI_InitStruct = {0};// 配置EXTI0為下降沿觸發EXTI_InitStruct.Line = EXTI_LINE0;EXTI_InitStruct.Trigger = EXTI_TRIGGER_FALLING;EXTI_InitStruct.LineCmd = ENABLE;HAL_EXTI_SetConfigLine(&EXTI_InitStruct);
}
五、調試與優化
1. 邏輯分析儀捕獲
- 使用Saleae捕獲SPI通信波形,驗證時序是否符合手冊要求(時鐘極性CPOL=0,相位CPHA=0)
2. 常見問題解決
現象 | 可能原因 | 解決方案 |
---|
無法檢測卡片 | 天線匹配不良 | 調整L/C參數至1.35μH+27pF |
通信錯誤 | SPI時鐘頻率過高 | 降低至1MHz以下 |
數據校驗失敗 | CRC計算錯誤 | 實現ISO14443A CRC算法 |
六、完整代碼示例
// 讀卡器初始化
void FM1702_Init(void) {FM1702_GPIO_Init(); // 配置GPIOFM1702_SPI_Init(); // 初始化SPIFM1702_Reset(); // 硬件復位FM1702_WriteReg(0x02, 0x8D); // 啟動射頻場
}// 主循環處理
int main(void) {FM1702_Init();while(1) {FM1702_State state = FM1702_DetectCard();if(state == FM1702_STATE_SELECTED) {// 執行讀寫操作uint8_t block_data[16];FM1702_ReadBlock(0x08, block_data);}}
}
七、性能優化建議
- 低功耗模式:在IDLE狀態下關閉射頻場(設置Reg02[3]=0)
- DMA傳輸:使用DMA實現SPI數據傳輸(配置DMA1_Stream0)
- 加密加速:利用STM32硬件加密模塊加速DES運算
八、參考資料
- 《FM1702SL數據手冊》(復旦微電子官網)
- 代碼 基于STM32F103的FM1702驅動程序 youwenfan.com/contentcsa/72737.html
- STM32F103參考手冊(ARM Cortex-M3內核)
- ISO/IEC 14443-3標準文檔(卡片通信協議)