125K RFID解码
ID卡(如EM4100)输出的数据已经是曼彻斯特编码了。需要对捕获的信号进行曼彻斯特解码(不是编码),才能得到正确的数据位。
曼彻斯特编码的方式一般有两种:

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

协议规定:1 bit 占用 64 个载波周期,载波频率:fc=125 kHz
所以:数据位速率就是:



所以:全位脉宽为512us,半位脉宽为256us。
当 64 位的最后一位发完之后,芯片会立刻从第一位重新开始发送,一直循环,直到磁场消失(掉电)。

我们使用状态机的方法进行数据解析:
首先讲一下我们需要用到的几个状态,我们这几个状态都写到
状态枚举定义
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);
}
浙公网安备 33010602011771号