你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CubeIDE的WIFI通信经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-7 15:08
一、stm32的WIFI配置        通常WIFI模块就是一个独立的单片机,只是内置了WFIF通信软件的单片机,并该通信软件提供了AT通信指令集给开发人员,基于这些指令集我们就可以针对项目需要进行二次集成开发出所需的业务应用软件。        本文本文采用的开发板是stm32L496VGT3,该开发板的MCU及WIFI模块(MW31)硬件电路图如下:        MCU采用PC4、PC5连接WIFI实现通信,PB0、PB1作为辅助控制。 d0dfa03d396047499c57c8f5a8ad06d7.png WIFI模块给出了两个通信接口,一个用来连接MCU(电路板已经连接好了,本文就采用该接口实现MCP串口通信控制WIFI模块),一个用来给外置使用。 99bba58bce1b452490dc250168d45cfb.png 与WIFI通信关联的MCU的IO端口设置要求,开发板给出如下: f8e3ff7fe3934d8e9fef03f1cfe49d8d.png          以及各个IO口具体参数要求 ee5109a3a7214726a6a7d5b02bcb7da4.png          打开CubeMX配置页面,按上述要求设置WIFI配置通信接口USART3: f7387884706e47dabc01717c21fcbffc.png          开启USART3外部中断功能: 68aa2fdb1ed749138e8f932b78947a78.png          设置PC4、PC5的IO接口参数 a23de988873f4b8c8645b2a5fe61ae18.png          同时芯片图形化配置页面设置PB0、PB1为GPIO_OutPut模式,并进入GPIO配置页面,设置PB0、PB1的IO接口参数: 3d67266a85744e0ebfc4ef63abf704c3.png           完成配置点击保存按钮或代码生产按钮生成代码: 557d3788476c48f193e40d4bde41a7fa.png 二、代码设计        本文基于前一篇博文的串口通信能力基础上来实现的,即已经完成了printf函数映射到lpusart进行串口通信         我们先实现串口USART3的接收回调实现,在改写ICore目录下的usart.h、usart.c代码文件:        usart.h内容如下,类似lpusart串口添加了串口USART3的接收辅助变量:
  1. /*
  2. * usart.h
  3. *
  4. *  Created on: Oct 20, 2022
  5. *      Author: Administrator
  6. */
  7. #ifndef INC_USART_H_
  8. #define INC_USART_H_
  9. #include "stm32l4xx_hal.h" //HAL库文件声明
  10. #include <string.h>//用于字符串处理的库
  11. #include "print.h"//用于printf函数串口重映射
  12. extern UART_HandleTypeDef hlpuart1;//声明LPUSART的HAL库结构体
  13. extern UART_HandleTypeDef huart3;//声明USART3的HAL库结构体
  14. #define HLPUSART_REC_LEN  256//定义LPUSART最大接收字节数
  15. #define USART3_REC_LEN  256//定义USART3最大接收字节数
  16. extern uint8_t  HLPUSART_RX_BUF[HLPUSART_REC_LEN];//接收缓冲,最大HLPUSART_REC_LEN个字节.末字节为换行符
  17. extern uint16_t HLPUSART_RX_STA;//接收状态标记
  18. extern uint8_t HLPUSART_NewData;//当前串口中断接收的1个字节数据的缓存
  19. extern uint8_t USART3_RX_BUF[USART3_REC_LEN];        //接收缓冲,最大USART_REC_LEN个字节.
  20. extern uint16_t USART3_RX_STA;                                //接收状态标记,bit15:接收完成标志,bit14:接收到0x0d,bit11~0:接收到的有效字节数目
  21. extern uint8_t USART3_NewData;                                        //当前串口中断接收的1个字节数据的缓存
  22. void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart);//串口中断回调函数声明
  23. #endif /* INC_USART_H_ */
复制代码
        usart.c内容如下,添加了USART3的回调处理,实现接收来自WIFI模块的数据,lpusart和USART3的回调处理几乎一样的,主要就是接收到一个数据,就缓存起来,并再次开启中断接收;在接收到回车字段或缓存溢出是,进行标记(HLPUSART_RX_STA和USART3_RX_STA的前四位可以标记,后12位为数据长度记录)改写,该标记留给外部调用来处理,不再回调函数中进行接收标记复位:
  1. /*
  2. * usart.c
  3. *
  4. *  Created on: Oct 20, 2022
  5. *      Author: Administrator
  6. */
  7. #include "usart.h"
  8. #include "wifi.h"
  9. uint8_t  HLPUSART_RX_BUF[HLPUSART_REC_LEN];//接收缓冲,最大HLPUSART_REC_LEN个字节.末字节为换行符
  10. /*
  11. * bit15:接收到回车(0x0d)时设置HLPUSART_RX_STA|=0x8000;
  12. * bit14:接收溢出标志,数据超出缓存长度时,设置HLPUSART_RX_STA|=0x4000;
  13. * bit13:预留
  14. * bit12:预留
  15. * bit11~0:接收到的有效字节数目(0~4095)
  16. */
  17. uint16_t HLPUSART_RX_STA=0;接收状态标记//bit15:接收完成标志,bit14:接收到回车(0x0d),bit13~0:接收到的有效字节数目
  18. uint8_t HLPUSART_NewData;//当前串口中断接收的1个字节数据的缓存
  19. uint8_t USART3_RX_BUF[USART3_REC_LEN];        //接收缓冲,最大USART_REC_LEN个字节.
  20. uint16_t USART3_RX_STA=0;                                //接收状态标记,bit15:接收完成标志,bit14:接收到0x0d,bit11~0:接收到的有效字节数目
  21. uint8_t USART3_NewData;                                        //当前串口中断接收的1个字节数据的缓存
  22. void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)//串口中断回调函数
  23. {
  24.         if(huart ==&hlpuart1)//判断中断来源(串口1:USB转串口)
  25.     {
  26.                 if(HLPUSART_NewData==0x0d){//回车标记
  27.                HLPUSART_RX_STA|=0x8000;//标记接到回车
  28.                 }else{
  29.                         if((HLPUSART_RX_STA&0X0FFF)<HLPUSART_REC_LEN){
  30.                                 HLPUSART_RX_BUF[HLPUSART_RX_STA&0X0FFF]=HLPUSART_NewData; //将收到的数据放入数组
  31.                                 HLPUSART_RX_STA++;  //数据长度计数加1
  32.                         }else{
  33.                                 HLPUSART_RX_STA|=0x4000;//数据超出缓存长度,标记溢出
  34.                         }
  35.         }
  36.        HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData,1); //再开启接收中断
  37.     }
  38.         if(huart ==&huart3)//判断中断来源(串口3:WIFI模块)
  39.         {
  40.                 if(USART3_NewData==0x0d){//回车标记
  41.                         USART3_RX_STA|=0x8000;//标记接到回车
  42.                 }else{
  43.                         if((USART3_RX_STA&0X0FFF)<USART3_REC_LEN){
  44.                                 USART3_RX_BUF[USART3_RX_STA&0X0FFF]=USART3_NewData; //将收到的数据放入数组
  45.                                 USART3_RX_STA++;  //数据长度计数加1
  46.                         }else{
  47.                                 USART3_RX_STA|=0x4000;//数据超出缓存长度,标记溢出
  48.                         }
  49.         }
  50.                 HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData,1); //再开启接收中断
  51.         }
  52. }
复制代码
        在ICore目录下创建wifi.h和wifi.c源码文件实现WIFI驱动:        wifi.h内容如下:
  1. /*
  2. * wifi.h
  3. *
  4. *  Created on:
  5. *      Author: Administrator
  6. */
  7. #ifndef WIFI_WIFI_H_
  8. #define WIFI_WIFI_H_
  9. #include "stm32l4xx_hal.h" //HAL库文件声明
  10. #include "usart.h"
  11. #include "main.h"
  12. #include <string.h>//用于字符串处理的库
  13. #include <stdarg.h>
  14. #include <stdlib.h>
  15. #include "stdio.h"
  16. extern UART_HandleTypeDef huart3;//声明UART2的HAL库结构体
  17. void WIFI_printf (char *fmt, ...); //WIFI模块发送
  18. void WIFI_TCP_SEND (char *fmt, ...);//在TCP模式下的发送数据(不处理返回状态的盲发)
  19. #endif /* WIFI_WIFI_H_ */
复制代码
        wifi.c内容如下,本质上就是调用HAL_UART_Transmit函数对huart3句柄进行写入数据操作,实现发送数据到WIFI模块:
  1. /*
  2. * wifi.c
  3. *
  4. *  Created on:
  5. *      Author: Administrator
  6. */
  7. #include "wifi.h"
  8. //WIFI模块通信,使用UART3,这是专用的printf函数
  9. //调用方法:WIFI_printf("123"); //向USART2发送字符123
  10. void WIFI_printf (char *fmt, ...)
  11. {
  12.         char buff[USART3_REC_LEN+1];  //用于存放转换后的数据 [长度]
  13.         uint16_t i=0;
  14.         va_list arg_ptr;
  15.         va_start(arg_ptr, fmt);
  16.         vsnprintf(buff, USART3_REC_LEN+1, fmt, arg_ptr);//数据转换
  17.         i=strlen(buff);//得出数据长度
  18.         if(strlen(buff)>USART3_REC_LEN)i=USART3_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
  19.         /*HAL_StatusTypeDef ret =*/ HAL_UART_Transmit(&huart3,(uint8_t *)buff,i,0xffff);//串口发送函数(串口号,内容,数量,溢出时间)
  20.     //printf("WIFI_printf Len:%02d\r\n",ret);
  21.     va_end(arg_ptr);
  22. }
  23. //WIFI模块在TCP模式下的数据发送:TCP发送的规定是先发AT+CIPSEND=数量,等待返回“>“后再发送数据内容。
  24. //调用方法:WIFI_TCP_SEND("123\r\n"); //TCP方式发送字符123和回车换行
  25. void WIFI_TCP_SEND (char *fmt, ...)
  26. {
  27.         char buff[USART3_REC_LEN+1];  //用于存放转换后的数据 [长度]
  28.         uint16_t i=0;
  29.         va_list arg_ptr;
  30.         va_start(arg_ptr, fmt);
  31.         vsnprintf(buff, USART3_REC_LEN+1, fmt, arg_ptr);//数据转换
  32.         i=strlen(buff);//得出数据长度
  33.         if(strlen(buff)>USART3_REC_LEN)i=USART3_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
  34.         WIFI_printf("AT+CIPSEND=%d\r\n",i);//先发送AT指令和数据数量
  35.         HAL_Delay(100);//等待WIFI模块返回">",此处没做返回是不是">"的判断。稳定性要求高的项目要另加判断。
  36.     HAL_UART_Transmit(&huart3,(uint8_t *)buff,i,0xffff);//发送数据内容(串口号,内容,数量,溢出时间)
  37.     va_end(arg_ptr);
  38. }
  39. //所有USART串口的中断回调函数HAL_UART_RxCpltCallback,统一存放在【usart.C】文件中。
复制代码
        在main.c文件添加WIFI通信实现代码,main.c部分内容如下:
  1. /* USER CODE END Header */
  2. /* Includes ------------------------------------------------------------------*/
  3. #include "main.h"
  4. #include "usart.h"
  5. #include "gpio.h"
  6. /* Private includes ----------------------------------------------------------*/
  7. /* USER CODE BEGIN Includes */
  8. //用户编写1
  9. #include "../../ICore/key.h"
  10. #include "../../ICore/led.h"
  11. #include "../../ICore/print.h"
  12. #include "../../ICore/usart.h"   //添加串口usart3接收回调实现的头文件
  13. #include "../../ICore/wifi.h"    //添加串口usart3写入数据实现的头文件
  14. /* USER CODE END Includes */
  15. /* Private typedef -----------------------------------------------------------*/
  16. /* USER CODE BEGIN PTD */
  17. /* USER CODE END PTD */
  18. /* Private define ------------------------------------------------------------*/
  19. /* USER CODE BEGIN PD */
  20. /* USER CODE END PD */
  21. /* Private macro -------------------------------------------------------------*/
  22. /* USER CODE BEGIN PM */
  23. /* USER CODE END PM */
  24. /* Private variables ---------------------------------------------------------*/
  25. /* USER CODE BEGIN PV */
  26. /* USER CODE END PV */
  27. /* Private function prototypes -----------------------------------------------*/
  28. void SystemClock_Config(void);
  29. /* USER CODE BEGIN PFP */
  30. /* USER CODE END PFP */
  31. /* Private user code ---------------------------------------------------------*/
  32. /* USER CODE BEGIN 0 */
  33. /* USER CODE END 0 */
  34. /**
  35.   * @brief  The application entry point.
  36.   * @retval int
  37.   */
  38. int main(void)
  39. {
  40.   /* USER CODE BEGIN 1 */
  41.   /* USER CODE END 1 */
  42.   /* MCU Configuration--------------------------------------------------------*/
  43.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  44.   HAL_Init();
  45.   /* USER CODE BEGIN Init */
  46.   /* USER CODE END Init */
  47.   /* Configure the system clock */
  48.   SystemClock_Config();
  49.   /* USER CODE BEGIN SysInit */
  50.   /* USER CODE END SysInit */
  51.   /* Initialize all configured peripherals */
  52.   MX_GPIO_Init();
  53.   MX_LPUART1_UART_Init();
  54.   MX_USART3_UART_Init();
  55.   /* USER CODE BEGIN 2 */
  56.   //用户编写2
  57.   ResetPrintInit(&hlpuart1);
  58.   HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断
  59.   HLPUSART_RX_STA = 0;
  60.   HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData, 1); //usart3开启接收中断
  61.   USART3_RX_STA = 0;
  62.   set_led0_val(0);
  63.   set_led1_val(get_key0_val());
  64.   /* USER CODE END 2 */
  65.   /* Infinite loop */
  66.   /* USER CODE BEGIN WHILE */
  67.   while (1)
  68.   {
  69.     //用户编写3
  70.         //接收到电脑发送给(lpusart)数据,转身将其发送到给usart3,进而实现送数据给WIFI模块
  71.                 if(HLPUSART_RX_STA&0xC000){//溢出或换行,重新开始
  72.                         WIFI_printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);
  73.                         HLPUSART_RX_STA=0;//接收错误,重新开始
  74.                         HAL_Delay(100);//等待
  75.                 }
  76.         //接收到WIFI模块发送给(usart3)数据,转身将其发送到给lpusart,进而实现送数据给电脑终端
  77.                 if(USART3_RX_STA&0xC000){//溢出或换行,重新开始
  78.                         printf("%.*s\r\n", USART3_RX_STA&0X0FFF, USART3_RX_BUF);
  79.                         USART3_RX_STA=0;//接收错误,重新开始
  80.                         HAL_Delay(100);//等待
  81.                 }
  82.     /*
  83.           if(KEY_0())//按下KEY0判断
  84.           {
  85.                   printf("KEY0被按下\r\n");
  86.                   WIFI_printf("AT+UARTE?\r\n");//发送AT指令
  87.                   HAL_Delay(100);//等待
  88.           }
  89.     */
  90.     /* USER CODE END WHILE */
  91.     /* USER CODE BEGIN 3 */
  92.   }
  93.   /* USER CODE END 3 */
  94. }
复制代码
三、编译及测试        点击编译及运行按钮, 76edc5d8973a4353a22d862a1dfee32d.png          如果编译及下载无异常,采用串口助手连接开发板,本文将开发板作为Station 模式连接家里的路由,设置账号密码及查询是否成功: 13c125dce2994d678897f00375ed1584.png 32e595f3a73b486cad08a7610c64d993.png 测试运行结果如下: f072771e64914b50822fc3c2ea7f3d69.png          访问家里的路由控制界面查看如下: 9f85f15d0244403c892a10888c57089e.png 四、关于WIFI模块的串口应用        通过上面的实现,市面上大部分WIFI模块都能适用。只要AT指令能直达WIFI模块,无论是从MCU还是从电脑端,对于WIFI模块的操作就是看AT指令支持的情况及我们对AT指令的组合应用,可以实现项目开发中各种对WIFI使用的要求。当然在具体项目中,对于WIFI模块的选型就是看他们WIFI模块给的AT指令能否直接或间接组合满足项目要求。        2022-11-21补充下面给出MW31模块的AT指令及部分测试演示。【1】基础指令 af4cbd13f84745a3b15f7bb142e14752.png 【2】UASRT管理 af80a59911fd4c6c94e53ba7a7d112a8.png 【3】WIFI管理 8d5c8728a246406b9164db1e34567c0a.png 【4】 TCP/UDP通信 cddaa4defdc34eb9873462285de9c5dd.png 关键指令测试演示:1)部分查询指令测试: d7ba28f8276a4277a45494ba9b0b071d.png 2)部分TCP通信测试 9b88cbf6c5004792868123d7eed75895.png ————————————————版权声明:py_free-物联智能如有侵权请联系删除
收藏 评论0 发布时间:2023-4-7 15:08

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版