丁丁的个人博客

作者: admin 分类: 娱乐 发布时间: 2020-01-17 10:59

  STM32与PN532修建NFC近场通讯指南(五):一种合用于STM32的通用串口通讯架构及与PN532的通讯推行

  STM32与PN532修建NFC近场通讯指南(五):一种合用于STM32的通用串口通讯架构及与PN532的通讯推行

  STM32与PN532修建NFC近场通讯指南(五):一种合用于STM32的通用串口通讯架构及与PN532的通讯推行

  这是这篇系列教程的结果一章节,有了之前的根基,咱们该当对PN532的通讯流程,以及收发包的细节有了肯定的认知,下面即是用STM32与PN532扶植相接了。本章节的最终方向,是愿望修建一套针对任无意设收发包的通用框架,而不单限于PN532和串口通讯。

  我局部对基于HAL库和RT-Thread的STM32开拓情有独钟,所以项目操纵STM32CubeMX天生了HAL库的KEIL工程,并正在KEIL中引入了RT-Thread nano。通讯框架的计划时我尽量避免了RT-Thread的信号量和事务的通报,而是采用最根基的办法,假使您能熟练操纵RT-Thread及其种种线程同步伎俩,那么修建通讯框架是一件卓殊适意的事,可能完整做成事务驱动的办法。

  开始,STM32中串口的设备,此处不表,我由于PCB计划的合联,这里用的是UART5。关于串口尚不知怎么初始化的同伙,可能阅读之前的几篇合于STM32的教程。

  这里值得属意的是,我局部方向于操纵DMA来处罚表设通讯,操纵STM32CubeMX不妨卓殊容易地设备出UART和DMA干系,同时启动UART的IDLE空闲停止,这种机造配合RT-Thread信号量等本领,可能卓殊适意地处罚大概长数据包。这里我由于念要更好地满意通用性,并没有操纵DMA和IDLE空闲停止,而是采用的UART_IRQHandler和HAL_UART_RxCpltCallback模范吸收停止来处罚吸收到的数据包。此后有机遇,我会正在新的项目教程里,用RT-Thread配合DMA和空闲停止来奥妙地处罚大概长数据包。

  关于数据的发送,咱们直接用HAL库的HAL_UART_Transmit发送函数即可;关于数据的吸收,咱们愿望开一个足够大的BUFFER数组,然后设立两个尖兵,一个叫前哨,一个叫后哨,前哨尽管往BUFFER里追加数据,后哨用来处罚数据,当后哨追逐上前哨时,两个尖兵都退回到BUFFER的发轫,从而完毕一种简单的吸收缓冲队伍。前哨的处罚理所当然会正在停止供职函数HAL_UART_RxCpltCallback中,后哨的处罚会正在行使逻辑中进处罚。

  无论是C++,JAVA,Go这类的高级软件开拓,照样JavaScript,HTML5这类的前端计划,囊括咱们现正在玩得较量多的纯C的嵌入式开拓,咱们总愿望编写的代码尽量模块化。比方咱们本日正在STM32F4上操纵了PN532做一个DEMO,咱们下一次能够会正在STM32F1/L0乃至STC51单片机上操纵PN532(事实只须有UART/I2C/SPI接口,软契约都相同的),假使咱们编写的合于PN532的代码会合正在某一个或者某几个文献中,正在其他项目中不妨直接引入工程做到开箱即用,那将是一件很酷的事宜。

  凭据模块化的头脑,咱们正在工程中新筑一个pn532.c和pn532.h,以及一个pn532hw.c的文献,咱们的念法是正在pn532.c中尽量实现一切与PN532合连契约栈的处罚,此后这个文献尽量不须要改动的;正在pn532hw.c文献中实现与硬件合连的耦合,并行使__weak合节字来注明,这些代码是须要与现实情景耦合的,其他工程是要酌情调解的。咱们正在编程的历程中都要尽能够依旧云云优越的模块化头脑,让工程代码变得很有层次,简单日后的保卫和移植。

  合于组织体,指针,他们与通讯契约的合联,C/C++发言的入门者能够并不行很好地独揽,正在这里引荐一本书《长远分析C指针》,看了这本书,我正在普通编程中对指针的行使率有了一个很大的升高,正在看少少大牛写的庞杂的合于指针蜕化的表达式时也能做到游刃多余。正在现实行使中,一种很棒的伎俩即是是计划合理的组织体,囊括组织体的巨细,内部变量的程序,变量的长度,这些都须要当心计划和计划,大个别工夫还须要操纵位字段、1字节对齐等伎俩。正在数据传输或者解析时,尽量让组织体全面酿成一个buffer用来传输,不要举办多余的内存拷贝操作。关于定长通讯契约,这么做可能计划出一套很棒的组织体出来,后面只须要对组织体赋完值,就能直接发送出去了。

  关于大概长的通讯数据包,咱们可能正在组织体中空洞出少少特点点,然后正在组织体其内部开垦一段buffer,计划一套code和decode函数,正在收发前后免不了举办少少内存拷贝。下面咱们来看一段合于PN532通讯契约计划出来的组织体:

  上述代码第一个组织体形容了一个PN532数据帧,第二个组织体形容了关于全面工程来说的一个总体PN532组织体对象,此后只须有了这个对象,合于全面契约栈的一切情景就了如指掌了,囊括各个BUFFER缓冲区,以及前尖兵和后尖兵的身分。同时由于C发言没有namespace之类的定名空间,所以用一个大型组织体封装模块所需的一切零落对象,不单能做到团结执掌,又能做到不污染其他表部全部变量。

  纯C的本领通俗来说被大无数人大大地低估了,人们老是天然而然地感应C++/JAVA要比纯C越发庞大,实在无论出于功能照样编程安逸性来说,纯C的本领都不逊于由此派生出去的那些高级发言。

  C的组织体+函数指针,这两个元素纠合起来就能完毕大个别C++/JAVA中类的效力。假使人工地再属意少少编程样板,比方驼峰式定名,大写函数首字母举动public函数,幼写函数首字母举动private函数等等,就能让C变得像高级发言相同逻辑了解。

  这段代码没有直接挪用HAL_UART_Transmit函数,而是挪用了pn532hw.c中的Pn532hwSendBuffer,即是注明数据的发送并不跟完全的硬件表设强耦合,假使这里写死了,就无法确保pn532.c正在以后契约栈移植时的褂讪性。再看pn532hw.c中Pn532hwSendBuffer的界说:

  可能看出,这里还是没有真正用HAL_UART_Transmit完毕发包,而是用一个__weak弱界说合节字形容了一个空函数,而且正在说明中提示开拓者必必要完毕这一函数。于是上层行使,可能正在工程中轻易身分从新强界说这个函数,真正地完毕数据包的发送。别的属意阅览到上面的Pn532hwWait函数,由于正在编写代码时,不成避免地会遭遇少少地方须要延时恭候,正在操纵RTOS和不操纵RTOS的情景下,能够延时的处罚不尽类似,是以这里的延时函数也操纵__weak界说了,只但是这里没有效空函数界说,而是默认操纵模范的HAL延时来处罚。

  可能看到,模块层通过两个尖兵RxCurrentPos和RxBufferSize,推断编造里现正在有没有尚未处罚掉的收取数据,实在模块层并没有完全地合注底层数据的吸收,而是靠尖兵的站位来推断有没少见据收取,那么逻辑就了解了,硬件层只须要追加数据进入buffer并转移前哨站位,就可能完毕数据的收取和处罚了。看pn532hw.c中的下面函数:

  这个函数没有举办弱界说,是一个不让遮盖的函数,同时说明中还写了这个函数必需被上层行使所挪用,模块才调平常吸收数据。这个函数中最首要的就两行代码:

  OK,现正在数据的吸收和发送都架构好了,咱们可能平常收发了。看看咱们的pn532.h中都形容了若何的函数界说:

  这个中少少完全的完毕办法不太首要,群多可能凭据我方的行使场景和逻辑去构造,首要的编程思念和模块化的解耦处罚,以及代码书写的风气。这里就扔转引玉了,自信肯定再有更多更卓越的架构办法。

  这一章咱们实在没有太多的合注PN532的契约,也没有带着群多正在STM32的根基上一步一步完毕PN532的契约,乃至没有过多的代码细节。但这一集所讲的实质正好是我最愿望分析的编程思念,面临一个纯C发言的嵌入式工程,怎么计划咱们的代码文献,秒速快3登录每个文献干少少什么事,放哪些逻辑,写代码的缩进办法是什么样的,变量名称怎么确定,函数名称怎么确定,哪些东西放正在全部变量中,我念这些才是最名贵的少少经历之讲吧。

  那么本系列教程就收场了,此后有机遇还会不断写少少面向项宗旨,面向某一完全模块的编程教程,愿望群多嗜好和支柱。

  本章为系列指南第四章,首要先容上位机与PN532举办Mifare S50卡片读写全流程的通讯数据流。中心须要阅读PN532 User Manual.pdf的第7章,目次如下:

  上一章中,咱们认识了PN532的通讯契约,其数据帧式样中有一段数据负载区域DATA,从PD0到PDn。正在PN532UM 第7章中有如下形容:

  将PN532模块的4根引脚与PC-USB-CH340模块(或者其他USB-TTL串口筑筑)相连,操纵串口调试帮手等软件举办上位机模仿:

  对比通讯契约,咱们可能很容易分析:发包后告捷收到了一个6字节ACK包,随后收到了一个Reponse数据,解析内部DATA为:03 32 01 06 07,个中03是发送指令02的+1呼应,后面32 01 06 07为返回的固件版本号。

  OK,至此咱们仍旧告捷的分析了一切通讯时所涉及的常识点,而且买通了第一次与PN532的通讯。下面即是凭据现实生意需求,举办数据包的请乞降继承了。

  正在本系列教程的第二讲STM32与PN532修建NFC近场通讯指南(二):PN532及恩智浦PN系列产物简介中,咱们提到,关于Mifare S50卡的读写流程,大致上分为以下环节:

  掀开手册到7.3.5章节,这一章的InListPassiveTarget指令即是寻卡的趣味,可能看到它的Command Code是0x4A,后面再有MaxTg和BrTy两个参数,凭据它的形容即可修建以下包:

  个中39 01 0B B1是这张卡片的UUID,这个咱们须要寄到本本上,后面还须要操纵。假使正在MCU中,那就配置一个32bit度的变量,将其缓存起来。

  掀开文档7.3.8章,这一章讲InDataExchange指令。这个指令可能与NFC对象举办数据交互,咱们须要完毕的认证操作,举动这个指令的子指令集包蕴正在个中,后面的数据读写指令也包蕴正在这个指令会合。

  当心阅读手册的Page130页,这里排列了咱们须要的几个子指令集,囊括认证和16字节的读写。而且还卓殊人道化地供应了几个example,咱们效尤样例,修建一个关于2号数据块的认证包:

  这一章咱们对PN532的通讯流程和合连指令集有了一次详明的梳理,凭据咱们的行使场景,计划出一套读写Mifare S50的最简数据流。下一章咱们将用STM32举动上位机,操纵串口举动通讯介接口,与PN532举办通讯,值得属意的是,下一章咱们将研商计划出一套通用的数据流处罚框架,无论是操纵UART, I2C, SPI都能滑润操纵的读写数据流的架构,并不单限于与PN532通讯。

  本章为系列指南第三章,首要先容上位机与PN532的通讯契约,本章咱们须要中心阅读PN532 User Manual.pdf手册的第6章,该章节目次如下:

  任何成编造的通讯契约都是由数据帧组成的,数据帧组织会正在全面通讯契约大个别合节中依旧类似,局部契约会临时呈现几个格表帧指令用来完毕格表效力。试念此次由咱们我方创作修建一套通讯契约,无非包蕴这几个方面:包头,长度,负载,校验,包尾;假使是针对读写寄存器的帧组织,那么还囊括:指令(读/写),寄存器所在,值(返回/写入)等;假使有1:N乃至N:M的总线架构,那么还要囊括方向所在Target和开头所在Source(相似以太网帧)。

  相似的,PN532与上位机之间通讯契约也会有上面那些元素,让咱们掀开文档看一看,正在PN532UM.pdf 6.2.1 Frames structure章节即是形容的数据帧式样,如下:

  OK,PN532的数据帧式样相比较较浅易,比拟咱们上面我方设念的通讯契约只是多了一个LCS的观念,从计划公式上来看,这是LEN的相反数。别的,数据负载段的校验数DCS,也是操纵和校验的相反数来显示。

  正在PN532UM 的 6.2.1.3- 6.2.1.5章节,先容了ACK呼应包的组织,NACK很是呼应包的组织,以及犯错包的组织,这里就不赘述了,事实咱们老是指望能获得确切的呼应。ACK包组织如下,卓殊浅易:

  ,PN532继承到此后会即刻发送一个ACK给主控,然后颠末一段年光处罚,PN532会再发送一次Response Packet给主控,至于主控念不念再发一个ACK给PN532,这个PN532不强求。这是一品种似TCP相接的历程。图中右边的P70_IRQ是一根停止信号线的电平蜕化历程,假使操纵UART来收发数据帧的话,这个信号可能纰漏,操纵串口RX停止就足够了,假使操纵485芯片来处罚,这根线章节的后续实质还形容了产生舛误时的会话流程,这里不表了,不首要。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!