#ifndef __BSP_RC522_H #define __BSP_RC522_H #include "main.h" #ifdef __cplusplus extern "C" { #endif /* RC522 典型 UID 最大长度为 10 字节 */ #define RC522_UID_MAX_LEN 10U // ================== 站点UID白名单(用户可根据实际卡片填写) ================== // 站点1(A)卡片 UID: 29 AF 22 07 #define STATION_1_UID {0x29, 0xAF, 0x22, 0x07} // 站点2(B)卡片 UID: 1B 45 F3 06 #define STATION_2_UID {0x1B, 0x45, 0xF3, 0x06} // 站点枚举(可扩展) typedef enum { STATION_NONE = 0, STATION_1 = 1, // 29 AF 22 07 STATION_2 = 2, // 1B 45 F3 06 // 可继续添加更多站点 } station_id_t; /** * @brief 根据UID判断属于哪个站点 * @param uid UID字节数组 * @param uid_len UID长度 * @return station_id_t 站点编号 */ station_id_t rc522_match_station(const uint8_t *uid, uint8_t uid_len); /* * RUN 提示灯策略: * 1) 轮询到卡片后点亮一段时间 (RC522_RUN_LED_HOLD_MS) * 2) 超时自动熄灭 * 如需关闭该功能,设置 RC522_RUN_LED_ENABLE 为 0 */ #ifndef RC522_RUN_LED_ENABLE #define RC522_RUN_LED_ENABLE 1U #endif #ifndef RC522_RUN_LED_HOLD_MS #define RC522_RUN_LED_HOLD_MS 300U #endif /* 按当前板卡默认 RUN_LED 低电平点亮 */ #ifndef RC522_RUN_LED_ON_LEVEL #define RC522_RUN_LED_ON_LEVEL GPIO_PIN_RESET #endif /* 最近卡缓存超时时间:超过该时间认为缓存失效 */ #ifndef RC522_CACHE_EXPIRE_MS #define RC522_CACHE_EXPIRE_MS 1500U #endif /* * 是否使用 IRQ 触发后再读卡: * 0 = 纯轮询(推荐先用) * 1 = 依赖 IOR 中断触发(需要在 EXTI 回调中调用 rc522_irq_callback) */ #ifndef RC522_USE_IRQ_TRIGGER #define RC522_USE_IRQ_TRIGGER 0U #endif /** * @brief RC522 读卡状态 */ typedef enum { RC522_OK = 0, RC522_NO_CARD, RC522_ERR_TIMEOUT, RC522_ERR_CRC, RC522_ERR_BCC, RC522_ERR_SPI, RC522_ERR_PARAM, RC522_ERR_INTERNAL } rc522_status_t; /** * @brief 最近一次读到的卡片信息 */ typedef struct { uint8_t valid; // 1: 有效卡信息, 0: 无效 uint8_t uid[RC522_UID_MAX_LEN]; // UID 原始字节 uint8_t uid_len; // UID 长度 (支持 4/7/10) uint8_t sak; // Select Acknowledge uint16_t atqa; // Answer To Request, 高字节在前 uint32_t last_seen_tick_ms; // 最近一次读到该卡的系统毫秒时间 } rc522_card_info_t; /** * @brief 初始化 RC522 模块 (SPI + 寄存器) * @note SPI1 已由 CubeMX 初始化,本函数只做 RC522 芯片侧初始化。 */ rc522_status_t rc522_init(void); /** * @brief 轮询一次读卡,并缓存结果 * @param out_card 可选输出,为 NULL 时仅更新内部缓存 * @return rc522_status_t */ rc522_status_t rc522_poll(rc522_card_info_t *out_card); /** * @brief RC522 周期服务函数(推荐在任务中调用) * @param out_card 可选输出,为 NULL 时仅更新内部状态 * @return RC522_OK: 本次成功读到卡; RC522_NO_CARD: 当前无卡; 其他: 读卡异常 */ rc522_status_t rc522_service(rc522_card_info_t *out_card); /** * @brief 获取最近一次成功读到的卡片信息 * @param out_card 输出参数 * @return 1: 成功复制, 0: 当前无有效卡信息 */ uint8_t rc522_get_last_card(rc522_card_info_t *out_card); /** * @brief 当前是否存在有效缓存卡 * @return 1: 有效, 0: 无效 */ uint8_t rc522_has_valid_card(void); /** * @brief 判断当前卡是否“新卡事件”(与上次输出不同) * @param out_card 输出参数 * @return 1: 新卡, 0: 非新卡或无卡 */ uint8_t rc522_get_new_card(rc522_card_info_t *out_card); /** * @brief 清除内部缓存的最近卡片信息 */ void rc522_clear_last_card(void); /** * @brief 将 UID 格式化为 HEX 字符串 (例如 "DE AD BE EF") * @param card 卡片信息 * @param out_str 输出缓冲区 * @param out_len 输出缓冲区长度 * @return 1: 成功, 0: 参数错误或缓冲区不足 */ uint8_t rc522_uid_to_string(const rc522_card_info_t *card, char *out_str, uint16_t out_len); /** * @brief EXTI 回调入口(可选) * @param GPIO_Pin EXTI 引脚号 */ void rc522_irq_callback(uint16_t GPIO_Pin); #ifdef __cplusplus } #endif #endif /* __BSP_RC522_H */