【物联网无线通信技术】NFC从理论到实践(FM17XX)
NFC,全称是Near Field Communication,即“近场通信”,也叫“近距离无线通信”。NFC诞生于2004年,是基于RFID非接触式射频识别技术演变而来,由当时的龙头企业NXP(原飞利浦半导体)、诺基亚以及索尼联合发起。NFC采用13.56MHz频段,设计运行于20厘米距离之间,传输速度分为13.25KB/s、26.5KB/s、53KB/s三种。
NFC虽然具有只需要靠近就能快速完成配对和传输全过程的优势,但是所谓成也萧何败也萧何,其短距离才能建立连接,以及低带宽的特点在面对手机与其他电子设备无线连接需求时劣势尽显,再加上跟蓝牙相比,其需要单独的天线(蓝牙可以wifi公用),所以其在刚诞生之际鲜有移动设备搭载此项功能,倒是在门禁等安防系统中有所应用。后来随着移动支付的需求增加,NFC功能又迎来了新的机遇。
本篇文章从NFC的技术诞生背景将起,从最常见的应用入手,由上到下讲述了整个NFC技术从理论到实现的过程,NFC读卡器使用的是复旦微电子的FM17XX系列芯片,NFC卡片为M1。
目录
NFC技术概述
防止冲突机制
卡片认证
实现原理
嵌入式软件
卡片触发
INITVAL VALUE
读卡
写卡
NFC技术概述
在讲NFC之前,先讲讲它的前辈:RFID,其英文全称是radio-frequency identification,即射频识别技术。RFID系统使用标签(Tag)来识别物体。除了标签,RFID系统还有一个双向无线收发机,被称为读写器(Interrogator/Reader),向标签发送信号,并读取标签的反馈。RFID属于自动识别(AIDC:Automatic Identification and Data Capture)技术中的一种。这个识别过程如下:
- 首先,跟物品绑定的数据会预先通过读写器存储在RFID标签中。
- 当标签进入读写器扫描天线的范围内时,无源RFID标签的天线将接收到的电磁波能量转化成电能,激活RFID标签中的芯片,并将RFID芯片中的数据发送出来。
- 无线电波被读写器的天线接收,读写器将这些无线电波解码为数字信息。

NFC作为RFID技术的后辈,在设计之初旨在智能设备的近场双向通信,但是其诞生之后,应用最为广泛还是门禁的功能。

ISO14443协议是Contactless card standards(非接触式IC卡标准)协议,它定义了以下两个主体:
- PICC:接近式卡 Proximity Card(PICC) (卡片)。
- PCD : 接近式耦合设备 Proximity coupling device (PCD)(读卡器)
根据信号发送和接收方式的不同,ISO/IEC14443-3定义了TYPEA、TYPEB两种卡型。 以飞利浦,西门子公司为代表的TYPEA。 以摩托罗拉,意法半导体公司为代表的TYPEB。今天我们讲到的为M1卡,指的是菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号,属于TYPEA类型。
读卡机我们文章涉及到的FM17XX系列芯片,可分别支持13.56MHz频率下的typeA、 typeB、15693三种非接触通信协议,支持MIFARE和SH标准的加密算法。
标准不仅定义了射频卡和读写器的物理特性,例如频率和天线设计,还描述了射频卡与读写器之间的初始化和防冲突机制以及数据传输协议和指令集。下图是文章涉及的读卡机与卡片的通信流程。

防止冲突机制
读卡器正常情况下一个时间点只能对磁场中的一张卡进行读或写操作,但是实际应用中经常有当多张卡片同时进入读写器的射频场,读写器怎么处理呢?读写器需要选出特定的一张卡片进行读或写操作,这就是标签防碰撞。常见的防冲突机制主要有以下几种:
- 面向比特的防冲突机制,ISO14443A(TYPEA)使用这种防冲突机制,其原理是基于卡片有一个全球唯一的序列号。比如Mifare1卡,每张卡片有一个全球唯一的32位二进制序列号。
- 面向时隙的防冲突机制,ISO14443B(TYPEB)中使用这种防冲突机制。
- 位和时隙相结合的防冲突机制,ISO15693中使用这种机制。一方面每张卡片有一个7字节的全球唯一序列号,另一方面读写器在防冲突的过程中也使用时隙叫号的方式,不过这里的号不是卡片随机选择的,而是卡片唯一序列号的一部分。
卡片认证
三重加密算法被用于执行标准认证。在密钥缓冲器中必须存储准确的密钥以便能够进行成功的认证操作。
- 通过LoadKeyE2或者LoadKey加载密钥到内部密钥缓冲器。
- 启动Authent1指令结束之后,检查错误标志来判断执行结果。
- 启动Authent2指令,结束之后,检查错误标志以及Crypto1On标志来判断执行结果。
实现原理
使用任意型号的MCU(一般需要具有低功耗模式)作为微处理器(下图中的uProcessor),MCU与FM17XX系列芯片采用SPI接口进行通信,天线直接连接FM17XX,具体如下图。

嵌入式软件
嵌入式软件从下到上主要分为以下三层:
- 常用/基本函数,包括卡片UID种类判断,FM17XX初始化,命令传输,向EEPROM以及FIFO读写数据等。
- FM17XX卡片操作基本函数,包括HALT,LOADKEY,REQUEST,ANTICOLLISION,SELECT,AUTHENTICATION,READ,WRITE,INCREMENT,DECREMENT,RESTORE,TRANSFER。
- 应用功能函数。
下面主要将应用功能的部分函数贴上来供各位深入理解读卡器对卡片的操作功能。
卡片触发
/*************************************
/*名称: HL Active
/*功能: 该函数实现高级 MIFARE 卡激活命今
/*输入: Secnr: 扇区号
/* Block Adr: 块地址
/*输出:操作状态码
/* 读出数据存于 buffer 中
*************************************/
uchar HL_Active(uchar Block_Adr,uchar Mode)
{uchar temp;Secnr = Block_Adr/4;MIF_Halt(); //Halttemp = Request(RF_CMD_REQUEST+STD);//Requestif(temp != FM1715_OK){return(FM1715_REQERR);}temp = AntiColl(); //AntiColif(temp != FM1715_OK){return(FM1715_ANTICOLLERR);}temp = Select_Card(); ///Selectif(temp != FM1715_OK){return(FM1715_SELERR);}Load_keyE2_CPY((Secnr%16),Wode);//LoadKeytemp = Authentication(UID, Secnr, Mode);//Authenticationif(temp != FM1715_OK){return(FM1715 AUTHERR)}return FM1715_OK;
}
INITVAL VALUE
/**************************************
/*名称:MIF_Initival
/*功能: 该函数实现 MIFARE 卡初始化值操作
/*输入: buff: 四个字节初始化数值起始地加
/* Block Adr: 块地址
/*输出: FM1715 NOTAGERR:无卡
/* FM1715 BYTECOUNTERR: 接收字节错误
/* FM1715 NOTAUTHERR: 未经权威认证
/* FM1715 EMPTY:数据溢出错误
/* FM1715 CRCERR: CRC 校验错
/* FM1715 PARITYERR: 奇偶校验错
/* FM1715 WRITEERR: 写卡块数据出错
/* FM1715 0K: 应答正确
/**************************************
uchar MIF_Initival(uchar idata *buff,uchar Block_Adr)
{uchar idata temp;uchar i;for (i = 0; i < 4: i++){*(buff + 4 + i)=~(*(buff + i));} for (i = 0;i < 4: i++){*(buff + 8 + i)=*(buff + i);}*(buff + 12) = Block Adr;*(buff + 13) =Block Adr;*(buff + 14) = Block Adr;*(buff + 15) =Block Adr;temp = MIF_Write(buff, Block_Adr);return temp;
}
读卡
/***************************
/*名称: HL Read
/*功能:该函数实现高级读命令
/*输入:Secnr: 扇区号
/* Block Adr: 块地址
/*输出:操作状态码
/*读出数据存于 buffer 中
/***************************
uchar HL_Read(uchar idata *buff,uchar Block_Adr,uchar Mode)
{uchar temp;temp = HL Active(Block_Adr, Mode);if(temp != FM1715_OK){return temp;}//Readtemp = MIF_READ (buff,Block_Adr);if(temp != FM1715_OK){return temp;}return FM1715_OK
}
写卡
/*******************************
/*名称: HL Write
/*功能:该函数实现高级写命令
/*输入: buff: 待写入数据的首地址
/* Secnr: 刷区号
/* Block Adr: 块地址
/*输出:操作状态码
/*******************************
uchar HL_Write(uchar idata *buff,uchar Block_Adr,uchar Mode)
{uchar temp;temp = HL_Active(Block_Adr, Mode);if(temp != FM1715_OK){return temp;}//Writetemp = MIF_Write(buff, Block_Adr);if(temp != FM1715_OK){return FM1715_WRITEERR;}return FM1715_OK;
}
十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。
相关文章:
【物联网无线通信技术】NFC从理论到实践(FM17XX)
NFC,全称是Near Field Communication,即“近场通信”,也叫“近距离无线通信”。NFC诞生于2004年,是基于RFID非接触式射频识别技术演变而来,由当时的龙头企业NXP(原飞利浦半导体)、诺基亚以及索尼联合发起。NFC采用13.5…...
Python爬虫猿人学逆向系列——第六题
题目:采集全部5页的彩票数据,计算全部中奖的总金额(包含一、二、三等奖) 地址:https://match.yuanrenxue.cn/match/6 本题比较简单,只是容易踩坑。话不多说请看分析。 两个参数,一个m一个f&…...
idea使用tomcat
1. 建立javaweb项目 2. /WEB-INF/web.xml项目配置文件 如果javaweb项目 先建立项目,然后在项目上添加框架支持,选择javaee 3. 项目结构 4.执行测试:...
搭建Tomcat HTTP服务:在Windows上实现外网远程访问的详细配置与设置教程
文章目录 前言1.本地Tomcat网页搭建1.1 Tomcat安装1.2 配置环境变量1.3 环境配置1.4 Tomcat运行测试1.5 Cpolar安装和注册 2.本地网页发布2.1.Cpolar云端设置2.2 Cpolar本地设置 3.公网访问测试4.结语 前言 Tomcat作为一个轻量级的服务器,不仅名字很有趣࿰…...
Java学习笔记——继承(包括this,super的使用总结)
继承: 使用情景:当类与类之间,存在相同(共性)的内容,并满足子类是父类的一种,就可以考虑使用继承,来优化代码 Java中提供一个关键字extends,用这个关键字,我…...
Android 获取应用sha1和sha256
在 Android 应用开发中,SHA-1(Secure Hash Algorithm 1)值是一种哈希算法,常用于生成应用的数字签名。这个数字签名用于验证应用的身份,并确保应用在发布到设备上时没有被篡改。 以下是生成 Android 应用的 SHA-1 值的…...
c# 方法参数修饰符(out、ref、in)的区别
在C#中,ref、out和in是三种方法参数修饰符,它们在传递参数的方式和作用上有所不同。 ref修饰符: 传递方式:使用ref修饰符的参数可以是输入输出参数,即在方法调用前后都可以对其进行修改。 作用:通过ref修…...
shell 编写一个带有进度条的程序安装脚本
需求 使用 shell 写一个 软件安装脚本,带有进度条 示例 #!/bin/bash# 模拟软件安装的步骤列表 steps("解压文件" "安装依赖" "配置设置" "复制文件" "")# 计算总步骤数 total_steps${#steps[]}# 安装进度的初…...
服务器数据恢复-AIX PV完整镜像方法以及误删LV的数据恢复方案
AIX中的PV相当于物理磁盘(针对于存储来说,PV相当于存储映射过来的卷;针对操作系统来说,PV相当于物理硬盘),若干个PV组成一个VG,AIX可以将容量不同的存储空间组合起来统一分配。AIX把同一个VG的所…...
首席执行官Adam Selipsky解读“亚马逊云科技的技术产品差异化”
迄今为止,亚马逊云科技已经参与了21世纪几乎所有的大型计算变革,亚马逊云科技是一个很传奇的故事,它始于大约20年前的一项实验,当时亚马逊试图出售其过剩的服务器。人们确实对此表示怀疑。为什么在线书店试图销售云服务࿱…...
C++ Day3
目录 一、类 【1】类 【2】应用实例 练习: 【3】封装 二、this指针 【1】this指针的格式 【2】必须使用this指针的场合 三、类中的特殊成员函数 【1】构造函数 i)功能 ii)格式 iii)构造函数的调用时机 iv)…...
OpenEuler 安装mysql
下载安装包 建议直接使用在openEuler官方编译移植过的mysql-5.7.21系列软件包 参考:操作系统迁移实战之在openEuler上部署MySQL数据库 | 数据库迁移方案 | openEuler社区官网 MySQL 5.7.21 移植指南(openEuler 20.03 LTS SP1) | 数据库移植…...
[Docker] Windows 下基于WSL2 安装
Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。 1. 开启虚拟化 进入系统BIOS(AMD 为 SVM;Intel 为 Intel-vt)改为启用(enable) 2. 开启WSL 系统设置->应用->程序和功能->…...
(未完成)【Spring专题】SringAOP底层原理解析——阶段三(AOP)
目录 前言前置知识代理范式SpringAOP的理解Spring动态代理的实现 课程内容一、动态代理的实现1.1 Cglib动态代理1.2 JDK动态代理1.3 ProxyFactory:Spring对两种代理的封装 二、AOP基础知识AOP基础概念回顾通知Advice的分类Advisor的理解 三、创建代理对象的方式3.1 …...
使用Nodejs创建简单的HTTP服务器,借助内网穿透工具实现公网访问的方法分享
文章目录 前言1.安装Node.js环境2.创建node.js服务3. 访问node.js 服务4.内网穿透4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5.固定公网地址 前言 Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation࿰…...
使用 OpenTelemetry 构建可观测性 03 - 导出
上一个博文中,我提到如何使用 OpenTelemery 的特定语言 API 来收集遥测数据,包含手动和自动的埋点技术,这很重要!但是,收集遥测数据只是解决方案的第一步。 你需要把遥测数据路由转发到其他地方,同时添加额…...
Pyqt5打开电脑摄像头进行拍照
目录 1、设计UI界面 2、设计逻辑代码,建立连接显示窗口 3、结果 1、设计UI界面 将ui界面转为py文件后获得的逻辑代码为:(文件名为 Camera.py) # -*- coding: utf-8 -*-# Form implementation generated from reading ui file …...
Flowable 7.0.0.M2 版本功能
CMMN 支持批量迁移重复支持案例重新激活支持停止内务处理批处理Http 任务支持 HTTP HEAD and OPTIONS for the Http Tasks移除了 Spring Boot 启动器 flowable-spring-boot-starter-basic - 切换为 flowable-spring-boot-starter-process flowable-spring-boot-starter-rest-ap…...
【golang】关于指针的有限操作
传统意义上来说,指针是一个指向某个确切的内存地址的值。这个内存地址可以是任何数据或代码的起始地址。在Go语言中有几种东西可以代表"指针"。其中最贴切传统意义的当属uintptr类型的了。该类型实际上是一个数值类型,也是Go语言内建的数据类型…...
ProGuard + SpringBoot3 + JDK17
1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.…...
嵌入式系统中void指针与函数指针的高级应用
void指针与函数指针在嵌入式系统中的高级应用1. void指针的工程应用1.1 void指针的本质特性void指针(void*)在C语言中表示一个"不知道类型"的指针变量,其核心特性在于:int nums[] {3, 5, 6, 7, 9}; void* ptr1 nums; int* ptr2 (int*)nums;…...
Transformer横空出世!解决NLP难题,引爆AI革命!
Transformer模型自2017年推出以来,已成为人工智能领域最具影响力的创新之一。本文深入探讨了Transformer的基本原理、出现背景及其精巧的架构设计。Transformer通过自注意力机制,成功克服了RNN在处理长序列数据时的长距离依赖和并行计算瓶颈,…...
【限时解密】某汽车Tier1工厂拒绝公开的Python网关冗余切换配置——双网口+心跳检测+自动故障转移(含Wireshark抓包验证截图)
第一章:工业Python网关冗余架构设计背景与合规边界在现代工业自动化系统中,Python因其丰富的生态、快速迭代能力及对OPC UA、Modbus、MQTT等协议的成熟支持,正被广泛用于边缘网关开发。然而,将通用编程语言应用于高可用性…...
Ensp与SecureCRT高效连接指南及常见回车空行问题排查
1. Ensp与SecureCRT连接全流程详解 第一次用Ensp连接SecureCRT时,我也被那一堆串口参数搞得头晕。后来才发现,只要掌握几个关键步骤,整个过程其实非常简单。下面我就把踩坑后总结的最稳定连接方案分享给大家。 1.1 软件安装与环境准备 在开始…...
Qwen3-ASR-1.7B服务管理技巧:使用Supervisor监控与重启服务
Qwen3-ASR-1.7B服务管理技巧:使用Supervisor监控与重启服务 当你把Qwen3-ASR-1.7B语音识别模型部署到服务器上,准备让它7x24小时稳定工作时,有没有遇到过这样的问题: 半夜服务突然挂了,第二天早上才发现,…...
Spring WebFlux + Reactivate-Feign实战:如何用响应式编程提升微服务性能
Spring WebFlux Reactivate-Feign实战:构建高性能响应式微服务架构 在当今高并发、低延迟的应用场景中,传统同步阻塞式的微服务调用方式逐渐暴露出性能瓶颈。当系统面临突发流量时,线程资源迅速耗尽,响应时间急剧上升,…...
Linux g++编译与GDB调试完整流程(文末附图)
验证安装 C which g g --versionC which gcc gcc --version安装 **centOs**:sudo yum install gcc **centOs**:sudo yum install g **ubuntu**:sudo apt-get install gcc **ubuntu**:sudo apt-get install g **kyLin**:…...
掌握微信聊天记录永久备份:从数据主权到智能记忆管理
掌握微信聊天记录永久备份:从数据主权到智能记忆管理 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChat…...
Betaflight 4.5配置文件升级实战:从STM32H743到AOCODARC H7Dual的硬件适配指南
Betaflight 4.5硬件适配深度解析:从STM32H743到AOCODARC H7Dual的实战迁移指南 穿越机飞控系统的核心在于硬件与软件的完美协同,而Betaflight作为开源飞控领域的标杆,其4.5版本在硬件抽象层进行了重大革新。本文将聚焦STM32H743芯片与AOCODAR…...
下一代嵌入式开发架构实战:基于Rust与STM32F4 HAL的安全高效系统设计
下一代嵌入式开发架构实战:基于Rust与STM32F4 HAL的安全高效系统设计 【免费下载链接】Awesome-Embedded A curated list of awesome embedded programming. 项目地址: https://gitcode.com/gh_mirrors/aw/Awesome-Embedded 在传统嵌入式开发中,开…...
