Funpack2-6基于nRF7002_DK模拟NFC卡片打开手机app,打开B站视频
项目基于NRF7002开发板,验证NFC功能。手机扫描NFC自动打开APP跳转到视频链接。
标签
Funpack活动
nRF5340
NFC
岁月静好 山河无恙
更新2023-10-16
677

一、项目介绍

      大家好我是长草的小破号,在参加硬禾学堂和得捷电子联合举办的funpack第二季第六期活动;本次活动设置三个题目,题目1是蓝牙键鼠,题目2是wifi远程控制。题目3是自定义NFC卡片。本次我选择的题目是题目三。

二、硬件介绍

      本次活动使用的开发板是nordic的NRF7002-DK开发板。

FlwcU2JX611QCmvKVYshv5rkR665

      这款开发板上有三颗mcu,两颗NRF5340,其中一颗用做jlink调试下载,另一颗为蓝牙主控芯片。一颗nrf7002,支持WIFI 6开发。本项目围绕nrf5340芯片展开,以下介绍以5340为主。

FmznuV4rDR0w0POeycyFf6JRexaN

 

       nRF5340是一颗双核cortex-M33内核无线SOC. 具有1M闪存和512K ram。支持蓝牙5.2 ,蓝牙低功耗音频,定位寻向等。

FuoLJRManBtY2M9r4rx56cCXP18h

      开发板板载2.4G蓝牙天线。外带一条NFC天线。这里的NFC天线使用FPC制作,是可拆卸的。调试的时候插上,调试完可以收起来,很是方便。nordic蓝牙芯片因其优秀的低功耗性能,多用于可穿戴设备,无线键鼠,智能家居,医疗器械等领域。

三、实现过程

      开发环境搭建:

      这里使用官方推荐的NRF connect for desktop.

Ft-IVPiXtlj4ZLVuQjNB4SblyLaW

      这个工具包里包含很多小工具,其中安装工具链会花些时间和精力,SDK版本我使用的是2.4.2,具体的安装教程,网上有很多前辈做过,这里不再赘述。在调试过程中可能遇到芯片保护无法下载代码的问题。需要使用命令解除保护,可能是我环境变量的问题,west命令无法执行。最后使用programmer进行全擦除才搞定。

FrYAHhWGv83k-lBgJ86uoQSMKjTj

      VScode的编译环境做的很全面,各种配置都很方便,debug和调试起来很方便。整体感觉nodic官方推荐的工具用起来还是很顺手的。

      NFC相关原理:

      环境搭建好就可以开始着手项目实现了。要想自定义一个NFC卡片,就需要了解手机在扫描NFC标签时发生了什么。当手机靠近NFC标签时,手机的NFC芯片会驱动13.6MHz天线,将信号传递到NFC标签天线,从而与NFC标签建立通信。NFC标签中包含了一些事先存储的信息,比如URL链接、应用程序启动命令等。手机的NFC芯片会读取这些信息,并根据标签中的指令执行相应的操作。

      功能需求:

      本次项目想要实现一个NFC标签既能打开APP又能打开视频链接的功能。

      任务分解:

      要想实现上述功能,大概需要两步:

      1.需要先将相关信息写入NFC标签中,本项目共记录两条数据,一条为哔哩哔哩视频链接,另一条是手机浏览器via app 启动指令。指令获取流程如下:打开NFC_TOOLS_PRO,切换到”写“任务栏,点击”添加记录“找到”应用程序“,最后点击android图标,上下滑动选择自己手机的应用程序。选好后APP相关信息会显示再左边的文本输入框里。

      2.NFC信息切换可以定义一个循环变量,记录扫描次数,扫描动作计满2次切换一次NFC标签内容。

四、软件相关

      软件流程如下,程序开始进入初始化,

FkeRQTiWdGWqpsUDiMWXG8dspI1i

     代码需要使用到uri_msg.h头文件,添加头文件时注意需要在两个地方同时添加才有效,一个是在主程序开始添加:

FhMDrKP2oJynE4li72mDVkz8l92y

      另一处是要在prj.conf 文件中添加,如下图:

FglegSr9vgqQUHYU9vvkfdeWmYiS

      主要代码如下:

      APP名称

static const uint8_t android_via_app[] = {                   //存储via浏览器名称
	'm', 'a', 'r', 'k', '.', 'v', 'i', 'a' };

      B站视频链接:

static const uint8_t bilibili_link[] = {                      //硬禾学堂B站视频
'h', 't', 't', 'p', 's', ':', '/', '/', 'w', 'w', 'w', '.', 'b', 'i', 'l', 'i', 'b', 'i', 'l', 'i', '.', 'c', 'o', 'm', '/', 'v', 'i', 'd', 'e', 'o', '/', 'B', 'V', '1', 'D', 'k', '4', 'y', '1', 'T', '7', 'N', 't' 
};

     NFC事件回调函数:回调函数操作了两个变量,一个是 SCAN_state,用来记录扫描状态,当手机靠近时置1,表示允许程序切换NFC内数据。第二个变量是NFC_count,这个变量用来累计扫描次数,判断到达设定次数后执行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);  指示灯注释掉 常亮太刺眼了
		SCAN_state=1;			      //扫描状态改变
		k_msleep(100);               //延时避免重复触发?  
		break;
	case NFC_T2T_EVENT_FIELD_OFF:
//		dk_set_led_off(NFC_FIELD_LED);  指示灯注释掉 常亮太刺眼了
		NFC_count++;               //只有当手机抬起时 NFC扫描次数才进入累加;
		
		break;
	default:
		break;
	}
}

      主程序部分首先将写入via APP 启动指令写入NFC标签。然后在while 1 里循环判断两个变量状态,当满足条件时将NFC停下来,写入哔哩哔哩 视频链接 ,再重启NFC。 此处注意在重新编辑NFC信息后要清掉标志位,这样就不会出现一遍一遍执行 NFC写入命令。

int main(void)
{
	int err;
	size_t len = sizeof(ndef_msg_buf);

	printk("Starting NFC Launch app example\n");
	/* Configure LED-pins as outputs */
	err = dk_leds_init();           //led初始化

	/* Set up NFC */
	err = nfc_t2t_setup(nfc_callback, NULL);
	/* Encode launch app data  */
	err = nfc_launchapp_msg_encode(android_via_app,             //写入APP信息
				       sizeof(android_via_app),
				       bilibili_link,
				       sizeof(bilibili_link),
				       ndef_msg_buf,
				       &len);

	/* Set created message as the NFC payload */
	err = nfc_t2t_payload_set(ndef_msg_buf, len);                     //装载数据

	/* Start sensing NFC field */
	err = nfc_t2t_emulation_start();                                           //启动NFC

	while(1)                                    //定义while 1 循环,根据扫描状态 和NFC扫描次数判断是否重新编辑NFC内容
	{
		/*指示灯闪烁表示程序正常运行*/
		dk_set_led_on(NFC_FIELD_LED);           //让指示灯熄灭
		dk_set_led_on(NFC_WRITE_LED);
		k_msleep(2000);
		dk_set_led_off(NFC_FIELD_LED);           //让指示灯点亮
		k_msleep(10);

		if((NFC_count>1)&&(NFC_count<3)&&(SCAN_state==1))
		{
		SCAN_state=0;                         //在开始重新编辑nfc内容时先把标志位清除,避免重复编辑NFC内容
		err=nfc_t2t_emulation_stop();         //停止nfc
		ndef_msg_buf_clear(ndef_msg_buf);     //清除缓存数据  

		err=nfc_ndef_uri_msg_encode(          //将bili bili 链接写入缓存
				       0x00,
				       bilibili_link,
				       sizeof(bilibili_link),
				       ndef_msg_buf,
				       &len); 

		k_msleep(10);                               //插入一段延时

		err=nfc_t2t_payload_set(ndef_msg_buf, len);   //装载数据


		k_msleep(10);

		err=nfc_t2t_emulation_start();                //开启NFC功能  自此bilibili 链接写入成功

		}

		if(NFC_count>4)
		{
			goto fail;      //程序进入重启 回到开始重新写入via app 信息
			return err;
		}
	k_msleep(100);

	}

   return 0;                  //放到while 1 后面
fail:
#if CONFIG_REBOOT
	sys_reboot(SYS_REBOOT_COLD);
#endif /* CONFIG_REBOOT */

	return err;
}

      超出扫描次数软件重启,重新写入APP数据

	if(NFC_count>4)
	{
		goto fail;      //进入重启
		return err;
	}

      最后有一个函数很关键,缓存数组清除函数,在重新编辑NFC信息前需打扫战场,使一切变量恢复如初才不会出错。

void ndef_msg_buf_clear(const uint8_t *payload)        //这是一段清除缓存内容的代码 
{
	uint8_t count;
	for(count=0;count<255;count++)
	{
		ndef_msg_buf[count]=0x00;
	}

}

四、功能展示

      使用nrf5340模拟了一个NFC tag,用手机扫一扫可以打开手机上的浏览器,然后在第三次扫描时,NFC信息会自动切换为硬禾学堂对本期活动的介绍视频。

Fm6BT_l4gkBc6wra4buMYYk-Y5JUFqq62ZsFojVjqtrPWWhLBpUoVGm8FpxgOYEa_S90CQ24ZKSY1zljhTdb

五、心得体会

      本次活动开发环境的搭建不算顺利,来来回回折腾了好几遍;好在大家都有问必答,遇到的问题都能完美解决;

      参加这次活动的初衷是为了学习蓝牙开发。现在NFC开发走顺了,接下来搞蓝牙项目应该会顺利些;

      最后感谢主办方推出的funpack系列活动,期待下一期。

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