WiFi ESP-12F
·
一、项目目标与硬件基础
- 核心目标:实现设备接入云端服务器,完成远程通信。
- 传输层:调通 TCP 通信。
- 应用层:调通 MQTT 通信(文档主要详述了TCP部分)。
- 硬件模块:
- ESP-12F/ESP-12E:支持WIFI联网。
- ESP32:双模,支持WIFI + BT/BLE(文档中部分指令表参考了ESP32,但操作对象主要是ESP8266/ESP-12F)。
- 烧录器:配合ESP-01S或ESP-12F使用。
二、固件准备与烧录 (关键步骤)
- 获取资源:从安信可官网下载支持 TCP 和 MQTT 的AT固件及烧录工具。
- 进入烧录模式:
- 硬件接线:将 IO0管脚拉低 (GND)。
- 复位模块。
- 烧录过程:
- 选择对应固件和端口 (如CH340)。
- 注意:烧录前必须关闭占用串口的软件(如XCOM),否则报错。
- 若卡在同步,需手动按复位键。
- 验证:烧录成功后,切换回工作模式(拔掉IO0跳线帽),发送
AT指令,返回OK即成功
三、AT指令集核心操作
所有指令需注意:波特率通常为115200,指令结尾必须加 \r\n。
1. WIFI连接配置 (Station模式)
- 设置模式:
AT+CWMODE=1(1=Station客户端模式, 2=AP热点模式, 3=混合模式)。 - 连接路由:
AT+CWJAP="WIFI账号","WIFI密码"- 注意:ESP-12F仅支持 2.4GHz 频段。
2. TCP通信配置 (透传模式)
- 设置透传:
AT+CIPMODE=1(1=透传模式, 0=非透传)。 - 建立连接:
AT+CIPSTART="TCP","服务器IP",端口(例如:192.168.137.1, 8080)。 - 发送数据:
- 进入发送状态:
AT+CIPSEND - 直接输入要发送的数据。
- 退出发送模式:单独发送
+++(注意:不需要加\r\n)。
- 进入发送状态:
四、STM32与ESP-12F联合开发流程
- 硬件连接:
- STM32 USART2 TX -> ESP-12F RX
- STM32 USART2 RX -> ESP-12F TX
- 共地 (GND)。
- 软件初始化:
- 初始化 STM32 的 USART2。
- 开启 接收中断 和 空闲中断 (用于接收不定长数据/响应)。
- 代码逻辑流:
- 恢复出厂设置 (可选):
AT+RESTORE - 设置WIFI模式 (
CWMODE=1) -> 等待OK。 - 连接WIFI (
CWJAP) -> 等待WIFI GOT IP。 - 设置透传 (
CIPMODE=1) -> 等待OK。 - 连接服务器 (
CIPSTART) -> 等待CONNECT OK。 - 进入透传发送 (
CIPSEND) -> 发送数据。 - 如需停止发送,发送
+++。
- 恢复出厂设置 (可选):
代码流程:
/*************************
函数名称:Wifi_Tcp_Init(void)
函数功能:TCP初始化
返回值:无
形参:void
作者:me
版本:1.0
*************************/
void Wifi_Tcp_Init(void)
{
u8 ret;
Usart2_Init(115200);
//退出发送模式
USART2_SendString("+++");
Delay_Ms(100);
//发送AT\r\n,跳过格式报错
USART2_SendString("AT\r\n");
Delay_Ms(100);
//①设置WIFI模式为客户端模式 AT+CWMODE=1\r\n
ret = Esp_SendData((u8 *)"AT+CWMODE=1\r\n",5000);
if(ret == 0) printf("设置WIFI模式为客户端模式成功\r\n");
//②连接软路由(连接WIFI)AT+CWJAP=\"Class8\",\"12345678\"\r\n
ret = Esp_SendData((u8 *)"AT+CWJAP=\"Class8\",\"12345678\"\r\n",10000);
if(ret == 0) printf("连接AP成功\r\n");
//③设置传输模式为透传模式 AT+CIPMODE=1
ret = Esp_SendData((u8 *)"AT+CIPMODE=1\r\n",10000);
if(ret == 0) printf("设置为透传模式成功\r\n");
//④连接服务器 AT+CIPSTART=\"TCP\",\"192.168.5.26\",5789\r\n
ret = Esp_SendData((u8 *)"AT+CIPSTART=\"TCP\",\"192.168.5.26\",5789\r\n",10000);
if(ret == 0) printf("服务器连接成功\r\n");
//⑤进入透传,开始传输数据到服务器 发送数据模试AT+CIPSEND\r\n
Esp_SendData((u8 *)"AT+CIPSEND\r\n",10000);
if(ret == 0) printf("进入发送数据模式成功\r\n");
}
初始化及 Esp_SendData()功能函数
#include "usart2wifi.h"
/*************************
函数名称:Usart2_Init(u32 baud)
函数功能:Usart2初始化函数
返回值:无
形参:u32 baud
作者:me
版本:1.0
U2 TX - PA2 U2 RX - PA3 APB1
*************************/
void Usart2_Init(u32 baud)
{
//打开串口/IO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
//初始化IO口 复用模式
//初始化IO口 复用模式
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Low_Speed;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);//PD8服用到USART2
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);//PD9服用到USART2
//初始化USART2控制器
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = baud;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 无硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No; //无校验
USART_InitStruct.USART_StopBits = USART_StopBits_1; //一位停止位
USART_InitStruct.USART_WordLength = USART_WordLength_8b; //8位数据位
USART_Init(USART2, &USART_InitStruct);
//中断使能
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//接收中断,接收数据断,接受到一个字节触发
USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);//空闲中断,接收结束后经过1个帧还没有数据的时候为1
//NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;//要配置的中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 4;//抢占优先级(值越小优先级越高)
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//次级优先级(值越小优先级越高)
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能,失能中断
NVIC_Init( &NVIC_InitStruct);
//U2 使能
USART_Cmd(USART2,ENABLE);
}
U2 u2;
/*************************
函数名称:USART2_IRQHandler(void)
函数功能:USART2接收中断服务函数
返回值:无
形参:无
作者:me
版本:1.0
函数说明:这里结构体由于是全局的变量,则初始值为0
*************************/
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE))//如果接收到了数据 0中断未触发 1触发
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清除接收中断标志位
u2.buff[u2.len++] = USART_ReceiveData(USART2);
}
if(USART_GetITStatus(USART2, USART_IT_IDLE))//进入空闲中断
{
u2.buff[u2.len] = '\0';
USART2->SR;//清标志位
USART2->DR;//清标志位
u2.len = 0;
u2.flag = 1;
printf("%s", u2.buff); // 打印接收到ESP-12F的数据
}
}
/*************************
函数名称:USART2_SendByte(u8 data)
函数功能:USART2字节发送函数
返回值:无
形参:u8 data
作者:me
版本:1.0
*************************/
void USART2_SendByte(u8 data)
{
//等待上一个字节发送完成 完成的时候为0 则需非
while(!(USART_GetFlagStatus(USART2, USART_FLAG_TXE)));//TXE发送寄存器为空
USART_SendData(USART2,data);
//等待这个字节发送完成
while(!(USART_GetFlagStatus(USART2, USART_FLAG_TC)));//TC发送完成
}
/*************************
函数名称:USART2_SendString(u32 data)
函数功能:USART2字符串发送函数
返回值:无
形参:u32 data
作者:me
版本:1.0
*************************/
void USART2_SendString(char *str)
{
while(*str != '\0')
{
USART2_SendByte(*str++);
}
}
/*************************
函数名称:Esp_SendData(u8 *at,u16 timeout)
函数功能:发送AT指令并判断响应
返回值:1 代表AT指令失败, 0 代表 AT指令成功
形参:u8 *at,发送的指令
u16 timeout 超时计数
作者:me
版本:1.0
*************************/
u8 Esp_SendData(u8 *at,u16 timeout)
{
u16 count = 0;
USART2_SendString((char *)at);
Delay_Ms(100);
while(1)
{
while(!u2.flag)
{
Delay_Ms(1);
count++;
if(count >= timeout)
{
u2.len = 0;//防止数据接到一半,没有接完,此时就返回0 重新开始接
return 1;
}
}
u2.flag = 0;
//需要在u2.buff 中找 ok
if(strstr((const char*)u2.buff,"OK") != NULL)
{
return 0;
}
}
}
更多推荐


所有评论(0)