161 lines
4.2 KiB
C
161 lines
4.2 KiB
C
#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 */
|