一、简介
实测VCC接5V通信将不正常。
二、USB-TTL与ESP-01
我们可以通过USB-TTL与ESP-01连接,通过AT指令设置或检查ESP-01工作是否正常。
RX和TX反接其他正常接线就行。ESP-01默认波特率为115200。
当我们通过串口助手发送指令“AT”,若接收到“OK”则表示模块正常。
注意要勾选“发送新行”
该模块支持STA模式、AP模式、STA兼AP模式三种。
(1)STA模式
配置为STA模式的AT指令为:AT+CWMODE=1
此时ESP8266模块已经被设置为了STA模式。我们可以连接家中的WIFI。
连接WIFI的AT指令为:AT+CWJAP=AT+CWJAP="WIFI ID","WIFI 密码"
例如我这里是:AT+CWJAP="Redmi K40","123456789"
显示WIFI GOT IP OK 则表示连接成功。
我们此时就可以通过AT指令“AT+CIFSR”查询IP地址
此时我们的电脑和ESP8266模块都连接到了同一个路由器。
我们就可以通过电脑创建TCP服务器,两者就可以进行通信了。
我们打开网络调试助手
创建TCP Server
然后在串口助手上用AT指令连接该TCP Server
AT指令为:AT+CIPSTART="TCP","IP地址",8080
注意英文的双引号和逗号
连接成功也会返回OK
测试两者就可以进行通信了
我们需要先告诉服务器我们需要发送的长度,如AT+CIPSEND=4
看到出现>符号后就可以发送了,如:good
(2)AP模式
首先,我们通过AT指令,AT+CWMODE=2配置ESP8266模块为AP模式
然后,我们通过AT指令使能多链接,AT+CIPMUX=1
多链接的意思为:
反之,AT+CIPMUX=0,表示设置为单链接。
接着,我们就可以通过ESP8266模块建立TCP服务器(上一小节的STA模式是通过PC建立TCP 服务器)ESP8266模块建立TCP服务器的AT指令为:AT+CIPSERVER=1
创建成功之后我们就用电脑连接AI开头的WIFI。连接成功后串口助手上会显示OK等信息
最后,我们就可以通过网络调试助手连接由ESP8266创建的TCP SERVER后就可以进行通信了。
(通信过程类似)
IP地址默认为192.168.4.1,也可以通过AT指令,AT+CIPSR查询,PORT默认为333
三、STM32与ESP-01进行通信(HAL库代码)
我们使用的是STM32最小系统板,CUBEMX+CUBEIDE。
代码是改的这位博主的ESP-01
串口3连接USB-TTL用来打印一些信息,设置如下:
串口2连接ESP-01模块,用于STM32与ESP-01模块进行通信,使用的方式是开启了串口2的DMA(DMA+空闲中断)
两个串口的波特率均为115200,串口2和串口3都开启DMA
并开启串口2和串口3的中断
首先,我们先写ESP-01模块的驱动代码,driver_esp.c
#include "driver_esp.h"
uint8_t WIFI_Name_Cipher[]="AT+CWJAP=\"Redmi K40\",\"123456789\"\r\n";
#define ESP01_UART_HANDLE huart2
void esp01_uart_send_data(uint8_t *data,uint16_t data_len)
{
HAL_UART_Transmit(&ESP01_UART_HANDLE, data , data_len,100 );
}
/*****************************************上面是需要修改的地方******************************************************/
/*私有定义*/
uint8_t g_esp8266_rx_buffer[256]; // ESP8266响应数据接收缓冲区
/*****************************************函数******************************************************/
/**
* @brief ESP8266发送命令
* @param cmd为AT指令,res为返回值
* @return 成功返回1,失败返回0
* 通过串口2发送AT指令给esp-01s模块,如果检索到串口2收到esp-01s回复的字符中存在指定字符(res),则表示成功且返回1,否则失败返回0
*其中cmd是需要发送的AT指令,res是esp-01s模块回复(发送)给串口2的字符消息
*/
_Bool ESP8266_Send_Cmd(char *cmd, char *res)
{
uint8_t TimeOut = 20;
esp01_uart_send_data(cmd, strlen(cmd));
while (TimeOut --)
{
if (strstr(g_esp8266_rx_buffer, res) != NULL)
return 1; //Success
HAL_Delay(100);
}
return 0; //Fail
}
/**
* @brief 测试命名
* @param None
* @retval None
**/
_Bool ESP8266_TEST(void)
{
return ESP8266_Send_Cmd("AT\r\n","OK");
}
/**
* @brief 选择ESP8266的工作模式
* @param enumMode 模式类型 STA AP STA_AP
* @retval 返回 true 发送成功,false 失败
**/
_Bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode)
{
switch (enumMode)
{
case STA:
return ESP8266_Send_Cmd("AT+CWMODE=1\r\n", "OK");
case AP:
return ESP8266_Send_Cmd("AT+CWMODE=2\r\n", "OK");
case STA_AP:
return ESP8266_Send_Cmd("AT+CWMODE=3\r\n", "OK");
default:
return 0;
}
}
/**
* @brief 设置ESP8266的连接模式(单连接/多连接)
* @param mode 0=单连接模式,1=多连接模式
* @return 成功返回1,失败返回0
*/
_Bool ESP8266_Set_MultiplesMode(uint8_t mode)
{
char cmd[32];
//构造AT指令:AT+CIPMUX=<mode>\r\n
sprintf(cmd, "AT+CIPMUX=%d\r\n", mode);
return ESP8266_Send_Cmd(cmd, "OK");
}
/**
* @brief 连接WIFI
* @param None
* @return 成功返回1,失败返回0
* @Note 注意修改WIFI_Name_Cipher
*/
_Bool ESP8266_JoinAP(void)
{
return ESP8266_Send_Cmd(WIFI_Name_Cipher,"OK");
}
/**
* @brief 连接TCP服务器(自动适配单连接/多连接模式)
* @param id 连接ID(仅在多连接模式下有效,单连接模式传0)
* @param ip 服务器IP地址(如 "192.168.1.100")
* @param port 服务器端口号(如 8080)
* @return 成功返回1,失败返回0
*/
_Bool ESP8266_Connect_TCPServer(uint8_t id, const char* ip, uint16_t port) {
char cmd[128];
// 根据当前模式构造AT指令
if (strstr(g_esp8266_rx_buffer, "+CIPMUX:1") != NULL) {
// 多连接模式:AT+CIPSTART=<id>,"TCP","<ip>",<port>\r\n
sprintf(cmd, "AT+CIPSTART=%d,\"TCP\",\"%s\",%d\r\n", id, ip, port);
} else {
// 单连接模式:AT+CIPSTART="TCP","<ip>",<port>\r\n
sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ip, port);
}
return ESP8266_Send_Cmd(cmd, "OK");
}
接下来是源文件
#ifndef __DRIVER_ESP_H
#define __DRIVER_ESP_H
#include "main.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
//ESP8266模式选择
typedef enum
{
STA,
AP,
STA_AP
}ENUM_Net_ModeTypeDef;
_Bool ESP8266_TEST(void);//测试命令 发送“AT”
_Bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode); //设置模式 STA AP STA_AP
_Bool ESP8266_Set_MultiplesMode(uint8_t mode);//选择多链路 1多 0单
_Bool ESP8266_JoinAP(void);//加入WIFI
_Bool ESP8266_Connect_TCPServer(uint8_t id, const char* ip, uint16_t port);//建立TCP服务器
_Bool ESP8266_Send_Cmd(char *cmd, char *res);
#endif
这个驱动文件封装了几个AT指令,如果需要其他命令可以自己封装
_Bool ESP8266_TEST(void);//测试命令 发送“AT”
_Bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode); //设置模式 STA AP STA_AP
_Bool ESP8266_Set_MultiplesMode(uint8_t mode);//选择多链路 1多 0单
_Bool ESP8266_JoinAP(void);//加入WIFI
_Bool ESP8266_Connect_TCPServer(uint8_t id, const char* ip, uint16_t port);//建立TCP服务器
_Bool ESP8266_Send_Cmd(char *cmd, char *res);//发送命名
接下来初始化代码 和空闲处理代码:(设置为STA模式并连接TCP服务器)
esp01_uart.c代码:
#include "esp01_uart.h"
extern uint8_t g_UART3_Rx_Buffer[256];
extern uint8_t g_esp8266_rx_buffer[256]; // ESP8266响应数据接收缓冲区
#define ESP01_UART_HANDLE huart2
uint8_t g_uart2_rx_buffer[256];
#define IP "192.168.160.197"
#define PORT 8080
/**
* @brief ESP8266初始化
* @param None
* @retval None
**/
void ESP8266_Init(void)
{
__HAL_UART_ENABLE_IT(&ESP01_UART_HANDLE, UART_IT_IDLE);
HAL_UART_Receive_DMA(&ESP01_UART_HANDLE, g_uart2_rx_buffer, strlen(g_uart2_rx_buffer));
while (!ESP8266_TEST());
HAL_Delay(500);
//设置为STA模式
while (!ESP8266_Net_Mode_Choose(STA));
HAL_Delay(500);
//连接WIFI
while (!ESP8266_JoinAP());
HAL_Delay(1000);
// 连接TCP模式
while (!ESP8266_Connect_TCPServer(0, IP, PORT));
HAL_Delay(500);
}
void ESP01_IDLE_CallBack(void)
{
uint8_t idle = __HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE);
if(RESET != idle){
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
HAL_UART_DMAStop(&huart2);
strcpy(g_esp8266_rx_buffer,g_uart2_rx_buffer);
//将串口2接收到的数据发送给串口3,
HAL_UART_Transmit(&huart3,g_esp8266_rx_buffer, strlen(g_esp8266_rx_buffer),100);
memset(g_uart2_rx_buffer,'\0',256);
HAL_UART_Receive_DMA(&huart2,g_uart2_rx_buffer,256);
HAL_UART_Receive_DMA(&huart3, g_UART3_Rx_Buffer, 256);
}
}
esp01_uart.h代码:
#ifndef __ESP01_UART_H
#define __ESP01_UART_H
#include "main.h"
#include "driver_esp.h"
#include "usart.h"
#include "UART3_PRINTF.h"
#include <string.h>
#include <stdio.h>
void ESP8266_Init(void);
void ESP01_IDLE_CallBack(void);
#endif
接下来是UART3的空闲中断函数,
#include "UART3_PRINTF.h"
uint8_t g_UART3_Rx_Buffer[256];
extern uint8_t g_uart2_rx_buffer[256];
int _write(int fd, char *ptr, int len) {
HAL_UART_Transmit(&huart3, (uint8_t *)ptr, len, 1000);
return len;
}
void UART3_Init(void)
{
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart3, g_UART3_Rx_Buffer, strlen(g_UART3_Rx_Buffer));
}
void UART3_IDLE_CallBack(void)
{
uint8_t idle = __HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE);
uint8_t UART3_Tx_Buffer[256];
if(RESET != idle) {
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
HAL_UART_DMAStop(&huart3);
strcpy(UART3_Tx_Buffer, g_UART3_Rx_Buffer);
//回显发送字符
HAL_UART_Transmit(&huart3, UART3_Tx_Buffer, strlen(UART3_Tx_Buffer), 100);
memset(g_UART3_Rx_Buffer, '\0', 256);
// //如果发送的字符是AT指令,发送成功就回回显"AT CMD Send OK!"
// if(strstr(UART3_Tx_Buffer,"AT") != NULL){
HAL_UART_Transmit_DMA(&huart2, UART3_Tx_Buffer, strlen(UART3_Tx_Buffer));
// HAL_UART_Transmit(&huart3, "AT CMD Send OK!\r\n", strlen("AT CMD Send OK!\r\n"), 100);
//
// }
HAL_UART_Receive_DMA(&huart3, g_UART3_Rx_Buffer, 256);
HAL_UART_Receive_DMA(&huart2,g_uart2_rx_buffer,256);
}
}
(串口3就用于将ESP-01返回值显示到串口助手上)
最后将空闲中断函数写到IT.c中
将程序下载到单片机上:
我们还可以在ESP8266_Init初始化函数中实现AP模式。
void ESP8266_Init(void)
{
__HAL_UART_ENABLE_IT(&ESP01_UART_HANDLE, UART_IT_IDLE);
HAL_UART_Receive_DMA(&ESP01_UART_HANDLE, g_uart2_rx_buffer, strlen(g_uart2_rx_buffer));
while (!ESP8266_TEST());
HAL_Delay(500);
//设置为AP模式
while (!ESP8266_Net_Mode_Choose(AP));
HAL_Delay(500);
while (!ESP8266_Set_MultiplesMode(1));
HAL_Delay(500);
//建立TCP 服务器
while(!ESP8266_Send_Cmd("AT+CIPSERVER=1\r\n","OK"));
HAL_Delay(500);
}