目录
一、固件库模板
二、准备资料
-
固件库模板
-
MDK5开发环境
-
stm32参考手册
-
UART串口协议
-
stm32中断概念
-
ESP8266模块资料
-
利用固件库模板点灯工程(下面第三行,手动狗头)
-
CH340 USB→TTL模块
-
ESP8266模块
-
手机软件
实验程序已经发布到百度网盘,本文末有链接可以自取
串口协议查看这篇博客USART串口协议
stm32中断概念STM32中断应用概括
ESP8266模块资料:ESP8266
串口调试工具 :https://pan.baidu.com/s/1V-jRJzb0INDXDLo9I4CJ6A 提取码:0000
网络助手(PC):https://pan.baidu.com/s/1EeDtr7eW-mIuOEZa1_4BWA 提取码:0000
网络调试助手(安卓)链接: https://pan.baidu.com/s/1uDGpyGt8VyUzcZXmWfTqhw 提取码: 0000
三、简介
ESP8266
是一款超低功耗的UART-WiFi 透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和物联网应用设计,可将用户的物理设备连接到Wi-Fi 无线网络上
,进行互联网或局域网通信,实现万物互联功能。
- 支持STA/AP/STA+AP 三种工作模式
- 内置TCP/IP协议栈,支持多路TCP Client连接
- 支持UART/GPIO数据通信接口
- 支持Smart Link 智能联网功能
- 内置32位MCU,可兼作应用处理器
- 3.3V 单电源供电
- 支持丰富的Socket AT指令
1. 引脚
标号 | PIN | 引脚说明 |
---|---|---|
1 | 3V3 | 模块供电正极 |
2 | RST | 低电平复位,高电平工作(默认高) |
3 | EN | 使能端,需要进入命令模式时接3.3V |
4 | TX | 发送端 |
5 | RX | 接收端 |
6 | IO0 | 工作模式选择:悬空:FlashBoot,工作模式;下拉:UARTDownload,下载模式 |
7 | IO2 | (1)开机上电时必须为高电平,禁止硬件下拉;(2)内部默认已拉高 |
8 | GND | 模块供电负极 |
本模块使用USART协议,具体请看下面两个博客,这里就不继续讲解了
USART串口协议
四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)
2. 无线组网
ESP8266 支持 softAP 模式, station 模式, softAP + station 共存模式三种。
利用 ESP8266 可以实现十分灵活的组网方式和网络拓扑。
- SoftAP: 即无线接入点, 是一个无线网络的中心节点。通常使用的无线路由器就是一个无线接入点。
- Station:即无线终端, 是一个无线网络的终端。
2.1 ESP8266 在 SoftAP 模式
ESP8266 作为 softAP(热点
),手机、 电脑、 用户设备、 其他 ESP8266 station 接口等均可以作为 station(终端用户
) 连入ESP8266, 组建成一个局域网。
2.2 ESP8266 在 station 模式
ESP8266 作为 station,通过路由器(AP) 连入 internet ,可向云端服务器上传、 下载数据。用户可随时使用移动终端(手机、 笔记本等) ,通过云端监控 ESP8266 模块的状况, 向 ESP8266 模块发送控制指令。
简单的来说就是ESP连接热点(可以上网),也可以手机上网,此时手机可以控制ESP8266
2.3 ESP8266 在 SoftAP + station 共存模式
ESP8266 支持 softAP+station 共存的模式,用户设备、 手机等可以作为station 连入 ESP8266 的 softAP 接口,同时, 可以控制 ESP8266 的 station接口通过路由器(AP) 连入 internet。
3、透传功能
透传, 即透明传输功能
。 Host 通过 uart 将数据发给ESP8266, ESP8266 再通过无线网络将数据传出去;ESP8266 通过无线网络接收到的数据,同理通过uart 传到 Host。 ESP8266 只负责将数据传到目标地址,不对数据进行处理,发送方和接收方的数据内容、 长度完全一致,传输过程就好像透明一样。
透传需要先建立连接:
Q: 什么是透传模式?
A: 透传模式影响发送数据的方式。
如果不开启透传模式,发送数据前都必须先发送指令AT+CIPSEND=,例如:
AT+CIPSEND=4
OK
> //在 > 后面输入要上传的数据
开启了透传模式:
AT+CIPMODE=1 进入透传模式
AT+CIPSEND 之后发送的所有内容将全部当成数据
退出透传模式: 发送数据"+++
"就可以了。注意:此时“+++”后面,不接发送新行
!
注意:透传只能在单连接模式下进行,所以在建立连接之前一定要用(AT+CIPMUX=0 设置单连接)
> AT+CIPMODE=1
> CIPMUX and CIPSERVER must be 0
4. 基本配置(所有AT指令都必须换行)
命令 | 描述 |
---|---|
基础指令 | |
AT | 测试 AT 启动 |
AT+RST | 重启模块 |
AT+GMR | 查看版本信息 |
wifi 功能指令 | |
AT+CWMODE | 选择 WIFI 应用模式 |
AT+CWJAP | 加入 AP |
AT+CWLAP | 列出当前可用 AP |
AT+CWQAP | 退出与 AP 的连接 |
AT+CWSAP | 设置 AP 模式下的参数 |
AT+ CWLIF | 查看已接入设备的 IP |
TCP/IP 指令 | |
AT+CIPSTATUS | 获得连接状态 |
AT+CIPSTART | 建立 TCP 连接或注册 UDP 端口号 |
AT+CIPSEND | 发送数据 |
AT+CIPCLOSE | 关闭 TCP 或 UDP |
AT+CIFSR | 获取本地 IP 地址 |
AT+CIPMUX | 启动多连接 |
AT+CIPSERVER | 配置为服务器 |
AT+CIPMODE | 设置模块传输模式 |
AT+CIPSTO | 设置服务器超时时间 |
+IPD | 接收到的数据 |
AT命令的详细说明在ESP8266这里面什么都有
4. 模式配置
4.1 STA 模式
STA 模式: ESP8266模块通过路由器连接互联网,手机或电脑通过互联网实现对设备的远程控制。
配置步骤:
1. AT+CWMODE=1 设置模组为STA模式。(串口助手)
2. AT+CWLAP 查询附近 WIFI(串口助手)
3. AT+CWJAP="1202","12345678" 连接 WIFI(串口助手)
4. AT+CIPMUX=0 打开单连接(串口助手)
5. AT+CIPSTART="TCP","192.168.2.6",808 (自己对应的ip地址,端口号随便,只要没有被占用都行)
6. AT+CIPMODE=1 使用透传模式
7. AT+CIPSEND
4.2 AP 模式
AP 模式: ESP8266模块作为热点,实现手机或电脑直接与模块通信,实现局域网无线控制。
配置步骤:
1. AT+CWMODE=2
2. AT+CIPAP="192.168.4.1"
3. AT+CWSAP="ESP8266","12345678",1,0
4. AT+CIPMUX=1
5. AT+CIPSERVER=1,8888
6. AT+CIPSTO=1800
7. AT+CIFSR
四、实验
1.硬件设计
- ESP8266与串口通信
GND接GND
VCC接3.3
RXD—CH340的TXD
TXD—CH340的RXD - 用ESP8266控制MCU
CH340的TXD-----USART1的RX引脚相连(c8t6 的PA10)
CH340的RXD-----USART1的TX引脚相连(c8t6 的PA9)
ESP8266的TXD-----USART2的RX引脚相连(c8t6 的PA3)
ESP8266的RXD-----USART2的TX引脚相连(c8t6 的PA2)
2.软件设计
-
使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;
-
初始化 GPIO,并将 GPIO 复用到 USART 上;
-
配置 USART 参数;
-
配置中断控制器并使能 USART 接收中断;
-
使能 USART;
-
在 USART 接收中断服务函数实现数据接收和发送。
2.1 复制工程 (复制stm32-USART串口通讯工程)
四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)
2.2 新建hc_05文件(打开工程)
2.3 编写代码
1. 使用串口助手和网络助手实现ESP8266通信
ESP8266的波特率为115200,8位数据位、1位停止位、无奇偶校验的通信格式。
-
发送
AT
,回复OK
-
AT+CWMODE=1 设置模组为STA模式。
-
AT+CWLAP 查询附近 WIFI
-
AT+CWJAP=“XXX”,“XXXX” 连接 WIFI(必须为第3步能查找到的)
-
AT+CIPMUX=0 打开单连接(否则不能透传)
-
AT+CIPSTART=“TCP”,“192.168.2.6”,808 (自己对应的ip地址,端口号随便,只要没有被占用都行)
-
AT+CIPMODE=1 使用透传模式
-
AT+CIPSEND
2. 使用ESP8266 STA模式实现透传功能
2.1 复制工程 (复制stm32-USART串口通讯工程)
四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)
2.2 新建文件,打开工程,添加路径
usart.c
在USART1_IRQHandler方法下面添加 usart2的初始化和中断
struct STRUCT_USARTx_Fram strEsp8266_Fram_Record = {
0 };
volatile uint8_t ucTcpClosedFlag = 0;
void uart2_init(u32 bound) {
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//USART2_TX GPIOA.2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA2
//USART2_RX GPIOA.3初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3
//Usart2 NVIC 配置
NVIC_PriorityGroupConfig(macNVIC_PriorityGroup_x);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART2, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//使能串口总线空闲中断
USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART2); //读取接收到的数据
//USART_SendData(USART1,Res);
if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) ) //预留1个字节写结束符
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ] = Res;
}
if ( USART_GetITStatus( USART2, USART_IT_IDLE ) == SET ) //数据帧接收完毕
{
strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;
Res = USART_ReceiveData( USART2 );
ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
}
}
usart.h
添加strHC05_Fram_Record结构体和uart2_init(u32 bound)函数
extern struct STRUCT_USARTx_Fram //串口数据帧的处理结构体
{
//STRUCT_USARTx_Fram 读取的数据
char Data_RX_BUF [ RX_BUF_MAX_LEN ];
union {
__IO u16 InfAll;
struct {
__IO u16 FramLength :15; // 14:0
__IO u16 FramFinishFlag :1; // 15
} InfBit;
};
}strUSART_Fram_Record,strEsp8266_Fram_Record;
//如果想串口中断接收,请不要注释以下宏定义
void uart1_init(u32 bound);
void uart2_init(u32 bound);
esp8266.c
#include "esp8266.h"
#include "delay.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
/********************************************************************************
*
RST -- A4
EN -- A5
TX -- A2(USART2_TX)
RX -- A3(USART2_RX)
********************************************************************************/
static void ESP8266_GPIO_Config ( void );
/**
* @brief ESP8266初始化函数
* @param 无
* @retval 无
*/
void ESP8266_Init ( void )
{
ESP8266_GPIO_Config ();
ESP8266_RST_HIGH_LEVEL();
ESP8266_CH_DISABLE();
}
/**
* @brief 初始化ESP8266用到的GPIO引脚
* @param 无
* @retval 无
*/
static void ESP8266_GPIO_Config ( void )
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/* 配置 CH_PD 引脚*/
ESP8266_CH_PD_APBxClock_FUN ( ESP8266_CH_PD_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = ESP8266_CH_PD_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init ( ESP8266_CH_PD_PORT, & GPIO_InitStructure );
/* 配置 RST 引脚*/
ESP8266_RST_APBxClock_FUN ( ESP8266_RST_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = ESP8266_RST_PIN;
GPIO_Init ( ESP8266_RST_PORT, & GPIO_InitStructure );
}
/*
* 函数名:ESP8266_Cmd
* 描述 :对WF-ESP8266模块发送AT指令
* 输入 :cmd,待发送的指令
* reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系
* waittime,等待响应的时间
* 返回 : 1,指令发送成功
* 0,指令发送失败
* 调用 :被外部调用
*/
bool ESP8266_Cmd ( char *cmd, char *reply1, char *reply2, u32 waittime )
{
strEsp8266_Fram_Record .InfBit .FramLength = 0; //从新开始接收新的数据包
ESP8266_Usart ( "%s\r\n", cmd );
if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据
return true;
Delay_ms ( waittime ); //延时
//增加一个结束符。
strEsp8266_Fram