单片机---------WIFI模块

1.ESP-12F模组基础知识

ESP12-F模组(安信可(Ai-Thinker)ESP8266系列模组)是一款基于乐鑫(Espressif)公司ESP8266芯片的Wi-Fi无线通信模块,广泛应用于物联网(IoT)领域。它体积小巧,集成度高,内置Wi-Fi功能和32位处理器 ,支持802.11 b/g/n无线标准。ESP12-F模组内置4MB Flash存储,拥有丰富的GPIO(通用输入输出)、UART、SPI、I2C、PWM、ADC等接口,方便与各种传感器和外设连接。ESP12-F模组功耗低,支持深度休眠,非常适合智能家居、远程控制、无线传感器、数据采集等应用场景。使用时需要注意其所有引脚电平为3.3V,不能直接接5V电源或信号,否则可能损坏芯片。

可以理解成ESP-12F是最小系统版,ESP8266是芯片

最终想要实现:

U5(采集温湿度以及可以控制设备)----------->WIFI-------------------->展示在QT服务器端

QT服务器端发送命令(点击按钮)---------------->WIFI-------------------->控制设备开关

如果要实现上述效果,WIFI组件需要将U5发送过来的数据正确发送给服务器端;将服务器发送的指令正确识别并发送给U5。但WIFI组件本身不具备这样的能力,需要烧入程序(也就是所说的固件)?那如何烧入固件?又如何与U5芯片连接来实现通信呢?

如何烧入固件?

GPIO0:控制WIFI模式,GPIO0为低电平是下载模式,高电平为运行模式

运行和下载模式

运行模式:此时串口为正常的通信功能--->接收AT指令

下载模式:此时串口为下载固件的功能

2.WIFI设备与其他设备之间的连接
1.将电脑端通过USB接口(底板type-c接口)与WIFI相连

22号引脚 TXD为WIFI模组的串口发送引脚

21号引脚 RXD为WIFI模组的串口接收引脚

【注意】为什么不直接将WIFI与USB相连?

WIFI是TTL电平信号,USB是差分信号,使用CH340进行电平转换TTL---->USB

2.U5与WIFI相连

wifi-----U5引脚--------U5内部

RX--- ---PD2----------串口5-TX

TX-------PC12---------串口5-RX

3.运行模式--->①与PC直接相连,也就是串口调试助手
3.1 AT指令

(1) 复位:AT+RST

这个指令就是复位指令,也可以通过按板子上的reset复位键进行复位,复位后会断开之前的连接,相当于重启。

(2) 设置WiFi模式:AT+CWMODE=

查询/设置 Wi-Fi 模式 (Station/SoftAP/Station+SoftAP)

0: 无 Wi-Fi 模式,并且关闭 Wi-Fi RF

1: Station 模式---------可以连接其他热点

2: SoftAP 模式---------变身成为一个路由器,可以发射wifi信号成为一个热点

3: SoftAP+Station------模式 混合模式

这里我们要联网,所以选择模式1,连接热点。

(3) 连接WiFi热点:AT+CWJAP="热点名字","热点密码"

这里我们用电脑开热点,因为大多数WiFi模组(比如我使用的ESP12-F模组 )只兼容2.4GHz频段;且ESP12-F模组是低功耗模组,而2.4G模组功耗更低,信号穿透能力更强,覆盖范围更广,复杂环境下稳定性更高。

(4) 连接服务器:AT+CIPSTART="TCP","服务器IP",服务器端口

(5) 发送数据:AT+CIPSEND=5 //发送五个字节给服务器

【注意】

这种方式只能实现单次固定长度数据的发送

输入后会出现箭头,表示等待串口向服务器发送五个字节的数据。

3.2什么是透传模式

(1)简介:

透传模式(Transparent Transmission)是一种数据传输方式,设备或系统在通信过程中不对数据内容进行解析或处理,仅作为通道将原始数据完整、无修改地传递给目标端。常见于串口通信、网络协议、物联网设备等场景。

也就是ESP8266作为一个搬运共,不去辨别串口发送过来的数据是什么,只是无脑的发送给服务器。

(2) 设置透传

1.设置透传模式:AT+CIPMODE=1

2.使能透传发送:AT+CIPSEND

之后就可以连续发送数据;

想退出透传模式可以发送"+++",就会退出透传模式:

4.使用单片机控制WIFI模块
1. 关键开关设置:
  • S2/S3:拨向 MCU方向(连接ESP8266与STM32)
  • S4:拨到 运行模式(使能ESP8266正常工作)
  • Type-C:插入核心板(供电+调试通信)
2. 整体流程
  1. PC通过串口调试助手(USART1)发送指令给STM32。

  2. STM32通过空闲中断接收完整指令,解析指令。

  3. STM32通过UART5向ESP8266发送相应的AT指令或数据。

  4. ESP8266执行操作(如连接服务器、发送数据等)。

  5. ESP8266将服务器返回的数据通过UART5传给STM32。

  6. STM32将结果通过USART1格式化输出到PC串口调试助手。

3. 2.wifi驱动代码
复制代码
#include "wifi.h"

int connect_flag = 0; // 是否连接成功的标志
int tt_flag = 0;	  // 是否有网络发过来的透传数据标志

char WIFI_Config0(int time) // 找到ready 返回 没有找到返回1
{
    memset(WiFi_RX_BUF, 0, 1024);
    WiFi_RxCounter = 0;
    while (time--)
    {
        HAL_Delay(100);
        if (strstr((char *)WiFi_RX_BUF, "ready"))
        {
            break;
        }
        // u1_USART ("WIFI_Config0:=%s",WiFi_RX_BUF);
    }
    if (time > 0)
        return 0;
    else
        return 1;
}

char WIFI_Config(int time, char *cmd, char *response) // 等待时间 发送内容 判断返回的内容
{
    memset(WiFi_RX_BUF, 0, 1024);
    WiFi_RxCounter = 0;
    ESP8266_USART("%s\r\n", cmd);
    while (time--)
    {
        HAL_Delay(100);
        if (strstr((char *)WiFi_RX_BUF, response))
        {
            break;
        }
        // u1_USART("%d ", time);
    }
    if (time > 0)
        return 0;
    else
        return 1;
}

char WIFI_Router(int time) // 配置WIFI名和密码
{
    memset(WiFi_RX_BUF, 0, 1024);
    WiFi_RxCounter = 0;
    //	ESP8266_USART("AT+CIPMUX=0");
    //	HAL_Delay(100);
    ESP8266_USART("AT+CWJAP=\"%s\",\"%s\"\r\n", ID, PASSWORD);
    while (time--)
    {
        HAL_Delay(1000);
        if (strstr((char *)WiFi_RX_BUF, "OK"))
        {
            break;
        }
        u1_USART("连接路由倒计时: %d\r\n ", time);
    }
    if (time > 0)
        return 0;
    else
        return 1;
}

char WIFI_ConnectTCP(int time) // 配置TCP
{
    memset(WiFi_RX_BUF, 0, 1024);
    WiFi_RxCounter = 0;
    ESP8266_USART("AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", ServerIP, ServerPort);
    while (time--)
    {
        HAL_Delay(100);
        if (strstr((char *)WiFi_RX_BUF, "OK"))
        {
            break;
        }
        u1_USART("正在建立TCP连接 :%d ", time);
    }
    if (time > 0)
        return 0;
    else
        return 1;
}

enum WIFI_STATE
{
    WIFI_READY = 0,
    WIFI_CONFIG1,
    WIFI_ROUTER,
    WIFI_CONFIG2,  //进入透传模式
    WIFI_CONNECT, //连接服务器
    WIFI_CONFIG3,
    WIFI_COMPLETE	//连接完成
    };

#define WAIT_TIME 1000

void WIFI_Connect()//状态机
{
    int state = WIFI_READY;  //默认等待复位
    while (1)
    {
        if(state == WIFI_COMPLETE)
        {
            u1_USART("连接服务器完成并开启透传!\r\n");
            memset(WiFi_RX_BUF,0,1024);
            //WIFI_SendData("hello world");
            break;  //这里直接跳出while(1)循环即可
        }
        switch (state)
        {
            case WIFI_READY://检测是否手动复位了
                /*0、按键复位*/
                u1_USART("0、准备按键复位!\r\n");
                if (WIFI_Config0(100))//判是否收到ready
                {
                    u1_USART("按键复位失败!\r\n");
                    HAL_Delay(WAIT_TIME);
                }
                else//成功了 找到了
                {
                    u1_USART("按键复位成功!\r\n");
                    state = WIFI_CONFIG1;
                }
                break;

            case WIFI_CONFIG1:
                /*1、配置WIFI模式*/
                u1_USART("1、准备配置WIFI模式!\r\n");
                if (WIFI_Config(50, "AT+CWMODE=1\r\n", "OK"))//发送命令 检测OK
                {
                    u1_USART("配置WIFI模式失败!\r\n");
                    HAL_Delay(WAIT_TIME);
                    break;
                }
            else//成功
                u1_USART("配置WIFI模式成功!\r\n");
				u1_USART("\r\n");
            /*2、重启(命令方式)*/
            u1_USART("2、准备复位!\r\n");
            if (WIFI_Config(50, "AT+RST\r\n", "ready"))
            {
                u1_USART("复位失败!\r\n");
                HAL_Delay(WAIT_TIME);
                break;
            }
            else
                u1_USART("复位成功!\r\n");
            u1_USART("\r\n");
            /*3、取消自动连接*/
            u1_USART("3、准备取消自动连接\r\n");
            if (WIFI_Config(50, "AT+CWAUTOCONN=0\r\n", "OK"))//取消热点自动连接 检测OK
            {
                u1_USART("取消自动连接失败!\r\n");
                HAL_Delay(WAIT_TIME);
                break;
            }
            else
                u1_USART("取消自动连接成功!\r\n");
 
            WiFi_RxCounter = 0;
            state = WIFI_ROUTER;
            break;
        case WIFI_ROUTER:
            /*4、连接路由器*/
            u1_USART("4、准备连接路由器\r\n");
            if (WIFI_Router(50))//连接热点并检测是否连接成功
            {
                u1_USART("连接路由器失败!\r\n");
                HAL_Delay(WAIT_TIME);
            }
            else
            {
                u1_USART("连接路由器成功!\r\n");
                state = WIFI_CONFIG2;
            }
            break;
        case WIFI_CONFIG2:
            /*5、配置单路连接模式*/
            u1_USART("5、准备配置单路连接模式!\r\n");
            if (WIFI_Config(50, "AT+CIPMUX=0\r\n", "OK"))//配置单路连接
            {
                u1_USART("配置单路连接模式失败!\r\n");
                HAL_Delay(WAIT_TIME);
                break;
            }
            else
            {
                u1_USART("配置单路连接模式成功!\r\n");
            }
            u1_USART("\r\n");
            /*6、开启透传模式*/
            u1_USART("6、准备开启透传模式\r\n");
            if (WIFI_Config(50, "AT+CIPMODE=1\r\n", "OK"))
            {
                u1_USART("开启透传模式失败!\r\n");
                HAL_Delay(WAIT_TIME);
                break;
            }
            else
            {
                u1_USART("开启透传模式成功!\r\n");
            }
            state = WIFI_CONNECT;
            break;
        case WIFI_CONNECT:
            /*7、建立TCP连接*/
            u1_USART("7、准备建立TCP连接\r\n");
            if (WIFI_ConnectTCP(50))//连接TCP
            {
                u1_USART("建立TCP连接失败!\r\n");
                HAL_Delay(WAIT_TIME);
            }
            else
            {
                u1_USART("建立TCP连接成功!\r\n");
                state = WIFI_CONFIG3;
            }
            break;
        case WIFI_CONFIG3:
            /*8、进入透传模式*/
            u1_USART("8、准备进入透传模式\r\n");
            if (WIFI_Config(50, "AT+CIPSEND\r\n", "\r\nOK\r\n\r\n>"))
            {
                u1_USART("进入透传模式失败!\r\n");
                HAL_Delay(WAIT_TIME);
            }
            else
            {
                u1_USART("进入透传模式成功!\r\n");
                state = WIFI_COMPLETE;
                connect_flag = 1;
                break;
            }
        default:
            break;
        }
    }
}
 
//int WIFI_SendData(const char *data)
//{
//	ESP8266_USART("%s", data);
//	//u1_USART("数据发送完成\r\n");
//	return 0;
//	if (WIFI_Config(10, "AT+CIPSEND=5\r\n", ">"))
//	{
//		ESP8266_USART("%s", data);
//		u1_USART("数据发送完成\r\n");
//		return 0;
//	}
//	else
//	{
//		u1_USART("数据发送失败!\r\n");
//		return -1;
//	}
//}

/r/n

/r:回到当前行行首;

/n:回到下一行的这个位置

相关推荐
程序员 _孜然3 小时前
Ubuntu/Debian修改网卡名字enP3p49s0为eth0
linux·运维·驱动开发·嵌入式硬件·ubuntu·debian
hahaha60163 小时前
pcie实现虚拟串口
stm32·单片机·fpga开发
Hard_August5 小时前
STM32窗口看门狗(WWDG)深度解析:精准守护嵌入式系统的实时性
stm32·单片机·嵌入式硬件·物联网
李永奉5 小时前
51单片机-实现外部中断模块教程
单片机·嵌入式硬件·51单片机
你怎么知道我是队长13 小时前
STM32CubeIDE V1.9.0下载资源链接
stm32·单片机·嵌入式硬件
曾哥嵌入式13 小时前
Stm32通过ESP8266 WiFi连接阿里云平台
stm32·嵌入式硬件·阿里云
顾念`14 小时前
单片机常用通信协议(二)
单片机·嵌入式硬件
Ronin-Lotus1 天前
嵌入式硬件篇---手柄
嵌入式硬件·手柄
芯岭技术1 天前
普冉PY32F002A单片机用LPTIM唤醒stop模式
单片机·嵌入式硬件