基于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标准文档(卡片通信协议)