在嵌入式开发中,无线通讯的办法有很多,其间 WIFI 是绕不开的话题。说到 WIFI 通讯,就不得不提 ESP8266了。

ESP8266 是一款高性能的 WIFI 串口模块,完结通明传输。只要有必定的串口知识,不需求知道 WIFI 原理就能够上手,在业内运用广泛。

1. 源码下载

本文首发 良许嵌入式网www.lxlinux.net/e/ ,欢迎重视!

本文所触及的源码及装置包如下(因为平台约束,请点击以下链接阅览原文下载):

www.lxlinux.net/e/stm32/esp…

  • STM32F103C8T6模板工程

  • 本文的源码

  • 串口调试帮手

  • 网络调试帮手

  • CH340驱动

假如不知道怎么树立 STM32 编程环境,不知道怎么烧录 STM32 代码,能够阅览这篇文章:

www.lxlinux.net/e/stm32/stm…

假如你连代码都不知道怎么烧录到 STM32 的,能够参阅下文,供给了 5 种代码烧录办法:

www.lxlinux.net/e/stm32/fiv…

文中所运用的芯片是 STM32F103C8T6 ,配套了一个工程模板,假如你需求自己树立一个工程模板,能够参阅下文:

www.lxlinux.net/e/stm32/cre…

2. ESP8266介绍

ESP8266 是一个十分强大的 WIFI 模块,能够运用串口与单片机进行通讯,然后编程完结操控 ESP8266。运用 ESP8266 能够拜访一些 API,获取气候信息或许完结网络授时,也能够衔接云平台进行开发。不过因为是串口传输,速度较慢,不能用来传输图像、视频这些大容量的数据,可是传些传感器数据仍是捉襟见肘的。

咱们常说的 ESP8266 是指 ESP8266 WIFI 模块,它是物联网和嵌入式开发常用的模块,其间 ESP8266 是 WIFI 模块的芯片型号。

ESP8266 有 ESP-01/01S/07/07S/12E/12F/12S 等标准,还有正点原子自研的 ATK-ESP8266 (修正了固件及模组引脚)。

本文用到的是 ESP-01S,长下面这样。这种模组十分廉价,某宝几块钱一个,建议能够买几个囤着。

手把手教你玩转ESP8266(原理+驱动)

3. 三种调试办法

ESP8266 现已是一款很老练的模组了,前文说到,它能够经过串口进行通讯。

已然能够进行串口通讯,那么咱们就能够运用以下三种办法进行调试。

  • USB 转 TTL 东西

这玩意儿咱们应该十分熟悉了,一般咱们用它来打印单片机 log。

当然,合作上位机(比方串口调试帮手),咱们也能够运用它对一些模组进行调试,比方:ESP8266、4G模组、蓝牙,等等。

假如对这个东西运用不熟悉的小伙伴,能够阅览下文:

零根底快速上手STM32开发(手把手保姆级教程)】

手把手教你玩转ESP8266(原理+驱动)

USB转TTL模块 ESP8266
3.3V 3.3V
TXD RX
RXD TX
GND GND

运用 USB 转 TTL 东西调试 ESP8266,能够经过上面的表格进行接线。

3.3V 相接后或许无法发动 ESP8266,这是因为 USB 转 TTL 模组的 3.3V 并没有真的达到 3.3V,莫慌,直接将 ESP8266 的3.3V 引脚接入 USB 转 TTL 的 5V 引脚,假如 ESP8266 会发烫到无法接触就拔掉,假如温度你手指还能接受,那就没问题,ESP8266 仍是没那么脆弱的。

接好线之后,将 USB 端衔接到电脑,翻开串口调试帮手就能够进行调试了。

  • USB 转 ESP8266WIFI 模块
手把手教你玩转ESP8266(原理+驱动)

上面的 USB 转 TTL 模组需求你动手去接线,比较麻烦,并且要是线有一根接错了,就无法正常调试了。

而这个模组专门是为了调试 ESP8266 而设计,不需求一个个引脚接线,直接把 ESP8266 往上一插就能够啦,超便利的。相同,USB 端衔接电脑,翻开串口调试帮手就能够进行调试了。

  • 单片机调试

这种便是在项目中最常用的办法了。需求将 ESP8266 接到单片机的任意一个串口,然后再编写代码驱动 ESP8266 ,完结各种业务逻辑。

本文便是手把手教咱们编写一个 ESP8266 驱动程序。

上电:正常作业验证

模块拿到手之后,咱们需求先保证这个模组是正常的,不然后边的调试、写代码都是白费。

首要,上电后,蓝色灯微弱闪耀后熄灭,表示正常作业。

手把手教你玩转ESP8266(原理+驱动)

还能够更进一步,接好线之后,然后翻开串口调试帮手发送 AT(并且还要敲一个回车),ESP8266 回复 OK,便是正常发动了。

手把手教你玩转ESP8266(原理+驱动)

4. ESP8266作业形式

ESP8266 支撑 STA、AP、AP+STA 三种作业形式。

  • STA 形式(Station)

一般用于远距离传输。ESP8266 经过路由器衔接互联网,终端设备经过互联网完结对设备的远程操控。简单来说,此刻的 ESP8266 能够当作是一个客户端,能够向服务端进行数据的下载与传输。这就类似于,手机/平板/笔记本(客户端)能够经过 WIFI 衔接到路由器进行上网。

  • AP 形式(Access Point)

一般用于近距离传输。ESP8266 作为热门,供给无线接入服务、数据拜访,一般的无线路由/网桥作业在 AP 形式下,最多支撑 4 台设备接入。简单来说,此刻的 ESP8266 能够当作是一个服务端。这就类似于,ESP8266 变身为一个路由器,然后手机/平板/笔记本能够经过 WIFI 衔接到 ESP8266 进行上网。

  • AP+STA 形式

两种形式的共存形式,能够经过互联网操控可完结无缝切换,便利操作。简单来说,此刻的 ESP8266 能够当作是一个路由器既能够做服务端接纳也能够当客户端衔接路由器,进行联网传输和操控。

5. AT指令介绍

5.1 什么是AT指令?

AT 指令(AT Commands)最早是由发明拨号调制解调器的贺氏公司为了操控拨号调制解调器而发明的操控协议。后来跟着网络带宽的升级,速度很低的拨号调制解调器根本退出市场,可是 AT 指令被保留了下来。

在嵌入式开发中,经常是运用 AT 指令去操控各种通讯模块,比方 ESP8266 模块、4G 模块、GPRS 模块等等。一般便是主芯片经过硬件接口(比方串口、SPI)发送 AT 指令给通讯模块,模块接纳到数据之后回应响应的数据。

5.2 常用AT指令介绍

AT 指令分为四种类型:

类型 格式 功能
测验指令 AT + < X > = ? 查询设置指令或内部程序设置的参数及其取值范围
查询指令 AT + < X > ? 返回参数的当时值
设置指令 AT + < X > = < … > 设置用户自界说的参数值
履行指令 AT + < X > 履行受模块内部程序操控的变参数不可变

AT 指令有近百条,但常用的就十几条,理解起来也十分简单,现在举例一些常用指令,并运用这些指令一步一步的经过 TCP 衔接到远程的服务器完结收发数据。

AT指令 功能
AT 测验是否正常发动
AT+CWMODE=1 设置 STA 形式
AT+CWMODE=2 设置 AP 形式
AT+CWMODE=3 设置 AP+STA 形式
AT+RST 重启收效
AT+CWSAP=”SSID”,”password”,1,4 设置 AP 参数:账号为SSID ,暗码为password,通道号为 1,加密办法为:WPA_WPA2_PSK
AT+CIPMUX=0 敞开单衔接
AT+CIPMUX=1 敞开多衔接
AT+CIPSERVER=1,8080 敞开 SERVER 形式,设置端口为 8080
AT+CIPSTART=“TCP”,”192.168.X.XXX”,8080 树立 TCP 衔接到”192.168.X.XXX”,8080
AT+CIPSTART=“UDP”,“192.168.X.XXX”,8080 树立 UDP 衔接到”192.168.X.XXX”,8080
AT+CIPCLOSE 断开 TCP 衔接
AT+CWQAP 断开热门
AT+CIPSEND=n 开端传输,n表示需求传输的字节数
AT+CIPSEND=0,n 向 ID0 发送 n 字节数据包,n的值自己定
AT+CIPMODE=1 敞开透传形式
AT+CIPSEND 开端发送数据
AT+CIPMODE=0 退出透传
AT+CWJAP=”SSID,“password” 加入 WIFI 热门:SSID ,暗码为:password
AT+CIFSR 查询 ESP8266 的 IP 地址
AT+CIPSTA? 查询 ESP8266 的 IP 、网关地址和子网掩码

接下来咱们要用串口帮手发送 AT 指令,假如你还不会用串口帮手,那么动动小手跟我操作:

  1. 插上 USB,挑选正确的串标语,正确的串标语是插上 USB 后多出的串标语;
  2. 挑选波特率,ESP8266 默认波特率是 115200 ,能够经过 AT 指令修正;
  3. 点击「翻开」或许「翻开串口」;
  4. 在输入框输入指令,AT 指令要以回车结尾;
  5. 点击「发送」,观察 ESP8266 的返回值
  6. 运用完点「断开」或许「封闭串口」。

不必定要用我的串口帮手,其他串口帮手也能够(比方正点原子开发的串口帮手,甚至你自己写一个也行),都是相同的。

假如现已插上 USB,挑选了正确的串标语,可是出现串口打不开并输出「【ERROR】Cannot set COM port parameters」 的情况,或许是 CH340 驱动还没装置,或许需求卸载重新装置一下。教你处理:

  1. 先点「断开」,断开串口;
  2. 翻开 CH340 驱动装置程序,我文章最初有供给;
  3. 假如你没有装置过,点击「装置」;假如你装置过,点击「卸载」再点击「装置」;
  4. 装置好后拔插一下 USB,看看串标语有没有变,有变更换一下串标语;
  5. 最终点「翻开」或许「翻开串口」就能够啦。

假如还不理解的,能够参阅下文,有图文教程:

零根底快速上手STM32开发(手把手保姆级教程)

5.2.1 测验模块是否正常(AT)

发送 AT,ESP8266 回复 OK,便是正常发动了。

手把手教你玩转ESP8266(原理+驱动)

5.2.2 敞开/封闭回显(ATE1/ATE0)

发送了指令 AT,模块回复了「AT OK」,即模块将发送过来的指令原封不动的先复述了一遍后接着发送有用回复,咱们称这种复述为 回显

发送 ATE0,封闭回显

发送 ATE1,敞开回显

手把手教你玩转ESP8266(原理+驱动)

5.2.3 设置AP形式及AP参数(AT+CWMODE,AT+CWSAP)

发送 AT+CWMODE?,查询模块当时处于哪一种形式;

发送 AT+CWMODE=1,设置 STA 形式;

发送 AT+CWMODE=2,设置 AP 形式;

发送 AT+CWMODE=3,设置 AP+STA 形式。

手把手教你玩转ESP8266(原理+驱动)

假如当时为 AP 形式,那么发送 AT+CWSAP="SSID","password",通道,加密办法 ,能够设置热门。这个过程相当于给路由器设置热门名称及暗码,便利手机衔接。

例如:发送 AT+CWSAP="ESP8266-liangxu","12345678",5,3 ,则能够将热门名设置为 ESP8266-liangxu ,暗码为 12345678,运用通道 5 ,加密办法为 WPA2_PSK(1-WEP,2-WPA_PSK,3-WPA2_PSK,4-WPA_WPA2_PSK),这儿的通道对应的便是不同的射频频率,假如同一空间内存在相同通道的 WIFI 信号,将会产生搅扰,影响上网质量,因此能够设置通道来避免这种搅扰,常用的通道有 1、6、11,因为这三个通道互不产生搅扰。

手把手教你玩转ESP8266(原理+驱动)

5.2.4 设置为STA形式(AT+CWMODE=1,AT+CWJAP,AT+CIFSR)

发送 AT+CWMODE=1,设置 STA 形式;

发送 AT+CWJAP="SSID","password",衔接路由器;

发送 AT+CIPSTA?,路由器分配给 ESP8266 的局域网 IP 以及网关地址和子网掩码;

发送 AT+CIFSR,查询 ESP8266 的 IP 地址信息。

手把手教你玩转ESP8266(原理+驱动)

5.2.5 TCP透传

5.2.5.1 准备作业

完结 TCP 透传需求树立一个 TCP 服务器,这儿咱们就运用网络调试帮手 + 自己的电脑就好。我的网络调试帮手是正点原子的,咱们不必定要用我的,只要是网络帮手都能够。

首要咱们需求知道自己电脑的 IP 地址,有两种办法:

办法1:翻开电脑的设置:

手把手教你玩转ESP8266(原理+驱动)

办法2:运用指令提示符:

手把手教你玩转ESP8266(原理+驱动)

翻开网络调试帮手,跟我装备,超快的。端标语 TCP 协议一般填8080。

手把手教你玩转ESP8266(原理+驱动)

5.2.5.2 正式开端

接下来咱们运用串口帮手将 ESP8266 衔接到 TCP 服务器。

发送 AT+CIPSTART="协议形式","服务端IP地址",端标语 ,树立衔接,协议形式有 TCP 和 UDP ;

因为咱们刚刚树立的是 TCP 服务器,服务器 IP 地址是 192.168.1.27,所以咱们发送 AT+CIPSTART="TCP","192.168.1.27",8080 。假如不出意外,过一会儿 ESP8266 就衔接上 TCP 服务器了,将返回 CONNECT OK 。

但这个时候,咱们再在输入框发送内容的话,依然是默以为指令。假如咱们想把数据直接发送给 TCP 服务器,那么就需求敞开透传形式。

所谓的透传形式,能够视为 ESP8266 为通明状态,客户端发送的信息直接就传输给服务端。

咱们需求先发送 AT+CIPMODE=1,敞开透传形式。然后,再发送 AT+CIPSEND,才真实开端透传发送。

此刻,你发送的任何数据,就直接传输到服务器了。

手把手教你玩转ESP8266(原理+驱动)

退出透传:先发送 +++(不要带回车),再发送 AT+CIPMODE=0

假如不退出透传,发出来的就算是 AT 指令,它也会被以为是普通字符串,直接透传给对方。

手把手教你玩转ESP8266(原理+驱动)

AT+CWCLOSE,断开 TCP 衔接。

AT+CWQAP,断开热门。

手把手教你玩转ESP8266(原理+驱动)

6. 编程实战

6.1 硬件接线

本教程运用的硬件如下:

  • 单片机:STM32F103C8T6

  • WiFi模块:ESP-01S

  • 串口:USB 转 TTL

  • 烧录器:ST-LINK V2。

接线可参照下表:

ESP8266 STM32 USB 转 TTL
3V3 3.3
TX A3
RX A2
GND G
A10 TX
A9 RX
G GND

烧录的时候接线如下表,假如不会烧录的话能够看我之前的文章【STM32下载程序的五种办法】。

ST-Link V2 STM32
SWCLK SWCLK
SWDIO SWDIO
GND GND
3.3V 3V3

其间 USB 转 TTL 衔接的是 STM32 的串口1(A9和A10),用来打印 STM32 的输出;STM32 的串口2(A2和A3),用来操控 ESP8266。

接好就像这样:

手把手教你玩转ESP8266(原理+驱动)

6.2 模板工程加载ESP8266模块代码

翻开模板工程和 ESP8266 驱动源码。

手把手教你玩转ESP8266(原理+驱动)

仿制好后翻开工程。

手把手教你玩转ESP8266(原理+驱动)

跟着我的贪吃蛇点点点:)

手把手教你玩转ESP8266(原理+驱动)

手把手教你玩转ESP8266(原理+驱动)

6.3 串口通讯完结

完结向串口发送数据,并等候返回值。ESP8266 的 TX 和 RX 界说在串口2。

  1. 界说串口句柄 g_uart_handle ,并调用 HAL_UART_Init 进行初始化。
UART_HandleTypeDef g_uart_handle;
void esp8266_uart_init(uint32_t baudrate)
{
    g_uart_handle.Instance          = ESP8266_UART_INTERFACE;       /* ESP8266 UART */
    g_uart_handle.Init.BaudRate     = baudrate;                     /* 波特率 */
    g_uart_handle.Init.WordLength   = UART_WORDLENGTH_8B;           /* 数据位 */
    g_uart_handle.Init.StopBits     = UART_STOPBITS_1;              /* 停止位 */
    g_uart_handle.Init.Parity       = UART_PARITY_NONE;             /* 校验位 */
    g_uart_handle.Init.Mode         = UART_MODE_TX_RX;              /* 收发形式 */
    g_uart_handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;          /* 无硬件流控 */
    g_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;         /* 过采样 */
    HAL_UART_Init(&g_uart_handle);                                  /* 使能ESP8266 UART */
}

其间,ESP8266_UART_INTERFACE 是宏界说,指代的便是 USART2

传入参数 baudrate 能够界说该串口的波特率。

  1. 初始化串口底层函数,调用 HAL_UART_MspInit 函数。

留意最终一行,需求调用 __HAL_UART_ENABLE_IT 函数使能接纳中止。

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;
    if (huart->Instance == USART_UX)                            /* 假如是串口1,进行串口1 MSP初始化 */
    {
        ....
        // 省掉串口1相关代码
        ....
    }
    else if (huart->Instance == ESP8266_UART_INTERFACE)                 /* 假如是ESP8266 UART */
    {
        ESP8266_UART_TX_GPIO_CLK_ENABLE();                              /* 使能UART TX引脚时钟 */
        ESP8266_UART_RX_GPIO_CLK_ENABLE();                              /* 使能UART RX引脚时钟 */
        ESP8266_UART_CLK_ENABLE();                                      /* 使能UART时钟 */
        gpio_init_struct.Pin    = ESP8266_UART_TX_GPIO_PIN;             /* UART TX引脚 */
        gpio_init_struct.Mode   = GPIO_MODE_AF_PP;                          /* 复用推挽输出 */
        gpio_init_struct.Pull   = GPIO_NOPULL;                              /* 无上下拉 */
        gpio_init_struct.Speed  = GPIO_SPEED_FREQ_HIGH;                     /* 高速 */
        HAL_GPIO_Init(ESP8266_UART_TX_GPIO_PORT, &gpio_init_struct);    /* 初始化UART TX引脚 */
        gpio_init_struct.Pin    = ESP8266_UART_RX_GPIO_PIN;             /* UART RX引脚 */
        gpio_init_struct.Mode   = GPIO_MODE_INPUT;                          /* 输入 */
        gpio_init_struct.Pull   = GPIO_NOPULL;                              /* 无上下拉 */
        gpio_init_struct.Speed  = GPIO_SPEED_FREQ_HIGH;                     /* 高速 */
        HAL_GPIO_Init(ESP8266_UART_RX_GPIO_PORT, &gpio_init_struct);    /* 初始化UART RX引脚 */
        HAL_NVIC_SetPriority(ESP8266_UART_IRQn, 0, 0);                  /* 抢占优先级0,子优先级0 */
        HAL_NVIC_EnableIRQ(ESP8266_UART_IRQn);                          /* 使能UART中止通道 */
        __HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);                          /* 使能UART接纳中止 */
    }
}
  1. 运用接纳中止+超时判别,完结数据接纳。

因为 ESP8266 经过串口返回的数据长度不固定,所以咱们能够运用接纳中止+超时判别的办法完结数据接纳。具体办法能够参阅下文:

STM32串口接纳不定长数据(接纳中止+超时判别)

在串口中止服务函数里,咱们能够将接纳到的字符保存在接纳缓冲区里 g_uart_rx_buf ,并界说一个变量 esp8266_cnt 核算总共收到了多少个字符。

void ESP8266_UART_IRQHandler(void)
{
    uint8_t receive_data = 0;   
    if(__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_RXNE) != RESET){
        if(esp8266_cnt >= sizeof(g_uart_rx_buf))
            esp8266_cnt = 0; //避免串口被刷爆
        HAL_UART_Receive(&g_uart_handle, &receive_data, 1, 1000);//串口2接纳1位数据
        g_uart_rx_buf[esp8266_cnt++] = receive_data;  
    }
    HAL_UART_IRQHandler(&g_uart_handle);
}

假如一帧的数据接纳完结了,那么 esp8266_cnt 变量的值应该维持不变。

咱们经过 while 死循环不停核算当时收到多少个字符,当时计算的值核算在 esp8266_cnt 变量里,界说另一个变量 esp8266_cntPre ,用于记录上一次计算接纳到的数据的长度,假如本次计算数据长度跟上一次相同的话就阐明数据接纳完结了。代码如下:

uint8_t esp8266_wait_receive(void)
{
    if(esp8266_cnt == 0) 							//假如接纳计数为0 则阐明没有处于接纳数据中,所以直接跳出,完毕函数
        return ESP8266_ERROR;
    if(esp8266_cnt == esp8266_cntPre) {				//假如上一次的值和这次相同,则阐明接纳完毕
        esp8266_cnt = 0;							//清0接纳计数
        return ESP8266_EOK;							//返回接纳完结标志
    }
    esp8266_cntPre = esp8266_cnt;					//置为相同
    return ESP8266_ERROR;							//返回接纳未完结标志
}

当然,接纳到的数据运用完结之后,咱们就应该清空接纳缓冲区,并将计数器置 0 ,便利下一次接纳。

void esp8266_clear(void)
{
    memset(g_uart_rx_buf, 0, sizeof(g_uart_rx_buf));
    esp8266_cnt = 0;
}

接下来,便是最关键的一个函数了。咱们运用这个函数经过串口向 ESP8266 发送一个字符串,并循环等候咱们所等待得到的字符串。

在下面这个函数里,cmd 变量是咱们向 ESP8266 发送的字符串,res 变量是咱们等待得到的回复。

比方,咱们向 ESP8266 发送 AT 这个字符串,那么 ESP8266 假如正常的话应该会回复 OK 。此刻,cmd 便是 AT ,而 res 便是 OK

uint8_t esp8266_send_command(char *cmd, char *res)
{
    uint8_t timeOut = 250;
    esp8266_clear();
    HAL_UART_Transmit(&g_uart_handle, (unsigned char *)cmd, strlen((const char *)cmd), 100);
    while(timeOut--) {
        if(esp8266_wait_receive() == ESP8266_EOK) {						//假如收到数据
            if(strstr((const char *)g_uart_rx_buf, res) != NULL)		//假如检索到关键词
                return ESP8266_EOK;
        }
        delay_ms(10);
    }
    return ESP8266_ERROR;
}

6.4 编程完结AT指令交互

接下来,咱们就能够运用 esp8266_send_command 发送 AT 指令并确定 ESP8266 回复是否正确。以代码办法完结各个 AT 指令,比如如下:

uint8_t esp8266_at_test(void)
{
    return esp8266_send_command("ATrn", "OK");
}
uint8_t esp8266_sw_reset(void)
{
    return esp8266_send_command("AT+RSTrn", "OK");
}
uint8_t esp8266_set_mode(uint8_t mode)
{
    switch (mode) {
        case ESP8266_STA_MODE:
            return esp8266_send_command("AT+CWMODE=1rn", "OK");    /* Station形式 */
        case ESP8266_AP_MODE:
            return esp8266_send_command("AT+CWMODE=2rn", "OK");    /* AP形式 */
        case ESP8266_STA_AP_MODE:
            return esp8266_send_command("AT+CWMODE=3rn", "OK");    /* AP+Station形式 */
        default:
            return ESP8266_EINVAL;
    }
}

因为 AT 指令有很多,这儿只截取了其间的一部分,完整的能够参阅我供给的代码。

6.5 编程完结STA形式

STA 形式完结思路如下:

  1. 进入 STA 形式(要重启收效);
  2. 设置单路衔接;
  3. 衔接 WIFI(留意 ESP8266 和服务端要在同一网络内);
  4. 浅查一下 ESP8266 的 IP 地址,不查也能够;
  5. 衔接TCP服务器;
  6. 敞开透传。
uint8_t esp8266_single_connection(void)
{
    return esp8266_send_command("AT+CIPMUX=0rn", "OK");
}
uint8_t esp8266_join_ap(char *ssid, char *pwd)
{
    char cmd[64];
    sprintf(cmd, "AT+CWJAP="%s","%s"rn", ssid, pwd);
    return esp8266_send_command(cmd, "WIFI GOT IP");
}
uint8_t esp8266_get_ip(char *buf)
{
    char *p_start;
    char *p_end;
    if (esp8266_send_command("AT+CIFSRrn", "STAIP") != ESP8266_EOK)
        return ESP8266_ERROR;
    p_start = strstr((const char *)g_uart_rx_buf, """);
    p_end = strstr(p_start + 1, """);
    *p_end = '';
    sprintf(buf, "%s", p_start + 1);
    return ESP8266_EOK;
}
uint8_t esp8266_connect_tcp_server(char *server_ip, char *server_port)
{
    char cmd[64];
    sprintf(cmd, "AT+CIPSTART="TCP","%s",%srn", server_ip, server_port);
    return esp8266_send_command(cmd, "CONNECT");
}
uint8_t esp8266_enter_unvarnished(void)
{
    uint8_t ret;
    ret  = esp8266_send_command("AT+CIPMODE=1rn", "OK");
    ret += esp8266_send_command("AT+CIPSENDrn", ">");
    if (ret == ESP8266_EOK)
        return ESP8266_EOK;
    else
        return ESP8266_ERROR;
}
/**
 * @brief       ESP8266初始化
 * @param       baudrate: ESP8266 UART通讯波特率
 * @retval      ESP8266_EOK  : ESP8266初始化成功,函数履行成功
 *              ESP8266_ERROR: ESP8266初始化失利,函数履行失利
 */
uint8_t esp8266_init(uint32_t baudrate)
{
    char ip_buf[16];
    esp8266_uart_init(baudrate);                /* ESP8266 UART初始化 */
    /* 让WIFI退出透传形式 */
	while(esp8266_exit_unvarnished())
        delay_ms(500);
	printf("1.ATrn");
	while(esp8266_at_test())
        delay_ms(500);
	printf("2.RSTrn");
    while(esp8266_sw_reset())
        delay_ms(500);
	while(esp8266_disconnect_tcp_server())
        delay_ms(500);
	printf("3.CWMODErn");
	while(esp8266_set_mode(ESP8266_STA_MODE))
        delay_ms(500);
	printf("4.AT+CIPMUXrn");  //设置单路衔接形式,透传只能运用此形式
	while(esp8266_multi_connection())
        delay_ms(500);
	printf("5.CWJAPrn");      //衔接WIFI
    printf("%srn",WIFI_SSID); 
	while(esp8266_join_ap(WIFI_SSID, WIFI_PWD))
        delay_ms(1000);
    printf("6.CIFSRrn");
    while(esp8266_get_ip(ip_buf))
        delay_ms(500);
    printf("ESP8266 IP: %srn", ip_buf);
    printf("7.CIPSTARTrn");
    while(esp8266_connect_tcp_server(TCP_SERVER_IP, TCP_SERVER_PORT))
        delay_ms(500);
    printf("8.CIPMODErn");
    while(esp8266_enter_unvarnished())
        delay_ms(500);
    printf("ESP8266初始化完结rn");
    return ESP8266_EOK;
}

代码完结,编译,烧录,翻开串口,串口输出,完结作用当当当:

手把手教你玩转ESP8266(原理+驱动)

6.6 编程完结AP形式

AP 形式完结思路很简单:

  1. 进入 AP 形式(要重启收效);
  2. 设置 AP 参数;
  3. 敞开多衔接或单衔接。
uint8_t esp8266_set_ap(char *ssid, char *pwd)
{
    char cmd[64];
    sprintf(cmd, "AT+CWSAP="%s","%s",5,3rn", ssid, pwd);
    return esp8266_send_command(cmd, "OK");
}
uint8_t esp8266_multi_connection(void)
{
    return esp8266_send_command("AT+CIPMUX=1rn", "OK");
}
uint8_t esp8266_init(uint32_t baudrate)
{
    char ip_buf[16];
    esp8266_uart_init(baudrate);                /* ESP8266 UART初始化 */
    /* 让WIFI退出透传形式 */
	while(esp8266_exit_unvarnished())
        delay_ms(500);
	printf("1.ATrn");
	while(esp8266_at_test())
        delay_ms(500);
	printf("2.RSTrn");
    while(esp8266_sw_reset())
        delay_ms(500);
	while(esp8266_disconnect_tcp_server())
        delay_ms(500);
    printf("3.CWMODErn");
	while(esp8266_set_mode(ESP8266_AP_MODE))
        delay_ms(500);
	printf("4.CWSAPrn");      //设置AP
    printf("%srn",WIFI_SSID); 
	while(esp8266_set_ap(WIFI_SSID, WIFI_PWD))
        delay_ms(1000);
	printf("5.AT+CIPMUXrn");  //设置多路衔接形式
	while(esp8266_multi_connection())
        delay_ms(500);
    printf("ESP8266_Init OKrn");
    return ESP8266_EOK;
}

代码完结,烧录,翻开串口,串口输出,完结作用当当当:

手把手教你玩转ESP8266(原理+驱动)

6.7 编程完结AP+STA形式

AP+STA 形式运用不多,便是前两个的结合,这儿就不多介绍了。仿照 STA 形式和 AP 形式写相应的 AT 指令代码就好啦,思路如下,需求留意的是要发动多衔接:

  1. 设置为 AP+STA 形式(要重启收效);
  2. AT+CWJAP=”SSID”,”password”,衔接WIFI(留意 ESP8266 和服务端要在同一网络内);
  3. AT+CWSAP=”SSID”,”password”,通道,加密办法,设置AP热门;
  4. AT+CIPMUX=1,发动多衔接;
  5. AT+CIPSERVER=1,8080,翻开服务器端口为8080。
uint8_t esp8266_join_ap(char *ssid, char *pwd)
{
    char cmd[64];
    sprintf(cmd, "AT+CWJAP="%s","%s"rn", ssid, pwd);
    return esp8266_send_command(cmd, "WIFI GOT IP");
}
uint8_t esp8266_set_ap(char *ssid, char *pwd)
{
    char cmd[64];
    sprintf(cmd, "AT+CWSAP="%s","%s",5,3rn", ssid, pwd);
    return esp8266_send_command(cmd, "OK");
}
uint8_t esp8266_multi_connection(void)
{
    return esp8266_send_command("AT+CIPMUX=1rn", "OK");
}
uint8_t esp8266_open_server()
{
    return esp8266_send_command("AT+CIPSERVER=1,8080rn", "OK");
}
uint8_t esp8266_init(uint32_t baudrate)
{
    char ip_buf[16];
    esp8266_uart_init(baudrate);                /* ESP8266 UART初始化 */
    /* 让WIFI退出透传形式 */
	while(esp8266_exit_unvarnished())
        delay_ms(500);
    /* STA+AP形式 */
	printf("1.ATrn");
	while(esp8266_at_test())
        delay_ms(500);
	printf("2.RSTrn");
    while(esp8266_sw_reset())
        delay_ms(500);
	while(esp8266_disconnect_tcp_server())
        delay_ms(500);
    printf("3.CWMODErn");
	while(esp8266_set_mode(ESP8266_STA_AP_MODE))
        delay_ms(500);
    printf("4.CWJAPrn");      //衔接WIFI
    printf("%srn",WIFI_SSID); 
    while(esp8266_join_ap(WIFI_SSID, WIFI_PWD))
        delay_ms(1000);
	printf("5.CWSAPrn");      //设置AP
	while(esp8266_set_ap("ESP8266-liangxu", "12345678"))
        delay_ms(1000);
	printf("6.AT+CIPMUXrn");  //设置多路衔接形式
	while(esp8266_multi_connection())
        delay_ms(500);
	printf("7.CIPSERVERrn");  //翻开服务器端口8080
    while(esp8266_open_server())
        delay_ms(500);
    printf("ESP8266_Init OKrn");
    return ESP8266_EOK;
}

代码完结,编译,烧录,翻开串口,串口输出,完结作用当当当:

手把手教你玩转ESP8266(原理+驱动)

esp8266.h文件内容如下:

#ifndef __ESP8266_H__
#define __ESP8266_H__
#include <stdint.h>
#include "usart.h"
extern UART_HandleTypeDef g_uart_handle;
/* 引脚界说 */
#define ESP8266_UART_TX_GPIO_PORT           GPIOA
#define ESP8266_UART_TX_GPIO_PIN            GPIO_PIN_2
#define ESP8266_UART_TX_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PC口时钟使能 */
#define ESP8266_UART_RX_GPIO_PORT           GPIOA
#define ESP8266_UART_RX_GPIO_PIN            GPIO_PIN_3
#define ESP8266_UART_RX_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0) /* PD口时钟使能 */
#define ESP8266_UART_INTERFACE              USART2
#define ESP8266_UART_IRQn                   USART2_IRQn
#define ESP8266_UART_IRQHandler             USART2_IRQHandler
#define ESP8266_UART_CLK_ENABLE()           do{ __HAL_RCC_USART2_CLK_ENABLE(); }while(0) /* UART2时钟使能 */
/* UART收发缓冲巨细 */
#define ESP8266_UART_RX_BUF_SIZE            128
#define ESP8266_UART_TX_BUF_SIZE            64
/* 过错代码 */
#define ESP8266_EOK                         0   /* 没有过错 */
#define ESP8266_ERROR                       1   /* 通用过错 */
#define ESP8266_ETIMEOUT                    2   /* 超时过错 */
#define ESP8266_EINVAL                      3   /* 参数过错 */
/* 作业形式 */
#define ESP8266_STA_MODE                    1
#define ESP8266_AP_MODE                     2
#define ESP8266_STA_AP_MODE                 3
#define WIFI_SSID                           "HuaweiAP-1ED0"
#define WIFI_PWD                            "87654321"
#define TCP_SERVER_IP                       "192.168.1.27"
#define TCP_SERVER_PORT                     "8080"
uint8_t esp8266_init(uint32_t baudrate);
void esp8266_clear(void);
void esp8266_uart_printf(char *fmt, ...);
#endif

7. 小结

经过学习和实践,希望咱们能够了解并把握 ESP8266 的特性和运用,然后更好地运用于嵌入式开发。无论是构建智能家居系统仍是开发物联网设备,ESP8266 都能够成为您的得力帮手,让咱们一起玩转 ESP8266,love and peace!


别的,想进大厂的同学,必定要好好学算法,这是面试必备的。这儿准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。

手把手教你玩转ESP8266(原理+驱动)

刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!

有收成?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅览:

欢迎重视我的博客:良许嵌入式教程网,满满都是干货!