TCP over WiFi#
B-L475E-IOT01A 板载的 WiFi 模块为 ISM43362-M3G-L44,其内部集成了 TCP/IP 协议栈,只需简单的 AT 指令即可建立无线连接。ISM43362-M3G-L44 可通过 UART 或 SPI 接口与单片机通信。那这个时候同学们就会有疑问了:thinking:,平时在单片机上用的 WiFi 透传模块几乎都是 UART 的,这款为什么有个 SPI 接口呢?
众所周知啊,单片机高速 WiFi 通信传输,是难以实现的,原因一般在于:
- 支持高速通信的 WiFi 模块,一般是 USB、SDIO、或PCIE 接口,这些接口一般出现在 Cortex-A 系列的芯片,大多数 Cortex-M 系列的普通单片机是没有这种接口的。 
- 即使某些单片机提供了这些接口,单片机和 WiFi模块的通信编程也会变得非常复杂,并造成单片机选型的成本增加。 
- 普通单片机因资源(性能和存储)有限,难以支持实用的、较好性能的单片机 WiFi 方案。 
所以,大多数用在单片机系统上的 WiFi 模块,要么是以 UART 为主的,只能做一些基本的低速控制命令的传输,或者费了九牛二虎之力,集成了 USB、 SDIO、或 PCIE 接口的 WIFI 模块,但效果也很一般,且造价昂贵。因此,在普通单片机上做高速 WiFi 通信(类似 ESP32 这种自带 WiFi 的芯片不在讨论范围内)是难以实现的,而通过 SPI 方式传输,就可以改变这种情况。原因在于 SPI 为全双工通信,传输速率可达几 Mbps,并且大部分单片机上都有 SPI 外设。
实验目的#
- 了解 SPI 通信协议 
- 实现 TCP over WiFi 
准备工作#
- :iphone:安装 TCP Server 软件 
硬件#
- 物联网实验箱 
- USB 数据线 
- :iphone: 
软件#
- CLion 
- STM32CubeMX 
- TCP Server 
相关电路原理#
- STM32 与 WiFi 模块的硬件连接 

:exclamation: 注意
开发板将 wifi 模块的 spi 和 uart 都引出来了,但官方的驱动代码默认使用 spi 通信,可以在程序中修改宏定义的值,从而使用 uart 通信,后面会讲在哪个文件里修改。
引脚定义与相关API#
- 引脚定义 
- 相关API 
实验步骤#
STM32CubeMX创建工程#
- 以开发板为模板生成工程,保持默认设置,不修改任何引脚配置和时钟配置 
代码编写及运行结果#
- 添加需要的源文件和板级支持包(BSP) 
- 添加 BSP(步骤跟前面的章节相同),创建 ~User/wifi 文件夹 
- 将以下路径中的四个 .h 文件添加到新建的 ~User/wifi 目录下,并将 es_wifi_conf_template.h 的文件名修改为 es_wifi_conf.h  
- 将以下路径中的三个 .c 文件添加到新建的 ~User/wifi 目录下  
完成后是这样的

- 修改 CMakeLists.txt 文件 
第56行添加 User

添加以下 include_directories 和 file 路径
include_directories(
        Drivers/BSP/B-L475E-IOT01
        User/wifi
        // 其他include目录
)
file(GLOB_RECURSE SOURCES
        "User/wifi/*.*"
        "Drivers/BSP/B-L475E-IOT01/*.*"
        // *.*表示通配符,也就是这个文件夹里的所有文件都会被编译
        )
- 修改 es_wifi_conf.h 文件,将原有的代码替换成以下代码 
/**
  ******************************************************************************
  * @file    es_wifi_conf.h
  * @author  MCD Application Team
  * @brief   ES-WIFI configuration.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2017 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
#ifndef ES_WIFI_CONF_H
#define ES_WIFI_CONF_H
#ifdef __cplusplus
 extern "C" {
#endif  
//#define WIFI_USE_CMSIS_OS
#ifdef WIFI_USE_CMSIS_OS
#include "cmsis_os.h"
extern osMutexId es_wifi_mutex;
#define LOCK_SPI()              osMutexWait(spi_mutex, 0)
#define UNLOCK_SPI()            osMutexRelease(spi_mutex)
#define LOCK_WIFI()             osMutexWait(es_wifi_mutex, 0)
#define UNLOCK_WIFI()           osMutexRelease(es_wifi_mutex)
#define SEM_SIGNAL(a)           osSemaphoreRelease(a)
#define SEM_WAIT(a,timeout)     osSemaphoreWait(a,timeout)
#define SPI_INTERFACE_PRIO              configMAX_SYSCALL_INTERRUPT_PRIORITY
#else
#define LOCK_WIFI()
#define UNLOCK_WIFI()
#define LOCK_SPI()
#define UNLOCK_SPI()
#define SEM_SIGNAL(a)
#define SPI_INTERFACE_PRIO              0
#endif
#define ES_WIFI_MAX_SSID_NAME_SIZE                  32
#define ES_WIFI_MAX_PSWD_NAME_SIZE                  32
#define ES_WIFI_PRODUCT_ID_SIZE                     32
#define ES_WIFI_PRODUCT_NAME_SIZE                   32
#define ES_WIFI_FW_REV_SIZE                         24
#define ES_WIFI_API_REV_SIZE                        16
#define ES_WIFI_STACK_REV_SIZE                      16
#define ES_WIFI_RTOS_REV_SIZE                       16
#define ES_WIFI_DATA_SIZE                           2000  /*Increased from 1400 to fit scan result.*/
#define ES_WIFI_MAX_DETECTED_AP                     10
   
#define ES_WIFI_TIMEOUT                             30000
                                                    
#define ES_WIFI_USE_PING                            1
#define ES_WIFI_USE_AWS                             0
#define ES_WIFI_USE_FIRMWAREUPDATE                  0
#define ES_WIFI_USE_WPS                             0
                                                    
#define ES_WIFI_USE_SPI                             1
#define ES_WIFI_USE_UART                            (!ES_WIFI_USE_SPI)
   
#ifdef __cplusplus
}
#endif
#endif /* ES_WIFI_CONF_H */
:exclamation: 注意
若要使用 uart 通信,可以通过 es_wifi_conf.h 文件中的宏定义修改
#define ES_WIFI_USE_SPI 1 // 1为SPI,0为uart #define ES_WIFI_USE_UART (!ES_WIFI_USE_SPI)
如果修改为 uart 通信,编译的时候会报错,这时候就要修改 es_wifi.c 文件,添加 char *ptr;。很多官方的代码偶尔会有一些小错误,根据实际情况修改并编译成功就行了。


- 修改 stm32l4xx_it.c 文件,添加以下代码 
/* USER CODE BEGIN 1 */
void EXTI1_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
/* USER CODE END 1 */
- 修改 main.c 文件,让手机和开发板连接上同一个wifi 
手机连接 wifi 后,打开 TCP Server 软件,会出现手机 IP 地址,修改 mian.c 中的 IP 地址。
 
/* Update SSID and PASSWORD with own Access point settings */
#define SSID     "LMX"      //wifi名称
#define PASSWORD "luo010607"    //wifi密码
uint8_t RemoteIP[] = {192,168,137,32};  //手机IP地址,注意是 , 不是 .
- 编译下载代码后,等待开发板连接上 wifi,然后点击 APP 的 CREATE 创建 TCP 连接 
- 右上角出现提示,此时开发板与手机通过 wifi 进行 TCP 通信 
 
- 手机发送”hello, pxh!”到单片机:grin:,单片机接收到(可通过串口查看单片机接收到的信息)并回复”Hello!” 
