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

文章目录


前言

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

一、AT指令函数封装

1.向ESP8266发送数据函数

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

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

c 复制代码
//发送命令给ESP8266
void ESP8266_SendCommand(const char* command)
{
	HAL_UART_Transmit(&huart3, (uint8_t *)command, strlen(command), 10000);
}

2.设置ESP8266工作模式

设置wifi模式的指令:

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

c 复制代码
ESP8266_SendCommand("AT+CWMODE=3\r\n");

3.连接WIFI函数

连接wifi函数如下:

c 复制代码
//连接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);  
}

函数的输入是 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地址指令如下:

c 复制代码
ESP8266_SendCommand("AT+CIFSR\r\n");//查询AP地址

5.连接TCP服务器

下面是连接TCP连接的代码:

c 复制代码
//连接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);	
}

函数的输入参数是 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服务器的函数:

c 复制代码
//发送数据到TCP服务器
void ESP8266_SendToTCPServer(const char* txData)
{
    // 发送命令:AT+CIPSEND=<length>
    char cmd[100];
    sprintf(cmd, "AT+CIPSEND=%d\r\n", strlen(txData));
    ESP8266_SendCommand(cmd);
    HAL_Delay(100);
    // 发送数据
    ESP8266_SendCommand(txData);	
}

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

c 复制代码
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(".....................");
			}
		}			
}

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指令:

c 复制代码
//关闭TCP服务
void ESP8266_CLOSETCP(void)
{
	ESP8266_SendCommand("AT+CIPCLOSE\r\n");
}

二、代码测试

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

让STM32 通过ESP8266连接到手机热点,让电脑也连接到手机热点,让他们处于同一个局域网下。然后就可以让STM32作为客户端和电脑建立TCP连接进行数据之间的通信。

开启TCP服务器:

将代码烧录到ESP8266中:

测试结果表明可以进行正常的数据收发。

总结

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

相关推荐
趙小贞1 小时前
UART 串口协议详解与 STM32 实战实现
stm32·单片机·嵌入式硬件·通信协议·1024程序员节
xyx-3v1 小时前
STM32F1和STM32F4在配置硬件SPI1时有什么不同?
stm32·单片机·嵌入式硬件
TDengine (老段)2 小时前
TDengine 数据函数 ROUND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·1024程序员节
TDengine (老段)2 小时前
TDengine 数学函数 RAND 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
宁静致远20213 小时前
STM32之TM1638数码管及键盘驱动
stm32·嵌入式
小莞尔3 小时前
【51单片机】【protues仿真】基于51单片机智能温控风扇系统
c语言·单片机·嵌入式硬件·物联网·51单片机·1024程序员节
hazy1k3 小时前
51单片机基础-DS18B20温度传感器
c语言·stm32·单片机·嵌入式硬件·51单片机·1024程序员节
代码不停4 小时前
网络 UDP 和 TCP / IP详细介绍
网络·网络协议·tcp/ip·udp·1024程序员节
集芯微电科技有限公司4 小时前
替代HT1621B液晶驱动显示模块芯片程序演示
stm32·单片机·嵌入式硬件
GIS数据转换器4 小时前
城市基础设施安全运行监管平台
大数据·运维·人工智能·物联网·安全·无人机·1024程序员节