之前接触过UART8266模块,但是它本质上是串口转wifi,带宽瓶颈都被串口给限制死了,不符合我的需求。在正点原子网站上无意间发现一款基于SPI的8266模块广告,果断入手回来摆弄试试。官方给出的数据是,能够达到M级的传输速率,可以应用在图传等领域。我是在STM32F405上使用它,经过一段时间的摆弄,基本达到了可用的阶段。
SPI的通信机制在之前捣腾的SPI双机通信里熟悉的差不多了,而且这个模块本身已经做了很完善的封装,卖家提供了比较详细的例程,所以很快就实现了通信。我要做的就是把例程看懂,并且在此基础上进行一些开发。
前面说过模块进行了很完善的封装,提供了丰富的API。所以刚拿到的时候只需要注意硬件的连接,还要修改配置文件中的一些宏定义即可。在使用例程实现通信中,主要有以下几个内容:
片选引脚和复位引脚的选定:这里之所以这么重要是因为模块本身会调用一个复位函数,其中涉及到一些片选和复位引脚的电平操作时序,所以要确定自己的主板上使用哪两个引脚作为片选和复位引脚,并且在例程的配置文件中作相应的修改;对于我选择的探索者开发板,例程配置文件中已经做好了LED,KEY以及SPI的初始化,所以程序部分没什么需要修改的,主要还是硬件连接,MISO和MOSI不能接错;上述硬件连接没问题后,下一步就是去修改STA/AP模式,STA需要修改目标热点的SSID和PSWD,AP模式需要修改自己的SSID和PSWD;选择通信方式为UDP/TCP,只是一个宏定义。麻烦的地方是IP和端口的指定,这一块很容易搞混;选择例程测试模式:收/发/收发;对于讲究模块数据接收的实时性,则需要用一个GPIO口配置为外部中断与模块的指定引脚连接;上手测试基本上没什么难度,主要就是有很多小细节不注意就会很浪费时间。只要把说明书好好看一边这些都不是问题。
我的使用场景中决定了该模块应当配置为:STA,UDP,一对多模式。
STA(Station)和AP(Access Point)其实是局域网中很常见的两个概念,简单的说,平常我们连接的路由器就可以理解为AP模式,而手机、电脑等设备则都是STA模式。UDP和TCP这两个比较常见的协议,UDP是无连接、不可靠但低延时的协议,而TCP则是可靠但延时不稳定的协议。此外,UDP支持广播而TCP只能点对点一对多的模式也决定了只能使用UDP而不能使用TCP剔除掉例程初始化过程中的无关紧要的部分以及最后的测试代码。最终的效果就是模块在上电连接到指定的AP后保持该状态。我不是很喜欢在代码中把IP和PORT写死,这样每次更换热点的时候会很麻烦,所以在这个过程中我做了如下工作:
开启一个连接服务,使用模块的一个固定端口:ListeningPort,远端IP和端口为随意指定。该服务不向外发送数据,仅仅起到监听的作用;PC在接入相同的AP后,使用本地的端口开启一个UDP服务,向255.255.255.255:ListeningPort发送一帧请求接入数据帧;模块接收中断触发后,接收数据并且提取出数据帧的源IP和PORT(模块API提供了相关函数);在请求帧解包正确的情况下,根据源信息以及本地的一个新端口,开启一个新的连接服务,发送一个响应数据帧返回给PC;PC接收到后同样可以解析出模块的IP和PORT,将先前开启的广播服务修改为面向模块的服务;至此,PC和模块完成了连接。在这个过程中优点是不需要对IP进行管理,可以很方便的实现模块和PC的通信,同时对于一对多的情况也很方便;缺点就是牺牲了一个监听端口,使得原本就只能支持同时开启4个服务的模块又少了一个。 上面提到的服务数限制,也就要求模块本身需要对接入请求以及已建立的服务进行一个管理。我设计了一个简单的抢占以及优先级机制,可以理解为是偷学的ucos。。但是实际上要简陋好多。。不过至少是实现了对接入设备的一个可控的管理。具体逻辑如下: 目前使用的板子已经实现了上述功能,当然接下来才是重头戏,通信协议的设计。本身UDP就是无连接的,如果没有心跳包之类的机制,模块也无法知道PC是否还在正常工作。还有一个问题是:模块的服务数有限,是否考虑使用广播机制,使得模块只需要开启一个广播就可以实现对所有设备的通信,所有的通信压力都交给路由器来做。此外,,上述调试过程中PC端都是使用的网络调试助手,后面自己还得写个PC端的测试软件配合使用,也许心血来潮试试写个安卓程序?路漫漫…