Funpack2-6 基于nRF7002-DK实现的多功能NFC电子标签
本设计基于nRF7002-DK开发板的NFC实现了一个多功能的电子标签,可以传输纯文本或快捷启动App(原神,启动!)。
标签
嵌入式系统
Funpack活动
nRF7002
NFC
raincorn
更新2023-10-13
河南工业大学
658

本项目的设计目的是借助nRF7002-DK的板载NFC功能实现多功能卡片模拟,当手机靠近NFC天线时能读取到卡片中存储的字符信息,板卡同时点亮LED1灯表示NFC通信正在进行;板载的按键可以在纯文本传输与启动APP之间切换,板卡通过LED2指示当前的工作模式。

硬件信息

nRF7002-DK板载三颗MCU芯片,其中一片nRF5340用作接口MCU,刷写有Jlink固件提供调试下载与虚拟串口的功能;一片nRF5340用作主MCU,用于用户逻辑的实现;一片nRF7002用作协同MCU,处理Wi-Fi相关的事务,并与主MCU之间通过QSPI进行通信。

Fj4dfvzmDPu8D3xkuzIX0jzQ5h7a

上图即为本板卡的俯视图,其中U2为接口MCU,U1为主MCU,U8为协同MCU。同样地,板卡上板载了三个天线接口J1 J5 J7与两个板载陶瓷天线A1 A2。其中J5为NFC天线接口、J1为WiFi天线接口、J7为蓝牙天线接口、A1为2.4G/5G双频天线、A2为2.4G单频天线,用户可以根据需求配置射频选择器来选择天线使用。

本设计中的关键内容是NFC部分的硬件连接与配置,通过查阅硬件手册的4.13章节得知NFC天线默认连接在P0.02与P0.03两个引脚。这对引脚的默认功能被配置为NFC,如需使用为GPIO需要配置prj.conf并修改硬件电路。相关电路图如下所示,在此只使用NFC功能不对硬件做修改。

FtWP59oM29I_l73XYL7itilKszdo

流程框图

本设计的工作流程展示如下,系统启动后会首先进行按键与LED相关GPIO的初始化,同样也会配置默认NFC工作模式为NFC_TEXT。

  • Button 1按键用于切换NFC工作模式,可以在NFC_TEXT与NFC_APP状态之间切换,功能分别为纯文本传输与APP打开。其中纯文本传输模式会向手机传输"Hello World!"字符串,APP打开模式将会默认启动原神!;

  • LED1用于展示NFC通讯状态,亮起表示NFC正在通信,熄灭表示通信结束;

  • LED2用于展示NFC工作模式,亮起表示处于NFC_TEXT模式,熄灭表示处于NFC_APP模式;

  • 板载Jlink自带两个虚拟串口,在系统正常运行时将会通过串口打印调试信息。

 

FvaAidOWShctyjkIP1Ww15oqrhPO

软件开发

环境配置

Nordic官方推荐的开发工具是VS Code,在其上安装一系列官方插件即可配置出完整的IDE环境,官方文档可以参考How to install the extension。在启动VS Code之前,必须通过官网的Toolchain Manager来安装SDK配置环境,建议不要将安装路径设置在C盘根目录否则容易导致权限问题。一切安装妥当后点击“Open VS Code”启动开发环境,如下图所示当nRF Connect SDK与nRF Connect Toolchain能自当识别到即代表SDK安装正确。

Fh5r2wKWHzWJHGbfNXmS0oQiu7lo

在欢迎界面点击"Create a new application"打开应用创建Freestanding应用,应用正常创建后将会跳转到开发环境,若仍停留在资源管理器界面请自行点击nRF Connect扩展图标打开开发环境。

FuksLA4PtwKTnQSrFbwdih9C7Ss6

此时新建的应用工程将提示"No build configurations"信息,配置"build configuartions"的作用类似配置BSP。在主界面的Board中选择核心为“nrf7002dk_nrf5340_cpuapp”即可,该CPU为不带TFM的核心。虽然该开发板不在兼容列表中,但通过查阅硬件手册可得知二者的NFC引脚相同故可直接套用。

FhzvU24VPzv_xVyMGmEFBKfB3vzM

配置完"build configuartions"后直接编译可能会提示无法找到“nfc_t2t_lib.h”或者"kernel.h",此时建议重启VS Code重新进行索引。同时如果需要使用NFC启动APP或TEXT功能时,需要在prj.conf中开启相关配置否则会报错未定义,本项目配置情况如下:

CONFIG_NFC_NDEF=y
CONFIG_NFC_NDEF_MSG=y
CONFIG_NFC_NDEF_RECORD=y
CONFIG_NFC_NDEF_URI_REC=y
CONFIG_NFC_NDEF_LAUNCHAPP_MSG=y
CONFIG_NFC_NDEF_TEXT_RECORD=y

代码介绍

  • 主函数:dk_leds_initdk_buttons_init分别对LED与按键进行初始化,并指定按键事件的回调函数button_handler。同时在外设初始化完成之后还通过nfc_record_text指定了NFC默认工作模式NFC_TEXT。
int main(void)
{
	int err;
	printk("Starting NFC Launch app example\n");

	/* 设置LED GPIO为输出 */
	err = dk_leds_init();
	if (err) {
		printk("Cannot init LEDs!\n");
		return err;
	}
	
	/* 初始化GPIO端口并指定handler */
	err = dk_buttons_init(button_handler);
	if (err) {
		printk("Cannot init KEYs!\n");
		return err;
	}

	/* 默认配置为record_text模式 */
	nfc_record_text();
	dk_set_led_on(NFC_MODE_LED);
	printk("Mode has been changed to NFC_TEXT!\n");

	return 0;
}
  • 按键事件处理函数:因为T2T模式无法在NFC活跃时修改Payload,因此当Button1按下时要先通过nfc_t2t_emulation_stopnfc_t2t_done关闭NFC功能,然后切换工作模式并重新配置NFC与LED灯。
static void button_handler(uint32_t button_state, uint32_t has_changed)
{
	uint32_t ret;
	uint32_t button = button_state & has_changed; //记录按键按下状态
	if (button & DK_BTN1_MSK)
	{
		//NFC状态切换前先关闭NFC功能
		if (nfc_t2t_emulation_stop()){
			printk("nfc_t2t_emulation_stop ret = %d\r\n", ret);
			return;
		}
		if (nfc_t2t_done()){
			printk("nfc_t2t_done ret = %d\r\n", ret);
			return;
		}

		//切换工作模式
		if (mode == NFC_TEXT)
		{
			mode = NFC_APP; //由NFC_TEXT状态转换为NFC_APP
			nfc_launch_app();
			dk_set_led_off(NFC_MODE_LED);
			printk("Mode has been changed to NFC_APP!\n");
		}else if(mode == NFC_APP)
		{
			mode = NFC_TEXT; //由NFC_APP状态转换为NFC_TEXT
			nfc_record_text();
			dk_set_led_on(NFC_MODE_LED);
			printk("Mode has been changed to NFC_TEXT!\n");
		}
	}
}
  • NFC_APP模式下NFC初始化函数:进行NFC的T2T工作状态配置,NDEF信息编码,Payload载入与NFC模拟开始。其中android_pkg_name为需要打开的Android应用程序包名,可以查询手机的包管理器得到。NFC_TEXT模式的初始化函数与之相似,不再赘述。
int nfc_launch_app()
{
	int err;
	uint32_t len = sizeof(ndef_msg_buf);

	/* 设置NFC为T2T */
	err = nfc_t2t_setup(nfc_callback, NULL);
	if (err) {
		printk("Cannot setup NFC T2T library!\n");
		return err;
	}

	/* 编码android_pkg_name、universal_link到ndef_msg_buf  */
	err = nfc_launchapp_msg_encode(android_pkg_name,
				       sizeof(android_pkg_name),
				       universal_link,
				       sizeof(universal_link),
				       ndef_msg_buf,
				       &len);
	if (err) {
		printk("Cannot encode message!\n");
		return err;
	}

	/* 把已生成的NDEF数据写入NFC Payload */
	err = nfc_t2t_payload_set(ndef_msg_buf, len);
	if (err) {
		printk("Cannot set payload!\n");
		return err;
	}

	/* 开启NFC模拟 */
	err = nfc_t2t_emulation_start();
	if (err) {
		printk("Cannot start emulation!\n");
		return err;
	}

	printk("NFC configuration done\n");

	return 0;
}
  • NFC回调函数:当NFC状态改变时,系统回调该函数处理相关事务。在本函数中,当NFC状态更改为NFC_T2T_EVENT_FIELD_ON时候开启LED灯,当NFC状态更改为NFC_T2T_EVENT_FIELD_OFF关闭LED灯,这两种事务分别对应NFC活跃与离线。
static void nfc_callback(void *context,
			 nfc_t2t_event_t event,
			 const uint8_t *data,
			 size_t data_length)
{
	ARG_UNUSED(context);
	ARG_UNUSED(data);
	ARG_UNUSED(data_length);

	switch (event) {
	case NFC_T2T_EVENT_FIELD_ON:
		dk_set_led_on(NFC_FIELD_LED);
		break;
	case NFC_T2T_EVENT_FIELD_OFF:
		dk_set_led_off(NFC_FIELD_LED);
		break;
	default:
		break;
	}
}

项目展示

分别展示纯文本信息传输与APP打开两个功能:

  • 手机靠近NFC天线,演示纯文本传输"Hello World!":

Foh2vPt2SyVwS5rrgXwZoPQ8R5IF

  • 原神,启动!

FgfclzM_xgEfULvYvEE4gCVY28X2

附件下载
record_launch_app.zip
团队介绍
个人作品
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号