嵌入式Linux开发板测试esp8266模块

news/2024/10/22 18:42:30/

一、介绍

  ESP8266是一款流行的Wi-Fi微控制器,通常用于物联网项目中。在嵌入式Linux开发板上使用C语言开发ESP8266,意味着我们将通过串口或其他通信方式,从Linux系统上发送AT指令来控制ESP8266。AT指令集是一种用于控制调制解调器和其他设备的标准命令集,ESP8266也支持AT指令集。

二、测试环境

硬件:

  1. 嵌入式Linux开发板
  2. ESP8266开发板

三、测试代码

  以下是一个简单的C语言测试代码示例,用于在嵌入式Linux开发板上通过串口发送AT指令来控制ESP8266,并测试其Wi-Fi连接功能。

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <termios.h>  #define SERIAL_DEVICE "/dev/ttyS0" // 根据您的实际串口设备名称进行修改  
#define BAUD_RATE B115200 // 设置串口波特率  int main() {  int serial_fd;  struct termios tty;  char buffer[256];  int bytes_read;  // 打开串口设备  serial_fd = open(SERIAL_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);  if (serial_fd < 0) {  perror("Error opening serial port");  return 1;  }  // 配置串口属性  memset(&tty, 0, sizeof(tty));  if (tcgetattr(serial_fd, &tty) != 0) {  perror("Error getting serial attributes");  return 1;  }  cfsetispeed(&tty, BAUD_RATE);  cfsetospeed(&tty, BAUD_RATE);  tty.c_cflag |= (CLOCAL | CREAD);  tty.c_cflag &= ~PARENB;  tty.c_cflag &= ~CSTOPB;  tty.c_cflag &= ~CSIZE;  tty.c_cflag |= CS8;  tty.c_cflag &= ~CRTSCTS;  tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  tty.c_iflag &= ~(IXON | IXOFF | IXANY);  tty.c_oflag &= ~OPOST;  tty.c_cc[VMIN] = 1;  tty.c_cc[VTIME] = 0;  if (tcsetattr(serial_fd, TCSANOW, &tty) != 0) {  perror("Error setting serial attributes");  return 1;  }  // 发送AT指令测试ESP8266的Wi-Fi连接状态  strcpy(buffer, "AT+CWSTATUS\r\n");  write(serial_fd, buffer, strlen(buffer));  // 读取ESP8266的响应  sleep(1); // 等待ESP8266响应  bytes_read = read(serial_fd, buffer, sizeof(buffer) - 1);  if (bytes_read > 0) {  buffer[bytes_read] = '\0'; // 添加字符串结束符  printf("ESP8266 Response: %s", buffer);  // 根据响应内容判断Wi-Fi连接状态  if (strstr(buffer, "CONNECTED")) {  printf("Wi-Fi connected\n");  } else {  printf("Wi-Fi not connected\n");  }

或者
服务端测试
参考连接https://blog.csdn.net/Killer_M/article/details/122092836

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <termios.h>
#include <sys/select.h>#define REV_OK		0	//接收完成标志
#define REV_WAIT	1	//接收未完成标志
#define UART_BUF    128 // 串口缓冲区#define ESP8266_AP_INFO         "AT+CWSAP=\"ATK-8266\",\"12345678\",1,4\r\n"#define u8 unsigned charunsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
unsigned char buf[UART_BUF] = {0};/* 实现ms级延时 */
static void delay_xms(unsigned int secs)
{struct timeval tval;tval.tv_sec=secs/1000;tval.tv_usec=(secs*1000)%1000000;select(0,NULL,NULL,NULL,&tval);
}typedef struct uart_hardware_cfg {unsigned int baudrate;  /* 波特率 */unsigned char dbit;     /* 数据位 */char parity;    /* 奇偶校验 */unsigned char sbit; /* 停止位 */
}uart_cfg_t;static struct termios old_cfg; /* 用于保存终端的配置参数 */
static int fd; /* 串口终端对应的文件描述符 *//* 串口初始化 
打开串口文件描述符,即对应的串口终端的设备节点 */
static int uart_init(const char *device)
{/* 打开串口 *//* O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机 */fd = open(device, O_RDWR | O_NOCTTY); if (fd < 0){fprintf(stderr, "open error:%s:%s\n", device, strerror(errno));return -1;}/* 获取串口当前的配置参数 */if (0 > tcgetattr(fd, &old_cfg)) {fprintf(stderr, "tcgetattr error: %s\n", strerror(errno));close(fd);return -1;}return 0;
}/**** 串口配置** 参数cfg指向一个uart_cfg_t结构体对象**/
static int uart_cfg(const uart_cfg_t *cfg)
{struct termios new_cfg = {0};   //将new_cfg对象清零speed_t speed;/* 设置为原始模式 */cfmakeraw(&new_cfg);/* 使能接收 */new_cfg.c_cflag |= CREAD;/* 设置波特率 */switch (cfg->baudrate) {case 1200: speed = B1200;break;case 1800: speed = B1800;break;case 2400: speed = B2400;break;case 4800: speed = B4800;break;case 9600: speed = B9600;break;case 19200: speed = B19200;break;case 38400: speed = B38400;break;case 57600: speed = B57600;break;case 115200: speed = B115200;break;case 230400: speed = B230400;break;case 460800: speed = B460800;break;case 500000: speed = B500000;break;default:    //默认配置为115200speed = B115200;printf("default baud rate: 115200\n");break;}if (0 > cfsetspeed(&new_cfg, speed)) {fprintf(stderr, "cfsetspeed error: %s\n", strerror(errno));return -1;}/* 设置数据位大小 */new_cfg.c_cflag &= ~CSIZE;  //将数据位相关的比特位清零switch (cfg->dbit) {case 5:new_cfg.c_cflag |= CS5;break;case 6:new_cfg.c_cflag |= CS6;break;case 7:new_cfg.c_cflag |= CS7;break;case 8:new_cfg.c_cflag |= CS8;break;default:    //默认数据位大小为8new_cfg.c_cflag |= CS8;
//        printf("default data bit size: 8\n");break;}/* 设置奇偶校验 */switch (cfg->parity) {case 'N':       //无校验new_cfg.c_cflag &= ~PARENB;new_cfg.c_iflag &= ~INPCK;break;case 'O':       //奇校验new_cfg.c_cflag |= (PARODD | PARENB);new_cfg.c_iflag |= INPCK;break;case 'E':       //偶校验new_cfg.c_cflag |= PARENB;new_cfg.c_cflag &= ~PARODD; /* 清除PARODD标志,配置为偶校验 */new_cfg.c_iflag |= INPCK;break;default:    //默认配置为无校验new_cfg.c_cflag &= ~PARENB;new_cfg.c_iflag &= ~INPCK;
//        printf("default parity: N\n");break;}/* 设置停止位 */switch (cfg->sbit) {case 1:     //1个停止位new_cfg.c_cflag &= ~CSTOPB;break;case 2:     //2个停止位new_cfg.c_cflag |= CSTOPB;break;default:    //默认配置为1个停止位new_cfg.c_cflag &= ~CSTOPB;
//        printf("default stop bit size: 1\n");break;}/* 将MIN和TIME设置为0 */new_cfg.c_cc[VTIME] = 0;new_cfg.c_cc[VMIN] = 0;/* 清空缓冲区 */if (0 > tcflush(fd, TCIOFLUSH)) {fprintf(stderr, "tcflush error: %s\n", strerror(errno));return -1;}/* 写入配置、使配置生效 */if (0 > tcsetattr(fd, TCSANOW, &new_cfg)) {fprintf(stderr, "tcsetattr error: %s\n", strerror(errno));return -1;}/* 配置OK 退出 */return 0;
}/**** 信号处理函数,当串口有数据可读时,会跳转到该函数执行**/
static void io_handler(int sig, siginfo_t *info, void *context)
{if(SIGRTMIN != sig)return;/* 判断串口是否有数据可读 */if (POLL_IN == info->si_code) {if (esp8266_cnt >= sizeof(buf))esp8266_cnt = 0; //防止串口被刷爆esp8266_cnt = read(fd, buf, sizeof(buf));printf("%s\r\n", buf);}
}/**** 异步I/O初始化函数**/
static void async_io_init(void)
{struct sigaction sigatn;int flag;/* 使能异步I/O */flag = fcntl(fd, F_GETFL);  //使能串口的异步I/O功能flag |= O_ASYNC;fcntl(fd, F_SETFL, flag);/* 设置异步I/O的所有者 */fcntl(fd, F_SETOWN, getpid());/* 指定实时信号SIGRTMIN作为异步I/O通知信号 */fcntl(fd, F_SETSIG, SIGRTMIN);/* 为实时信号SIGRTMIN注册信号处理函数 */sigatn.sa_sigaction = io_handler;   //当串口有数据可读时,会跳转到io_handler函数sigatn.sa_flags = SA_SIGINFO;sigemptyset(&sigatn.sa_mask);sigaction(SIGRTMIN, &sigatn, NULL);
}void Uart4_Init(unsigned int baud, char *device)
{uart_cfg_t cfg = {0};if (NULL == device) {fprintf(stderr, "Error: the device no found!\n");exit(EXIT_FAILURE);}/* 串口初始化 */if (uart_init(device))exit(EXIT_FAILURE);/* 设置波特率 */cfg.baudrate = baud;/* 串口配置 */if (uart_cfg(&cfg)) {tcsetattr(fd, TCSANOW, &old_cfg);   //恢复到之前的配置close(fd);exit(EXIT_FAILURE);}
}//==========================================================
//	函数名称:	ESP8266_Clear
//
//	函数功能:	清空缓存
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_Clear(void)
{memset(buf, 0, sizeof(buf));esp8266_cnt = 0;
}//==========================================================
//	函数名称:	ESP8266_WaitRecive
//
//	函数功能:	等待接收完成
//
//	入口参数:	无
//
//	返回参数:	REV_OK-接收完成		REV_WAIT-接收超时未完成
//
//	说明:		循环调用检测是否接收完成
//==========================================================
_Bool ESP8266_WaitRecive(void)
{if(esp8266_cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数return REV_WAIT;if(esp8266_cnt == esp8266_cntPre)				//如果上一次的值和这次相同,则说明接收完毕{esp8266_cnt = 0;							//清0接收计数return REV_OK;								//返回接收完成标志}esp8266_cntPre = esp8266_cnt;					//置为相同return REV_WAIT;								//返回接收未完成标志}//==========================================================
//	函数名称:	ESP8266_SendCmd
//
//	函数功能:	发送命令
//
//	入口参数:	cmd:命令
//				res:需要检查的返回指令
//
//	返回参数:	0-成功	1-失败
//
//	说明:		
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{int ret = 0;unsigned char timeOut = 200;ret = write(fd, (unsigned char *)cmd, strlen((const char *)cmd));if (ret == 0)   printf("write err!\r\n");
//	printf("UartBuf:%s, Len:%d\r\n", buf, esp8266_cnt);while(timeOut--){if(ESP8266_WaitRecive() == REV_OK)							//如果收到数据{
//			printf("ESP8266_SendCmd Function:%s\r\n", buf);if(strstr((const char *)buf, res) != NULL)		//如果接收到的数据是在给定数据的范围内,则不为NULL{ESP8266_Clear();									//清空缓存return 0;}}delay_xms(10);//2s内让串口2中断函数循环接收到的数据}return 1;}//==========================================================
//	函数名称:	ESP8266_SendData
//
//	函数功能:	发送数据
//
//	入口参数:	data:数据
//				len:长度
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_SendData(unsigned char *data, unsigned short len)
{char cmdBuf[32];ESP8266_Clear();								//清空接收缓存sprintf(cmdBuf, "AT+CIPSEND=0,%d\r\n", len);		//发送命令if(!ESP8266_SendCmd(cmdBuf, ">"))				//收到‘>’时可以发送数据,改不得{write(fd, data, len);		//发送设备连接请求数据}}_Bool Esp8266_Init()
{ESP8266_Clear();printf("1. AT\r\n");while(ESP8266_SendCmd("AT\r\n", "OK"))delay_xms(500);printf("2. CWMODE\r\n");while(ESP8266_SendCmd("AT+CWMODE=2\r\n", "OK"))delay_xms(500);printf("2.1 AT+RST\r\n");while(ESP8266_SendCmd("AT+RST\r\n", "OK"))delay_xms(2000);printf("3. CWSAP\r\n");while(ESP8266_SendCmd(ESP8266_AP_INFO, "OK")){delay_xms(500);}printf("4. AT+CIPMUX\r\n");// 启动多连接while(ESP8266_SendCmd("AT+CIPMUX=1\r\n", "OK")){delay_xms(500);}printf("5. CIPSERVER\r\n");while(ESP8266_SendCmd("AT+CIPSERVER=1,8080\r\n", "OK"))delay_xms(500);printf("6. CIFSR\r\n");while(ESP8266_SendCmd("AT+CIFSR\r\n", "OK"))delay_xms(500);printf("6. ESP8266 Init OK\r\n");return 0;
}int main(int argc, char *argv[])
{u8 test_buf[] = "OSS迟早暴富^.^!";Uart4_Init(115200, argv[1]); // 初始化串口4async_io_init(); // 异步IO初始化,相当于STM32的外部中断配置的初始化,不过STM32下应该是硬件中断,这里是软件中断 while (Esp8266_Init()){printf("Esp8266 Init Failed!!!\r\n");}while (1){/* 通信测试 */if (strstr((const char*)buf, "AA")){ESP8266_SendData(test_buf,strlen(test_buf));ESP8266_Clear();}sleep(1);     }/* 退出 */tcsetattr(fd, TCSANOW, &old_cfg);   //恢复到之前的配置close(fd);exit(EXIT_SUCCESS);
}

客户端测试

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <termios.h>
#include <sys/select.h>#define REV_OK		0	//接收完成标志
#define REV_WAIT	1	//接收未完成标志
#define UART_BUF    128 // 串口缓冲区#define ESP8266_AP_INFO         "AT+CWSAP=\"ATK-8266\",\"12345678\",1,4\r\n"
#define ESP8266_JAP_INFO          "AT+CWJAP=\"TP-LINK_XXXX\",\"123456789\"\r\n"
#define ESP8266_TCP_SERVER_INFO "AT+CIPSTART=\"TCP\",\"192.168.1.181\",8080\r\n"#define u8 unsigned charunsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
unsigned char buf[UART_BUF] = {0};/* 实现ms级延时 */
static void delay_xms(unsigned int secs)
{struct timeval tval;tval.tv_sec=secs/1000;tval.tv_usec=(secs*1000)%1000000;select(0,NULL,NULL,NULL,&tval);
}typedef struct uart_hardware_cfg {unsigned int baudrate;  /* 波特率 */unsigned char dbit;     /* 数据位 */char parity;    /* 奇偶校验 */unsigned char sbit; /* 停止位 */
}uart_cfg_t;static struct termios old_cfg; /* 用于保存终端的配置参数 */
static int fd; /* 串口终端对应的文件描述符 *//* 串口初始化 
打开串口文件描述符,即对应的串口终端的设备节点 */
static int uart_init(const char *device)
{/* 打开串口 *//* O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机 */fd = open(device, O_RDWR | O_NOCTTY); if (fd < 0){fprintf(stderr, "open error:%s:%s\n", device, strerror(errno));return -1;}/* 获取串口当前的配置参数 */if (0 > tcgetattr(fd, &old_cfg)) {fprintf(stderr, "tcgetattr error: %s\n", strerror(errno));close(fd);return -1;}return 0;
}/**** 串口配置** 参数cfg指向一个uart_cfg_t结构体对象**/
static int uart_cfg(const uart_cfg_t *cfg)
{struct termios new_cfg = {0};   //将new_cfg对象清零speed_t speed;/* 设置为原始模式 */cfmakeraw(&new_cfg);/* 使能接收 */new_cfg.c_cflag |= CREAD;/* 设置波特率 */switch (cfg->baudrate) {case 1200: speed = B1200;break;case 1800: speed = B1800;break;case 2400: speed = B2400;break;case 4800: speed = B4800;break;case 9600: speed = B9600;break;case 19200: speed = B19200;break;case 38400: speed = B38400;break;case 57600: speed = B57600;break;case 115200: speed = B115200;break;case 230400: speed = B230400;break;case 460800: speed = B460800;break;case 500000: speed = B500000;break;default:    //默认配置为115200speed = B115200;printf("default baud rate: 115200\n");break;}if (0 > cfsetspeed(&new_cfg, speed)) {fprintf(stderr, "cfsetspeed error: %s\n", strerror(errno));return -1;}/* 设置数据位大小 */new_cfg.c_cflag &= ~CSIZE;  //将数据位相关的比特位清零switch (cfg->dbit) {case 5:new_cfg.c_cflag |= CS5;break;case 6:new_cfg.c_cflag |= CS6;break;case 7:new_cfg.c_cflag |= CS7;break;case 8:new_cfg.c_cflag |= CS8;break;default:    //默认数据位大小为8new_cfg.c_cflag |= CS8;
//        printf("default data bit size: 8\n");break;}/* 设置奇偶校验 */switch (cfg->parity) {case 'N':       //无校验new_cfg.c_cflag &= ~PARENB;new_cfg.c_iflag &= ~INPCK;break;case 'O':       //奇校验new_cfg.c_cflag |= (PARODD | PARENB);new_cfg.c_iflag |= INPCK;break;case 'E':       //偶校验new_cfg.c_cflag |= PARENB;new_cfg.c_cflag &= ~PARODD; /* 清除PARODD标志,配置为偶校验 */new_cfg.c_iflag |= INPCK;break;default:    //默认配置为无校验new_cfg.c_cflag &= ~PARENB;new_cfg.c_iflag &= ~INPCK;
//        printf("default parity: N\n");break;}/* 设置停止位 */switch (cfg->sbit) {case 1:     //1个停止位new_cfg.c_cflag &= ~CSTOPB;break;case 2:     //2个停止位new_cfg.c_cflag |= CSTOPB;break;default:    //默认配置为1个停止位new_cfg.c_cflag &= ~CSTOPB;
//        printf("default stop bit size: 1\n");break;}/* 将MIN和TIME设置为0 */new_cfg.c_cc[VTIME] = 0;new_cfg.c_cc[VMIN] = 0;/* 清空缓冲区 */if (0 > tcflush(fd, TCIOFLUSH)) {fprintf(stderr, "tcflush error: %s\n", strerror(errno));return -1;}/* 写入配置、使配置生效 */if (0 > tcsetattr(fd, TCSANOW, &new_cfg)) {fprintf(stderr, "tcsetattr error: %s\n", strerror(errno));return -1;}/* 配置OK 退出 */return 0;
}//==========================================================
//	函数名称:	ESP8266_Clear
//
//	函数功能:	清空缓存
//
//	入口参数:	无
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_Clear(void)
{memset(buf, 0, sizeof(buf));esp8266_cnt = 0;
}/**** 信号处理函数,当串口有数据可读时,会跳转到该函数执行**/
static void io_handler(int sig, siginfo_t *info, void *context)
{if(SIGRTMIN != sig)return;/* 判断串口是否有数据可读 */if (POLL_IN == info->si_code) {if (esp8266_cnt >= sizeof(buf)){// esp8266_cnt = 0; //防止串口被刷爆// memset(buf,0,sizeof(buf));ESP8266_Clear();}esp8266_cnt = read(fd, buf+esp8266_cnt, sizeof(buf)-esp8266_cnt);printf("esp8266_cnt=%d\r\n", esp8266_cnt);printf("io_handler=%s\r\n", buf);}
}/**** 异步I/O初始化函数**/
static void async_io_init(void)
{struct sigaction sigatn;int flag;/* 使能异步I/O */flag = fcntl(fd, F_GETFL);  //使能串口的异步I/O功能flag |= O_ASYNC;fcntl(fd, F_SETFL, flag);/* 设置异步I/O的所有者 */fcntl(fd, F_SETOWN, getpid());/* 指定实时信号SIGRTMIN作为异步I/O通知信号 */fcntl(fd, F_SETSIG, SIGRTMIN);/* 为实时信号SIGRTMIN注册信号处理函数 */sigatn.sa_sigaction = io_handler;   //当串口有数据可读时,会跳转到io_handler函数sigatn.sa_flags = SA_SIGINFO;sigemptyset(&sigatn.sa_mask);sigaction(SIGRTMIN, &sigatn, NULL);
}void Uart4_Init(unsigned int baud, char *device)
{uart_cfg_t cfg = {0};if (NULL == device) {fprintf(stderr, "Error: the device no found!\n");exit(EXIT_FAILURE);}/* 串口初始化 */if (uart_init(device))exit(EXIT_FAILURE);/* 设置波特率 */cfg.baudrate = baud;/* 串口配置 */if (uart_cfg(&cfg)) {tcsetattr(fd, TCSANOW, &old_cfg);   //恢复到之前的配置close(fd);exit(EXIT_FAILURE);}
}void Uart5_Init(unsigned int baud, char *device)
{uart_cfg_t cfg = {0};if (NULL == device) {fprintf(stderr, "Error: the device no found!\n");exit(EXIT_FAILURE);}/* 串口初始化 */if (uart_init(device))exit(EXIT_FAILURE);/* 设置波特率 */cfg.baudrate = baud;/* 串口配置 */if (uart_cfg(&cfg)) {tcsetattr(fd, TCSANOW, &old_cfg);   //恢复到之前的配置close(fd);exit(EXIT_FAILURE);}
}//==========================================================
//	函数名称:	ESP8266_WaitRecive
//
//	函数功能:	等待接收完成
//
//	入口参数:	无
//
//	返回参数:	REV_OK-接收完成		REV_WAIT-接收超时未完成
//
//	说明:		循环调用检测是否接收完成
//==========================================================
_Bool ESP8266_WaitRecive(void)
{if(esp8266_cnt == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数return REV_WAIT;if(esp8266_cnt == esp8266_cntPre)				//如果上一次的值和这次相同,则说明接收完毕{esp8266_cnt = 0;							//清0接收计数return REV_OK;								//返回接收完成标志}esp8266_cntPre = esp8266_cnt;					//置为相同return REV_WAIT;								//返回接收未完成标志}//==========================================================
//	函数名称:	ESP8266_SendCmd
//
//	函数功能:	发送命令
//
//	入口参数:	cmd:命令
//				res:需要检查的返回指令
//
//	返回参数:	0-成功	1-失败
//
//	说明:		
//==========================================================
_Bool ESP8266_SendCmd(char *cmd, char *res)
{int ret = 0;unsigned char timeOut = 200;ret = write(fd, (unsigned char *)cmd, strlen((const char *)cmd));if (ret == 0)   printf("write err!\r\n");
//	printf("UartBuf:%s, Len:%d\r\n", buf, esp8266_cnt);while(timeOut--){if(ESP8266_WaitRecive() == REV_OK)							//如果收到数据{
//			printf("ESP8266_SendCmd Function:%s\r\n", buf);if(strstr((const char *)buf, res) != NULL)		//如果接收到的数据是在给定数据的范围内,则不为NULL{ESP8266_Clear();									//清空缓存return 0;}}delay_xms(10);//2s内让串口2中断函数循环接收到的数据}return 1;}//==========================================================
//	函数名称:	ESP8266_SendData
//
//	函数功能:	发送数据
//
//	入口参数:	data:数据
//				len:长度
//
//	返回参数:	无
//
//	说明:		
//==========================================================
void ESP8266_SendData(unsigned char *data, unsigned short len)
{char cmdBuf[32];ESP8266_Clear();								//清空接收缓存// sprintf(cmdBuf, "AT+CIPSEND=0,%d\r\n", len);		//发送命令  多连接sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);		//发送命令  单连接if(!ESP8266_SendCmd(cmdBuf, ">"))				//收到‘>’时可以发送数据,改不得{write(fd, data, len);		//发送设备连接请求数据}}_Bool Esp8266_Init()
{ESP8266_Clear();printf("1. AT\r\n");while(ESP8266_SendCmd("AT\r\n", "OK"))delay_xms(500);printf("2. CWMODE\r\n");while(ESP8266_SendCmd("AT+CWMODE=2\r\n", "OK"))delay_xms(500);printf("2.1 AT+RST\r\n");while(ESP8266_SendCmd("AT+RST\r\n", "OK"))delay_xms(2000);printf("3. CWSAP\r\n");while(ESP8266_SendCmd(ESP8266_AP_INFO, "OK")){delay_xms(500);}printf("4. AT+CIPMUX\r\n");// 启动多连接while(ESP8266_SendCmd("AT+CIPMUX=1\r\n", "OK")){delay_xms(500);}printf("5. CIPSERVER\r\n");while(ESP8266_SendCmd("AT+CIPSERVER=1,8080\r\n", "OK"))delay_xms(500);printf("6. CIFSR\r\n");while(ESP8266_SendCmd("AT+CIFSR\r\n", "OK"))delay_xms(500);printf("6. ESP8266 Init OK\r\n");return 0;
}
_Bool Esp8266_Init_One_TCP_Client()
{ESP8266_Clear();printf("1. CWMODE\r\n");while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))delay_xms(5000);// printf("1.1 CWDHCP\r\n");// while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))// 		delay_xms(5000);printf("1.1 CIPSTA\r\n");while(ESP8266_SendCmd("AT+CIPSTA=\"192.168.1.87\",\"192.168.1.1\",\"255.255.255.0\"\r\n", "OK"))delay_xms(5000);//printf("2. CWJAP\r\n");while(ESP8266_SendCmd(ESP8266_JAP_INFO, "OK"))//WIFI CONNECTED ;// OKdelay_xms(5000*10);// printf("2.1 AT+RST\r\n");// while(ESP8266_SendCmd("AT+RST\r\n", "OK"))// 		delay_xms(20000);printf("3. CIFSR\r\n");while(ESP8266_SendCmd("AT+CIFSR\r\n", "OK"))delay_xms(5000);printf("4. CIPSTART\r\n");while(ESP8266_SendCmd(ESP8266_TCP_SERVER_INFO, "ERROR")==0)delay_xms(5000*10);printf("4. ESP8266 Init OK\r\n");return 0;
}int main(int argc, char *argv[])
{u8 test_buf[] = "esp8266 $$$$$!\r\n";// Uart4_Init(115200, argv[1]); // 初始化串口4Uart5_Init(115200, argv[1]); // 初始化串口5async_io_init(); // 异步IO初始化,相当于STM32的外部中断配置的初始化,不过STM32下应该是硬件中断,这里是软件中断 // while (Esp8266_Init())// {//     printf("Esp8266 Init Failed!!!\r\n");// }while (Esp8266_Init_One_TCP_Client()){printf("Esp8266 Init Failed!!!\r\n");}while (1){/* 通信测试 */if (strstr((const char*)buf, "AA")){ESP8266_SendData(test_buf,strlen(test_buf));ESP8266_Clear();}else if(strstr((const char*)buf, "end")){sleep(1); ESP8266_Clear();break;}sleep(1);     }/* 退出 */tcsetattr(fd, TCSANOW, &old_cfg);   //恢复到之前的配置close(fd);exit(EXIT_SUCCESS);
}

测试结果
打开网络服务器
在这里插入图片描述
启动测试程序,进行连接
在这里插入图片描述
通信测试
在这里插入图片描述

注意:
由于模块的版本不同,测试应根据固件的实际情况进行修改。


http://www.ppmy.cn/news/1372466.html

相关文章

MySql--死锁

一、什么是mysql死锁? MySQL中的死锁是指多个事务同时请求对同一资源进行操作(读或写),并且由于资源被互斥地锁定,导致彼此无法继续进行。当发生死锁时,MySQL会自动选择其中一个事务作为死锁的牺牲者,回滚该事务,并释放锁定的资源,从而解除死锁。 以下是一些处理MyS…

常见的几种httpclient

工作是spring 项目一般都是使用ResTemplate 但是还是有些项目中会用到httpClient&#xff0c;没有毛用。 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> …

Git 如何上传本地的所有分支

Git 如何上传本地的所有分支 比如一个本地 git 仓库里定义了两个远程分支&#xff0c;一个名为 origin&#xff0c; 一个名为 web 现在本地有一些分支是 web 远程仓库没有的分支&#xff0c;如何将本地所有分支都推送到 web 这个远程仓库上呢 git push web --all

WordPress 从入门到精通【设置 WordPress】

前言&#xff1a;为方便演示&#xff0c;前几张图使用 Playground 环境截取 如果你还不会部署WordPress&#xff0c;请看下面的链接并使用雨云可视化构建一个WordPress站点&#xff1a; 超简单EP面板搭建WordPress网站教程 - 风屿岛 10 (biliwind.com) 进入仪表盘 在搭建完…

JAVA中YML:几个用法

项目有一些配置文件&#xff0c;ini、prop类型的配置文件都考虑过后&#xff0c;还是选择yml文件&#xff0c;如上图&#xff1a;xxconfig.yml。 要求&#xff1a; 1、允许实施人员手动配置 2、配置文件要能轻便的转化为一个JAVA对象 3、程序启动后&#xff0c;打印这些配置项&…

自然语言处理之语言模型(LM)介绍

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;的一个重要分支&#xff0c;它旨在使计算机能够理解、解释和生成人类语言。在自然语言处理中&#xff0c;语言模型&…

【项目】Boost 搜索引擎

文章目录 1.背景2.宏观原理3.相关技术与开发环境4. 实现原理1.下载2.加载与解析文件2.1获取指定目录下的所有网页文件2.2. 获取网页文件中的关键信息2.3. 对读取文件进行保存 3.索引3.1正排与倒排3.2获取正排和倒排索引3.3建立索引3.3.1正排索引3.3.2倒排索引 4.搜索4.1 初始化…

【动态规划入门】最长上升子序列

每日一道算法题之最长上升子序列 一、题目描述二、思路三、C代码 一、题目描述 题目来源:LeetCode 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 输入格式 第一行包含整数 N。 第二行包含 N个整数&#xff0c;表示完整序列。 输出格式 输出一个整数…