• STM32物联网(封装AT指令进行TCP连接及数据的接收和发送)



    前言

    本篇文章将继续带大家学习STM32物联网,那么在这篇文章中将会封装对应AT指令操作的函数来进行WIFI连接以及TCP的连接。

    一、AT指令函数封装

    1.向ESP8266发送数据函数

    我们需要封装一个函数来给ESP8266发送AT指令。

    ESP8266连接到了开发板的串口3,实验直接使用HAL_UART_Transmit来向串口3发送数据即可。

    //发送命令给ESP8266
    void ESP8266_SendCommand(const char* command)
    {
    	HAL_UART_Transmit(&huart3, (uint8_t *)command, strlen(command), 10000);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.设置ESP8266工作模式

    设置wifi模式的指令:
    在这里插入图片描述

    直接使用封装好的函数进行连接即可。

    ESP8266_SendCommand("AT+CWMODE=3\r\n");
    
    • 1

    3.连接WIFI函数

    连接wifi函数如下:
    在这里插入图片描述

    //连接wifi
    void ESP8266_ConnectWiFi(const char* ssid, const char* pass) 
    {
      char cmd[100];
      
      // 发送命令:AT+CWJAP="YourWiFiSSID","YourWiFiPassword"
      sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, pass);
      ESP8266_SendCommand(cmd);  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    函数的输入是 Wi-Fi 网络的 SSID 和密码。这些参数是指向 char 数组的指针。ssid 是要连接的 Wi-Fi 网络的 SSID (Service Set Identifier),而 pass 则是该 Wi-Fi 网络的密码。

    首先,该函数声明了一个长度为100的字符数组 cmd 用于存储最终发送到 ESP8266 模块的 AT 命令。

    使用 sprintf 函数将 Wi-Fi SSID 和密码拼接到一个格式化的字符串中,这个字符串是一个包含了 Wi-Fi SSID 和密码的 AT 命令,格式为 “AT+CWJAP=“SSID”,“PASSWORD”\r\n”,其中 “SSID” 和 “PASSWORD” 部分会被传入的 ssid 和 pass 替换。

    最后,将格式化后的 AT 命令通过 ESP8266_SendCommand 函数发送给 ESP8266 模块,使其连接到指定的 Wi-Fi 网络。

    4.查询IP地址

    查询IP地址指令如下:

    在这里插入图片描述

    ESP8266_SendCommand("AT+CIFSR\r\n");//查询AP地址
    
    • 1

    5.连接TCP服务器

    下面是连接TCP连接的代码:
    在这里插入图片描述

    //连接TCP服务器
    void ESP8266_ConnectTCPServer(const char* ServerIP, int ServerPort)
    {
    	// 定义一个缓冲区用于存储命令字符串
    	char cmd[100];
    
    	// 发送连接到TCP服务器的命令
    	// 例如:AT+CIPSTART="TCP","192.168.1.100",80
    	sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ServerIP, ServerPort);
    	ESP8266_SendCommand(cmd);	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    函数的输入参数是 ServerIP 和 ServerPort。ServerIP 是要连接的服务器的 IP 地址,以字符串形式传入。ServerPort 是服务器的端口号,以整数形式传入。

    首先,函数声明了一个长度为 100 的字符数组 cmd,用于存储最终发送到 ESP8266 模块的 AT 命令。

    使用 sprintf 函数将服务器的 IP 地址和端口号拼接到一个格式化的字符串中,形成一个 AT 命令,格式为 “AT+CIPSTART=“TCP”,“ServerIP”,ServerPort\r\n”,其中 “ServerIP” 和 ServerPort 部分会被传入的 ServerIP 和 ServerPort 替换。

    最后,将格式化后的 AT 命令通过 ESP8266_SendCommand 函数发送给 ESP8266 模块,以连接到指定的 TCP 服务器。

    6.发送数据到TCP服务器

    下面是发送数据到TCP服务器的函数:
    在这里插入图片描述

    //发送数据到TCP服务器
    void ESP8266_SendToTCPServer(const char* txData)
    {
        // 发送命令:AT+CIPSEND=
        char cmd[100];
        sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(txData));
        ESP8266_SendCommand(cmd);
        HAL_Delay(100);
        // 发送数据
        ESP8266_SendCommand(txData);	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    7.接收并解析来自TCP服务器的数据

    uint8_t esp8266_rxbuf[RECVBUFSIZE] = {0};//用于保存ESP8266发来的数据
    
    //空闲中断回调函数
    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
    {
    	if(huart->Instance == USART3)
    	{		
    		printf("%s", esp8266_rxbuf);
    		ESP8266_PraseToTCPServer((const char*)esp8266_rxbuf);
    		memset(esp8266_rxbuf, 0, sizeof(esp8266_rxbuf));//清空接收到的数据
    		HAL_UARTEx_ReceiveToIdle_DMA(&huart3, esp8266_rxbuf, RECVBUFSIZE);
    	}
    }
    
    //解析ESP8266接收到的TCP数据
    void ESP8266_PraseToTCPServer(const char* rxdata)
    {
    		//检查数据中是否含有IPD
        char *ipdPtr = strstr(rxdata, "IPD");
        if (ipdPtr != NULL)
    		{
    			// 找到消息内容的起始位置
    			char *ptr = strstr(rxdata, ":");
    			if (ptr != NULL) 
    			{
    					char* message = ptr + 1;
    					printf("\r\n.....................\r\n");
    					printf("recvmsg : %s\r\n", message);
    					printf(".....................");
    			}
    		}			
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    uint8_t esp8266_rxbuf[RECVBUFSIZE] = {0};: 定义了一个长度为 RECVBUFSIZE 的缓冲区 esp8266_rxbuf,用于保存 ESP8266 模块接收到的数据。

    void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size): 这是一个空闲中断回调函数。当 UART 接收到足够数量的数据后,会触发空闲中断,进入这个回调函数。在这个回调函数中,首先检查 huart->Instance 是否为 USART3,以确保是与 ESP8266 通信的 UART。然后,通过 printf(“%s”, esp8266_rxbuf); 打印接收到的数据,接着调用 ESP8266_PraseToTCPServer 函数对接收到的数据进行解析,最后通过 memset 清空接收缓冲区,准备接收下一次的数据。

    void ESP8266_PraseToTCPServer(const char* rxdata): 这个函数用于解析从 TCP 服务器接收到的数据。首先,通过 strstr 函数检查数据中是否包含 “IPD”,表示接收到了一个 TCP 数据包。如果找到了 “IPD”,则继续寻找 “:”,找到消息内容的起始位置。接着,通过 printf 打印接收到的消息内容。

    8.关闭TCP服务器

    下面是关闭TCP服务器的AT指令:
    在这里插入图片描述

    //关闭TCP服务
    void ESP8266_CLOSETCP(void)
    {
    	ESP8266_SendCommand("AT+CIPCLOSE\r\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、代码测试

    先使用手机开一个热点,这个热点要是2.4GHZ的频段。

    让STM32 通过ESP8266连接到手机热点,让电脑也连接到手机热点,让他们处于同一个局域网下。然后就可以让STM32作为客户端和电脑建立TCP连接进行数据之间的通信。
    在这里插入图片描述
    开启TCP服务器:

    在这里插入图片描述
    将代码烧录到ESP8266中:
    在这里插入图片描述

    测试结果表明可以进行正常的数据收发。
    在这里插入图片描述

    总结

    本篇文章就讲解到这里,下篇文章将带大家继续学习。

  • 相关阅读:
    未在本地计算机上注册“Microsoft .ACE. OLEDB .12.0”提供程序
    使用CLion和gdb server debug haproxy
    ubuntu用户与用户组管理
    Ip地址基础--全篇无废话
    Feign调用异常触发降级捕获异常
    html网页如何获取后台数据库的数据(html + ajax + php + mysql)
    面试题 17.04. 消失的数字
    【图像分割】基于神经气体网络的图像分割与量化(Matlab代码实现)
    Docker打包深度学习项目
    云IDE 使用体验,git项目快速启动实践
  • 原文地址:https://blog.csdn.net/m0_49476241/article/details/136243745