125K RFID解码

ID卡(如EM4100)输出的数据已经是曼彻斯特编码了。需要对捕获的信号进行曼彻斯特解码(不是编码),才能得到正确的数据位。

曼彻斯特编码的方式一般有两种:

image

我们使用的EM4100属于第一种。即:1用 0 1表示,0 用 1 0表示。

image

协议规定:1 bit 占用 64 个载波周期,载波频率:fc=125 kHz

所以:数据位速率就是:

image

image

image

所以:全位脉宽为512us,半位脉宽为256us。

当 64 位的最后一位发完之后,芯片会立刻从第一位重新开始发送,一直循环,直到磁场消失(掉电)。

image

 

我们使用状态机的方法进行数据解析:

首先讲一下我们需要用到的几个状态,我们这几个状态都写到

状态枚举定义

typedef enum {
    RFID_STATE_IDLE = 0,           // 空闲状态
    RFID_STATE_WAIT_FIRST_EDGE,    // 等待第一个边沿状态,验证第一个1状态
    RFID_STATE_SYNC_HEADER,        // 同步头检测(后续8个"1")
    RFID_STATE_DATA_RECEIVE,       // 数据接收状态
    RFID_STATE_CHECK_STOP_BIT,     //检查停止位状态
    RFID_STATE_FRAME_PROCESS,      // 帧处理状态
} rfid_state_t;

1.空闲状态:解码器的初始和复位状态,没有检测到任何有效信号。检测到有效上升沿 → 转移到等待第一个边沿状态

2.等待第一个边沿状态:已检测到起始上升沿,等待对应的下降沿以确认第一个数据位。 检测到下降,并且和上升沿的间隔时间满足→ 转移到同步头检测状态;超时错误→ 空闲状态。

3.同步头检测状态:检测和验证同步头中的后续8个连续的"1"。成功检测→ 数据接收状态;失败 → 空闲状态。

4.数据接收状态:接收和解析数据位(40位ID + 14位校验 + 1位停止位)。成功接收完整数据帧→帧处理状态。接收出错 → 空闲状态。

5.检查停止位状态:已经接收64位,检验停止位是否正确。

6.帧处理状态:帧处理完成→ IDLE(准备接收下一帧)

 触发状态转换的事件枚举定义

/* 重新定义的事件类型 -------------------------------------------------*/
typedef enum {
    RFID_EVT_NONE = 0,              // 无事件
    
    /* 边沿类型 + 时间间隔组合事件 */
    RFID_EVT_FULL_RISING,           // 完整位时间的上升沿(间隔≈512μs)
    RFID_EVT_FULL_FALLING,          // 完整位时间的下降沿(间隔≈512μs)
    RFID_EVT_HALF_RISING,           // 半位时间的上升沿(间隔≈256μs)
    RFID_EVT_HALF_FALLING,          // 半位时间的下降沿(间隔≈256μs)
    
    /* 特殊事件 */
    RFID_EVT_FRAME_GAP,             // 帧间隔(间隔>3000μs)
    RFID_EVT_TIMEOUT,               // 超时事件
    RFID_EVT_INVALID_INTERVAL,      // 无效时间间隔(既不是256μs也不是512μs)
    
    /* 数据验证事件 */
    RFID_EVT_SYNC_COMPLETE,         // 同步头完成(内部事件)
    RFID_EVT_DATA_COMPLETE,         // 数据接收完成(内部事件)
    
    RFID_EVT_COUNT                  // 事件总数
} rfid_event_t;

状态转换表项结构

typedef struct {
    rfid_state_t current_state;     // 当前状态
    rfid_event_t event;             // 触发事件
    rfid_state_t next_state;        // 下一个状态
    void (*callback)(rfid_decoder_t *decoder, rfid_event_data_t *event); // 回调函数
} rfid_state_transition_t;

完整状态转换表

/* 状态转换表 --------------------------------------------------------*/
static const rfid_state_transition_t state_transition_table[] = {
    /*******************************************************************
     * 状态1:空闲状态 (RFID_STATE_IDLE)
     * 描述:系统初始状态,等待RFID卡片出现
     * 目标:检测帧间隔,准备开始新帧
     *******************************************************************/
    {
        .current_state = RFID_STATE_IDLE,
        .event = RFID_EVT_FRAME_GAP,           // 检测到帧间隔
        .next_state = RFID_STATE_WAIT_FIRST_EDGE,  // 转换到等待第一个边沿
        .callback = on_idle_frame_gap          // 帧开始回调
    },
    {
        .current_state = RFID_STATE_IDLE,
        .event = RFID_EVT_FULL_RISING,         // 检测到完整位上升沿
        .next_state = RFID_STATE_IDLE,         // 保持空闲
        .callback = on_idle_ignore             // 忽略噪声
    },
    {
        .current_state = RFID_STATE_IDLE,
        .event = RFID_EVT_FULL_FALLING,        // 检测到完整位下降沿
        .next_state = RFID_STATE_IDLE,         // 保持空闲
        .callback = on_idle_ignore             // 忽略噪声
    },
    {
        .current_state = RFID_STATE_IDLE,
        .event = RFID_EVT_TIMEOUT,             // 超时
        .next_state = RFID_STATE_IDLE,         // 保持空闲
        .callback = NULL                       // 无操作
    },
    
    /*******************************************************************
     * 状态2:等待第一个边沿 (RFID_STATE_WAIT_FIRST_EDGE)
     * 描述:已检测到帧间隔,等待第一个边沿(新帧开始)
     * 目标:接收第一个边沿,开始解码过程
     *******************************************************************/
    {
        .current_state = RFID_STATE_WAIT_FIRST_EDGE,
        .event = RFID_EVT_FULL_RISING,         // 第一个上升沿(完整位时间)
        .next_state = RFID_STATE_CHECK_FIRST_BIT, // 转换到检查第一个位
        .callback = on_wait_first_edge         // 第一个边沿处理
    },
    {
        .current_state = RFID_STATE_WAIT_FIRST_EDGE,
        .event = RFID_EVT_FULL_FALLING,        // 第一个下降沿(完整位时间)
        .next_state = RFID_STATE_CHECK_FIRST_BIT, // 转换到检查第一个位
        .callback = on_wait_first_edge         // 第一个边沿处理
    },
    {
        .current_state = RFID_STATE_WAIT_FIRST_EDGE,
        .event = RFID_EVT_HALF_RISING,         // 半位上升沿(不应出现)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_unexpected_half_edge    // 意外半位处理
    },
    {
        .current_state = RFID_STATE_WAIT_FIRST_EDGE,
        .event = RFID_EVT_HALF_FALLING,        // 半位下降沿(不应出现)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_unexpected_half_edge    // 意外半位处理
    },
    {
        .current_state = RFID_STATE_WAIT_FIRST_EDGE,
        .event = RFID_EVT_TIMEOUT,             // 等待超时
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_wait_timeout            // 超时处理
    },
    
    /*******************************************************************
     * 状态3:检查第一个位 (RFID_STATE_CHECK_FIRST_BIT)
     * 描述:已收到第一个边沿,需要验证是否为有效"1"
     * 目标:验证第二个边沿是否为半位时间,确认第一个"1"
     *******************************************************************/
    {
        .current_state = RFID_STATE_CHECK_FIRST_BIT,
        .event = RFID_EVT_HALF_RISING,         // 半位上升沿(有效!)
        .next_state = RFID_STATE_SYNC_HEADER,  // 转换到同步头状态
        .callback = on_first_bit_valid         // 第一个位有效处理
    },
    {
        .current_state = RFID_STATE_CHECK_FIRST_BIT,
        .event = RFID_EVT_HALF_FALLING,        // 半位下降沿(有效!)
        .next_state = RFID_STATE_SYNC_HEADER,  // 转换到同步头状态
        .callback = on_first_bit_valid         // 第一个位有效处理
    },
    {
        .current_state = RFID_STATE_CHECK_FIRST_BIT,
        .event = RFID_EVT_FULL_RISING,         // 完整位上升沿(无效!)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_invalid_first_bit       // 第一个位无效处理
    },
    {
        .current_state = RFID_STATE_CHECK_FIRST_BIT,
        .event = RFID_EVT_FULL_FALLING,        // 完整位下降沿(无效!)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_invalid_first_bit       // 第一个位无效处理
    },
    {
        .current_state = RFID_STATE_CHECK_FIRST_BIT,
        .event = RFID_EVT_TIMEOUT,             // 检查超时
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_check_timeout           // 超时处理
    },
    
    /*******************************************************************
     * 状态4:同步头状态 (RFID_STATE_SYNC_HEADER)
     * 描述:验证同步头(9个连续"1")
     * 目标:接收18个连续半位边沿,确认同步头
     *******************************************************************/
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_HALF_RISING,         // 半位上升沿(同步头位)
        .next_state = RFID_STATE_SYNC_HEADER,  // 保持同步头状态
        .callback = on_sync_bit_received       // 同步位接收处理
    },
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_HALF_FALLING,        // 半位下降沿(同步头位)
        .next_state = RFID_STATE_SYNC_HEADER,  // 保持同步头状态
        .callback = on_sync_bit_received       // 同步位接收处理
    },
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_FULL_RISING,         // 完整位上升沿(同步中断!)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_sync_break              // 同步中断处理
    },
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_FULL_FALLING,        // 完整位下降沿(同步中断!)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_sync_break              // 同步中断处理
    },
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_TIMEOUT,             // 同步超时
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_sync_timeout            // 同步超时处理
    },
    {
        .current_state = RFID_STATE_SYNC_HEADER,
        .event = RFID_EVT_SYNC_COMPLETE,       // 同步头完成(内部事件)
        .next_state = RFID_STATE_DATA_RECEIVE, // 转换到数据接收状态
        .callback = on_sync_complete           // 同步完成处理
    },
    
    /*******************************************************************
     * 状态5:数据接收状态 (RFID_STATE_DATA_RECEIVE)
     * 描述:接收64位数据(包括同步头)
     * 目标:解码曼彻斯特编码,提取数据位
     *******************************************************************/
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_FULL_RISING,         // 完整位上升沿(表示位"0")
        .next_state = RFID_STATE_DATA_RECEIVE, // 保持数据接收状态
        .callback = on_data_bit_zero           // 数据位0处理
    },
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_FULL_FALLING,        // 完整位下降沿(表示位"1")
        .next_state = RFID_STATE_DATA_RECEIVE, // 保持数据接收状态
        .callback = on_data_bit_one            // 数据位1处理
    },
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_HALF_RISING,         // 半位上升沿(连续相同位)
        .next_state = RFID_STATE_DATA_RECEIVE, // 保持数据接收状态
        .callback = on_half_bit_skip           // 半位跳过处理
    },
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_HALF_FALLING,        // 半位下降沿(连续相同位)
        .next_state = RFID_STATE_DATA_RECEIVE, // 保持数据接收状态
        .callback = on_half_bit_skip           // 半位跳过处理
    },
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_TIMEOUT,             // 数据接收超时
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_data_timeout            // 数据超时处理
    },
    {
        .current_state = RFID_STATE_DATA_RECEIVE,
        .event = RFID_EVT_DATA_COMPLETE,       // 数据接收完成(内部事件)
        .next_state = RFID_STATE_CHECK_STOP_BIT, // 转换到检查停止位
        .callback = on_data_complete           // 数据完成处理
    },
    
    /*******************************************************************
     * 状态6:检查停止位 (RFID_STATE_CHECK_STOP_BIT)
     * 描述:验证第64位是否为停止位0
     * 目标:确认帧有效性,准备帧完成处理
     *******************************************************************/
    {
        .current_state = RFID_STATE_CHECK_STOP_BIT,
        .event = RFID_EVT_FULL_RISING,         // 停止位上升沿(应为0)
        .next_state = RFID_STATE_FRAME_COMPLETE, // 转换到帧完成状态
        .callback = on_stop_bit_valid          // 停止位有效处理
    },
    {
        .current_state = RFID_STATE_CHECK_STOP_BIT,
        .event = RFID_EVT_FULL_FALLING,        // 停止位下降沿(应为1,错误!)
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_stop_bit_invalid        // 停止位无效处理
    },
    {
        .current_state = RFID_STATE_CHECK_STOP_BIT,
        .event = RFID_EVT_TIMEOUT,             // 检查超时
        .next_state = RFID_STATE_ERROR,        // 转换到错误状态
        .callback = on_check_timeout           // 超时处理
    },
    
    /*******************************************************************
     * 状态7:帧完成状态 (RFID_STATE_FRAME_COMPLETE)
     * 描述:成功接收完整帧
     * 目标:处理帧数据,等待帧间隔
     *******************************************************************/
    {
        .current_state = RFID_STATE_FRAME_COMPLETE,
        .event = RFID_EVT_FRAME_GAP,           // 检测到帧间隔
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_frame_processed         // 帧处理完成
    },
    {
        .current_state = RFID_STATE_FRAME_COMPLETE,
        .event = RFID_EVT_TIMEOUT,             // 处理超时
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_frame_timeout           // 帧处理超时
    },
    
    /*******************************************************************
     * 状态8:错误状态 (RFID_STATE_ERROR)
     * 描述:解码过程中发生错误
     * 目标:错误恢复,返回空闲状态
     *******************************************************************/
    {
        .current_state = RFID_STATE_ERROR,
        .event = RFID_EVT_FRAME_GAP,           // 检测到帧间隔
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_error_recovered         // 错误恢复
    },
    {
        .current_state = RFID_STATE_ERROR,
        .event = RFID_EVT_TIMEOUT,             // 错误状态超时
        .next_state = RFID_STATE_IDLE,         // 返回空闲状态
        .callback = on_error_timeout           // 错误超时
    },
    
    /* 结束标记 */
    {RFID_STATE_COUNT, RFID_EVT_NONE, RFID_STATE_IDLE, NULL}
};

回调函数

/* 关键回调函数实现 -----------------------------------------------*/

/* 同步位接收回调 */
void on_sync_bit_received(rfid_decoder_t *decoder, rfid_event_data_t *event)
{
    // 增加边沿计数
    decoder->edge_counter++;
    
    // 每两个边沿构成一个位"1"
    if (decoder->edge_counter % 2 == 0) {
        decoder->bit_counter++;
        
        // 验证时间间隔(应为256μs ± 误差)
        if (event->interval_us < HALF_BIT_MIN || event->interval_us > HALF_BIT_MAX) {
            // 时间间隔异常,触发错误
            decoder->current_state = RFID_STATE_ERROR;
            return;
        }
        
        printf("[SYNC] Bit %d received, edges: %d\n", 
               decoder->bit_counter, decoder->edge_counter);
    }
}

/* 数据位0解码回调(完整位上升沿) */
void on_data_bit_zero(rfid_decoder_t *decoder, rfid_event_data_t *event)
{
    // 验证时间间隔(应为512μs ± 误差)
    if (event->interval_us < FULL_BIT_MIN || event->interval_us > FULL_BIT_MAX) {
        decoder->current_state = RFID_STATE_ERROR;
        return;
    }
    
    // 解码位"0"
    uint8_t bit_value = 0;
    store_bit(decoder, bit_value);
    
    decoder->bit_counter++;
    printf("[DATA] Bit %d = 0\n", decoder->bit_counter);
}

/* 数据位1解码回调(完整位下降沿) */
void on_data_bit_one(rfid_decoder_t *decoder, rfid_event_data_t *event)
{
    // 验证时间间隔
    if (event->interval_us < FULL_BIT_MIN || event->interval_us > FULL_BIT_MAX) {
        decoder->current_state = RFID_STATE_ERROR;
        return;
    }
    
    // 解码位"1"
    uint8_t bit_value = 1;
    store_bit(decoder, bit_value);
    
    decoder->bit_counter++;
    printf("[DATA] Bit %d = 1\n", decoder->bit_counter);
}

/* 半位跳过回调 */
void on_half_bit_skip(rfid_decoder_t *decoder, rfid_event_data_t *event)
{
    // 半位时间:连续相同位的中间跳变
    // 不存储新位,只更新边沿计数
    decoder->edge_counter++;
    
    // 验证时间间隔(应为256μs ± 误差)
    if (event->interval_us < HALF_BIT_MIN || event->interval_us > HALF_BIT_MAX) {
        decoder->current_state = RFID_STATE_ERROR;
        return;
    }
    
    printf("[HALF] Half-bit skipped, edges: %d\n", decoder->edge_counter);
}

 

posted @ 2025-12-11 21:56  小小卡拉  阅读(2)  评论(0)    收藏  举报