news 2026/5/12 21:01:01

别再只读卡号了!用STM32+RC522深入玩转M1卡:读写数据块、值块操作实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再只读卡号了!用STM32+RC522深入玩转M1卡:读写数据块、值块操作实战

深入探索STM32与RC522的M1卡高级操作:从数据块读写到值块应用实战

当你已经成功用STM32和RC522读取了M1卡的UID,是否想过这些卡片还能做什么?实际上,M1卡(S50)的功能远不止于简单的身份识别。本文将带你深入探索M1卡的内存结构、访问控制机制,以及如何实现数据块和值块的高级操作。

1. M1卡内存结构与访问控制基础

M1卡(S50)采用13.56MHz射频通信,内存容量为1KB,分为16个扇区(Sector),每个扇区包含4个数据块(Block),每个块16字节。其中:

  • 块0(Block 0)通常存储厂商信息,包含卡的UID和厂商数据,不可改写
  • 每个扇区的块3是该扇区的控制块,存储两个密钥(Key A和Key B)以及访问控制位(Access Bits)

访问控制位决定了每个数据块的读写权限。理解这些权限设置对于安全操作至关重要:

访问控制位组合密钥A权限密钥B权限数据块操作权限
000不可读不可读只读
001可读不可读可写
010不可读可读可写
011可读可读可写
100不可读不可读值块操作

注意:错误配置访问控制位可能导致扇区被永久锁定,操作前务必确认当前权限设置

2. RC522与STM32的深度集成

要实现M1卡的高级功能,首先需要确保RC522模块与STM32的正确连接和初始化。不同于简单的UID读取,深度操作需要更完整的SPI通信实现:

// RC522初始化示例代码 void RC522_Init(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 启用SPI和GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE); // 配置SPI引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7; // SCK, MOSI GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // MISO GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置片选和复位引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // SDA(CS) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // RST GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); // SPI配置 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); // 复位RC522 RC522_Reset(); // 初始化RC522寄存器 RC522_InitRegisters(); }

关键操作流程如下:

  1. 寻卡:检测卡片进入射频场
  2. 防冲突:获取卡片UID
  3. 选择卡片:准备进行后续操作
  4. 认证:使用密钥A或B验证扇区权限
  5. 操作数据:读写数据块或值块

3. 数据块读写实战

数据块是M1卡存储用户数据的基本单元。每个扇区的前3个块(Block 0-2)通常是数据块,而块3是控制块。以下是读写数据块的关键步骤:

3.1 读取数据块

uint8_t ReadBlock(uint8_t sector, uint8_t block, uint8_t *data) { uint8_t status; uint8_t blockAddr = sector * 4 + block; // 计算绝对块地址 // 1. 寻卡 status = RC522_Request(PICC_REQIDL, NULL); if(status != MI_OK) return status; // 2. 防冲突获取UID status = RC522_Anticoll(NULL); if(status != MI_OK) return status; // 3. 选择卡片 status = RC522_SelectTag(NULL); if(status != MI_OK) return status; // 4. 认证 status = RC522_Auth(PICC_AUTHENT1A, blockAddr, DefaultKey, NULL); if(status != MI_OK) return status; // 5. 读取数据 status = RC522_Read(blockAddr, data); // 6. 停止认证 RC522_Halt(); return status; }

3.2 写入数据块

写入数据块前,必须确保该块的访问权限允许写入操作。典型写入流程:

  1. 认证目标扇区
  2. 准备要写入的数据(16字节)
  3. 调用写块命令
  4. 验证写入结果
uint8_t WriteBlock(uint8_t sector, uint8_t block, uint8_t *data) { uint8_t status; uint8_t blockAddr = sector * 4 + block; // 认证流程同上... // 写入数据 status = RC522_Write(blockAddr, data); // 可选:读取验证 uint8_t readBack[16]; RC522_Read(blockAddr, readBack); if(memcmp(data, readBack, 16) != 0) { return ERR_WRITE_VERIFY; } RC522_Halt(); return status; }

提示:写入前建议先读取块内容,确认当前访问权限和已有数据,避免意外覆盖重要信息

4. 值块操作与电子钱包应用

值块(Value Block)是M1卡的特殊数据块,支持原子增减操作,非常适合电子钱包、积分系统等应用。值块有固定的数据结构:

  • (4字节):存储的数值,小端格式
  • 地址(4字节):备份值存储地址
  • 校验(4字节):值和地址的校验

4.1 创建值块

要将普通数据块初始化为值块,需要写入特定格式的数据:

uint8_t CreateValueBlock(uint8_t sector, uint8_t block, int32_t initialValue) { uint8_t data[16] = {0}; uint8_t blockAddr = sector * 4 + block; // 构造值块数据结构 data[0] = initialValue & 0xFF; data[1] = (initialValue >> 8) & 0xFF; data[2] = (initialValue >> 16) & 0xFF; data[3] = (initialValue >> 24) & 0xFF; // 地址通常设为相同值 memcpy(&data[4], &data[0], 4); // 计算校验 for(int i=0; i<4; i++) { data[8+i] = data[i] ^ data[4+i]; } return WriteBlock(sector, block, data); }

4.2 值块增减操作

值块支持三种原子操作:

  1. 增值(Increment):增加指定数值
  2. 减值(Decrement):减少指定数值
  3. 恢复(Restore):从备份地址恢复值
uint8_t ValueBlockOperation(uint8_t sector, uint8_t block, uint8_t cmd, int32_t value) { uint8_t status; uint8_t blockAddr = sector * 4 + block; // 认证流程同上... // 准备命令结构 uint8_t sendData[4]; sendData[0] = cmd; // 操作命令 sendData[1] = value & 0xFF; sendData[2] = (value >> 8) & 0xFF; sendData[3] = (value >> 16) & 0xFF; // 发送操作命令 status = RC522_ValueOperation(cmd, blockAddr, sendData); RC522_Halt(); return status; }

典型应用场景示例:

  • 公交卡扣费:使用减值操作扣除车费
  • 积分充值:使用增值操作增加积分
  • 余额恢复:当主值损坏时从备份恢复

5. 安全实践与常见问题

深入操作M1卡时,安全性至关重要。以下是一些关键安全实践:

5.1 密钥管理最佳实践

  • 不要使用默认密钥:出厂默认密钥(如FF FF FF FF FF FF)极不安全
  • 分层密钥策略
    • 不同扇区使用不同密钥
    • 根据敏感程度分配密钥复杂度
  • 密钥轮换:定期更换关键扇区的密钥

5.2 访问控制位配置

配置访问控制位时,务必遵循最小权限原则:

  1. 确定每个数据块的实际需求(读、写、值操作)
  2. 选择能满足需求的最严格权限组合
  3. 测试配置后再应用到生产环境

常见错误配置及后果:

  • 过度开放权限:允许未授权修改
  • 过度限制权限:导致合法操作失败
  • 错误配置控制块:可能永久锁定扇区

5.3 错误处理与恢复

健壮的系统应该包含完善的错误处理机制:

typedef enum { RC522_OK = 0, RC522_NO_TAG, RC522_AUTH_FAIL, RC522_READ_FAIL, RC522_WRITE_FAIL, RC522_VALUE_INVALID, RC522_ACCESS_DENIED } RC522_Status; const char *RC522_GetErrorString(RC522_Status status) { static const char *strings[] = { "操作成功", "未检测到卡片", "认证失败", "读取失败", "写入失败", "值块操作无效", "访问权限不足" }; if(status >= sizeof(strings)/sizeof(strings[0])) { return "未知错误"; } return strings[status]; }

实际项目中,我发现最常遇到的问题集中在认证失败和权限不足上。通过详细的错误日志和用户反馈,可以快速定位并解决这些问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 20:58:45

5分钟掌握TEdit地图编辑器:终极泰拉瑞亚世界创作工具

5分钟掌握TEdit地图编辑器&#xff1a;终极泰拉瑞亚世界创作工具 【免费下载链接】Terraria-Map-Editor TEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also lets you cha…

作者头像 李华
网站建设 2026/5/12 20:56:11

西电b测场景下如何快速接入多模型api服务

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 西电B测场景下如何快速接入多模型API服务 应用场景类&#xff0c;针对高校科研或项目测试场景&#xff0c;开发者需要在西电B测等内…

作者头像 李华
网站建设 2026/5/12 20:52:12

从SPI模式0到Quad I/O:手把手带你玩转W25Q128JV的性能压榨与接口升级

从SPI模式0到Quad I/O&#xff1a;W25Q128JV性能优化实战指南 在嵌入式系统设计中&#xff0c;存储器的性能往往成为整个系统响应速度的瓶颈。W25Q128JV这颗128Mbit容量的串行Flash芯片&#xff0c;凭借其灵活的接口配置和出色的性价比&#xff0c;已成为众多物联网设备、消费电…

作者头像 李华
网站建设 2026/5/12 20:50:40

私域电商直播怎么做?500+品牌都在用的增长秘籍

一、私域电商直播&#xff1a;品牌增长的第三曲线当公域流量成本逐年攀升&#xff0c;越来越多企业意识到&#xff1a;私域流量才是未来竞争的核心战场。私域电商直播 vs 公域直播的本质区别&#xff1a;对比维度公域直播&#xff08;抖音/淘宝&#xff09;私域电商直播流量来源…

作者头像 李华
网站建设 2026/5/12 20:49:23

Docker容器化部署OpenClaw AI智能体:安全隔离与一键启动实践

1. 项目概述&#xff1a;为什么选择容器化部署OpenClaw&#xff1f;如果你正在探索AI智能体&#xff08;Agent&#xff09;领域&#xff0c;尤其是像OpenClaw这样功能强大的开源项目&#xff0c;那么部署和管理环节的复杂性很可能已经让你头疼不已。OpenClaw本身是一个集成了多…

作者头像 李华
网站建设 2026/5/12 20:42:41

微信AI机器人插件生态全解析:从入门到开发实战指南

1. 项目概述&#xff1a;一个为微信AI机器人量身打造的插件生态宝库如果你正在使用或关注基于微信的AI对话机器人项目&#xff0c;比如CoW (ChatGPT-on-Wechat)或DoW (Dify-on-Wechat)&#xff0c;那么你很可能已经体会过它们强大的基础对话能力。但你是否想过&#xff0c;让这…

作者头像 李华