本帖最后由 donatello1996 于 2020-10-13 00:19 编辑

       本次比赛我原定计划使用USBHID通信的方案,使电脑端上位机程序可以通过USB线发送指令和数据控制开发板进行读卡/写卡操作,而开发板也可以通过STM32 LL库USB发送代码将读到的NFC卡信息发送到电脑端上位机,因此申请的是第一款开发板(ST25R3916-DISCO),但是收到的却是X-NUCLEO-NFC06A1扩展模块和nucleo-64 L476底板,板上没有USB接口,于是只能将官方代码移植到我自己的STM32F769Discovery开发板上,这个Discovery型号开发板带有Arduino扩展接口,4寸液晶屏,一个USB-HID接口,一个USART6串口,可以用于实现我的方案,但在实际测试中USB-HID接口的接收代码有问题,并且官方的X-NUCLEO-NFC06A1扩展模块的中断触发太频繁,因此USB接口只能发送不能接收,相当于崴了脚,不过好在有串口6(USART6),与电脑端上位机通信是没有任何问题的。解决了开发板问题,又到了NFC标签卡的问题,官方赠送了三个NFC标签,是V类标签,但是只有其中一个能识别,另外两个是坏的,于是我去淘宝买了最常用的那种NFC白卡,是A类标签,非常好用,要是没有买NFC白卡,这比赛都没法进行下去了。

系统框图如下:(点击可放大)
2.jpg

整个系统可以分为两部分,对外部分就是STM32主控板以及X-NUCLEO-NFC06A1扩展模块,主控板通过Arduino接口上的SPI接口以及IRQ外部中断接口与X-NUCLEO-NFC06A1扩展模块上面的ST25芯片通信,至于说为什么要用到外部中断呢,那是因为官方的代码就是用SPI中断+外部中断的方式进行通信的。另外,Arduino接口上还有6个通用GPIO接口用于控制扩展模块上面的6个LED灯,这六个灯用于指示各种事件,如LED_Field指示RF接收定时器的工作状态,每秒闪烁一次,LED_A指示是否监测到A类NFC卡读取,LED_V指示是否监测到V类NFC卡读取;对于STM32主控板即STM32F769Discovery开发板,除了用于显示各种信息用的大液晶屏还有一个独立按键(蓝色),用于切换显示模式,有简易模式和完整模式两种,简易模式下,NFC读取后只显示UID号和物业门牌号,完整模式下,NFC读取后不仅显示UID号和门牌号,还显示住户姓名和电话,这个完整模式功能是方便住户用的,住户可以随时查看并修改上面的电话信息,两种模式选择哪种也是住户打卡时自行选择。在Arduino地板上引出了STM32主控板的USART6 TTL串口用于进行数据通信,通过一根CH340串口线转接到电脑USB接口上。最后就是门锁模块和红外传感器模块了,门锁模块用一根GPIO输出高低电平就可以控制,我这里没有专门的门锁模块,用一个电磁继电器代替,红外传感器则可以选择人体红外传感器或者反射式红外传感器,只是为了检测手势用的,可用可不用。
14.jpg

IMG_20201011_135503.jpg IMG_20201011_120735.jpg



流程图如下:(点击可放大)

5.jpg


上电之后,除了进行对必要硬件接口的初始化外,就是打开三个中断,其中两个中断即SPI和IRQ外部中断是官方代码已经写明要打开的,不打开的话没法进行NFC卡的识别,然后就是串口空闲中断了,使用串口空闲中断+RX DMA接收的意义在于开发板可以零延迟接收串口发过来的指令,接收过程不需要CPU主控进行处理,CPU只需一直轮询接收完没有即可(判断一个bool类型的变量是否为真),并且指令长度可以不变,最长为65536字节,大部分情况是使用其中的256字节。


对于NFC卡读取,完整的通信流程如下:

进入官方的DemoCycle()函数的读卡分支,即NDEF_DEMO_READ =》
扩展模块检测到NFC卡的外部中断+SPI中断信号 =》
进行处理得到UID,NFC卡卡内信息 =》
将必要信息显示到液晶屏上 =》
通过特定串口指令将卡上信息发送到电脑QT上位机 =》
电脑上位机发送串口应答包进行开门(可发可不发,不发也没有任何影响)
对于最后一步,电脑端的QT上位机甚至还可以做一个小Demo扩展,就是从文件或者数据库中读取住户信息,只有记录在案的住户信息的其中一条与卡上信息吻合,才给开发板发送开门指令

NFC卡读取,开发板=》电脑上位机串口指令帧结构:
6.jpg

这个帧结构理解起来非常简单,除去前四个起始字节和一个识别字节外,剩下的就是7个UID字节,4个门牌号字节,20个住户姓名字节,11个住户电话字节,1个住户类型字节;

电脑上位机,命令开发板进入读取循环:
8.jpg
这个更简单,识别到起始字节之后第五个字节是0x02就是上位机命令开发板进入读取循环


NFC卡读取完成之后识别正确,上位机命令开发板开门串口指令帧结构:
7.jpg
这个一样简单,识别到起始字节之后第五个字节是0x03就是上位机让开发板开门;


对于NFC卡写入,电脑上位机完整的通信流程如下:

电脑QT上位机发送串口指令使开发板进入写卡循环 =》
进入官方的DemoCycle()函数的写卡分支,即NDEF_DEMO_WRITE_MSG1=》
扩展模块检测到NFC卡的外部中断+SPI中断信号 =》
进行处理将格式化信息写入到卡上=》
开发板发送串口应答包告知电脑上位机写卡完成


对于NFC卡写入,电脑上位机=》开发板的串口指令帧结构

与开发板读取NFC卡发送到电脑端的流程大同小异,少了UID,起始字节改为电脑上位机=》开发板的格式;


NFC卡写入完毕后,开发板=》电脑上位机发送反馈完成报文的串口指令帧结构:
10.jpg


除了上述必要通信流程外,开发板程序加入独立看门狗防止SPI中断读取卡死或者程序跑飞,独立看门狗两秒溢出一次,喂狗间隔为DemoCycle()函数的自带Systick定时器,大致是一秒一次,为了防止在读卡时触发复位,SPI中断服务函数也加入喂狗操作。

电脑端QT上位机与STM32开发板通信采用的协议为串口和USB双协议,为了保证这次比赛作品的完成度并节省时间,目前只实现了串口协议部分的完整通信,而USB协议部分则是做了个简单的交互Demo。上位机界面如下:


3.jpg
NFC读取界面,完整显示NFC卡类型,UID,门牌号,住户姓名,电话,住户类型(租户或业主),这个界面只能读,没有交互按钮;





4.jpg
NFC写入界面,可以自定义门牌号,姓名,电话,在这个界面下可以直接将写入指令输送到主控板上,或者将主控板模式切换为读,下面加入一个写入状态的反馈显示。


到了演示效果环节,首先是默认状态下的NFC卡检测流程,开发板读取到NFC卡之后只在屏幕显示UID和门牌号:

IMG_20201012_085657.jpg IMG_20201012_085731.jpg 1.gif


住户可用按键切换屏幕是否完整显示NFC卡信息,即姓名和手机号也一起显示:
IMG_20201012_090456.jpg IMG_20201012_090458.jpg 2.gif

上位机界面可以看到NFC读取页面的信息刷新了:
13.jpg

至于NFC卡写入那里就不做太完整的演示了,只显示上位机变化:
11.jpg 12.jpg


STM32开发板代码压缩包文件: STM32F769 - 副本.zip (3.31 MB, 下载次数: 9)