打印
[STM32F0]

STM32 ESP8266 无线模块使用

[复制链接]
1016|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
略略u|  楼主 | 2024-6-30 23:33 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
文章介绍了ESP8266的特性以及连网模式(AP,station),使用串口(USART)接入STM32,实现连网功能。

ESP8266介绍
esp8266 内置超低功耗 Tensilica L106 32 位 RISC 处理器,CPU 时钟速度最高可达 160 MHz,支持实时操作系统 (RTOS) 和 Wi-Fi 协议栈。标准数字外设接口、天线开关、射频 balun、功率放大器、低噪放大器、过滤器和电源管理模块等。低功耗

模块参数



使用特权

评论回复
沙发
略略u|  楼主 | 2024-6-30 23:33 | 只看该作者
UART成帧
ESP8266 判断 UART 传来的数据时间间隔,若时间间隔大于 20ms, 则认为一帧结束;否则, 一直接收数据到上限值 2KB, 认为一帧结束。 ESP8266 模块判断UART 来的数据一帧结束后, 通过 WIFI 接口将数据转发出去。
成帧时间间隔为 20ms, 一帧上限值为 2KB。

使用特权

评论回复
板凳
略略u|  楼主 | 2024-6-30 23:33 | 只看该作者
无线组网方式
ESP8266 支持 softAP 模式, station 模式, softAP + station 共存模式三种。

SoftAP: 即无线接入点, 是一个无线网络的中心节点,类似于无线路由器。手机 用户设备、 其他 ESP8266 station 接口等均可以作为 station 连入ESP8266, 组建成一个局域网。(透传)


使用特权

评论回复
地板
略略u|  楼主 | 2024-6-30 23:33 | 只看该作者
Station:即无线终端, 是一个无线网络的终端。
通过连接路由器(AP) 连入 internet ,可向云端服务器上传、 下载数据。用户可随时使用移动终端(手机、 笔记本等) ,通过云端连接ESP8266。



使用特权

评论回复
5
略略u|  楼主 | 2024-6-30 23:34 | 只看该作者
网络相关的模块,比如4G、lora等模块都有AT指令,使用AT指令配置模块,ESP8266的AT指令如下

AT指令

使用特权

评论回复
6
略略u|  楼主 | 2024-6-30 23:34 | 只看该作者
基础指令

使用特权

评论回复
7
略略u|  楼主 | 2024-6-30 23:34 | 只看该作者
wifi 功能指令

使用特权

评论回复
8
略略u|  楼主 | 2024-6-30 23:34 | 只看该作者
TCP/IP 指令

使用特权

评论回复
9
略略u|  楼主 | 2024-6-30 23:34 | 只看该作者
STM32连接模块与配置

RST复位引脚,与CH_PD片选引脚,在模式初始化阶段使用。RST拉高,CH_PD先复位 再置位,模块正常工作。采用串口方式与STM32进行通信,使用串口中断,有数据时,去读取数据。

使用特权

评论回复
10
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
GPIO配置
// CH_PD引脚
// Enables or disables the High Speed APB (APB2) peripheral clock
#define      macESP8266_CH_PD_APBxClock_FUN                   RCC_APB2PeriphClockCmd
//RCC_APB2Periph: specifies the APB2 peripheral to gates its clock
#define      macESP8266_CH_PD_CLK                             RCC_APB2Periph_GPIOB  
//PORT
#define      macESP8266_CH_PD_PORT                            GPIOB
//PIN
#define      macESP8266_CH_PD_PIN                             GPIO_Pin_8

RST引脚
#define      macESP8266_RST_APBxClock_FUN                     RCC_APB2PeriphClockCmd
#define      macESP8266_RST_CLK                               RCC_APB2Periph_GPIOB
#define      macESP8266_RST_PORT                              GPIOB
#define      macESP8266_RST_PIN                               GPIO_Pin_9
//

static void ESP8266_GPIO_Config ( void )
{
        GPIO_InitTypeDef GPIO_InitStructure;
        macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE );
        //CH_PD引脚                                                                                  
        GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN;       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure );         
        //RST引脚
        macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE );                                           
        GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN;       
        GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure );         
}

使用特权

评论回复
11
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
USART配置
#define      macESP8266_USART_BAUD_RATE                       115200

#define      macESP8266_USARTx                                USART3
#define      macESP8266_USART_APBxClock_FUN                   RCC_APB1PeriphClockCmd
#define      macESP8266_USART_CLK                             RCC_APB1Periph_USART3

#define      macESP8266_USART_GPIO_APBxClock_FUN              RCC_APB2PeriphClockCmd
#define      macESP8266_USART_GPIO_CLK                        RCC_APB2Periph_GPIOB     
//发送TX
#define      macESP8266_USART_TX_PORT                         GPIOB   
#define      macESP8266_USART_TX_PIN                          GPIO_Pin_10
//接受RX
#define      macESP8266_USART_RX_PORT                         GPIOB
#define      macESP8266_USART_RX_PIN                          GPIO_Pin_11
//中断
#define      macESP8266_USART_IRQ                             USART3_IRQn
#define      macESP8266_USART_INT_FUN                         USART3_IRQHandler

extern struct  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;
  };
       
} strEsp8266_Fram_Record;

struct  STRUCT_USARTx_Fram strEsp8266_Fram_Record = { 0 };

//USART 的 NVIC中断
static void ESP8266_USART_NVIC_Configuration ( void )
{
        NVIC_InitTypeDef NVIC_InitStructure;
       
        /* Configure the NVIC Preemption Priority Bits */  
        NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );

        /* Enable the USART3 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ;         
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

}
static void ESP8266_USART_Config ( void )
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
       
       
        /* config USART clock */
        macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );
        macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );
       
        /* USART GPIO config */
        /* Configure USART Tx as alternate function push-pull */
        GPIO_InitStructure.GPIO_Pin =  macESP8266_USART_TX_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure);  
  
        /* Configure USART Rx as input floating */
        GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure);
       
        /* USART1 mode config */
        USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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(macESP8266_USARTx, &USART_InitStructure);
       
       
        /* 中断配置 */
        USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断
        USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口空闲中断

        ESP8266_USART_NVIC_Configuration ();
        USART_Cmd(macESP8266_USARTx, ENABLE);
}

使用特权

评论回复
12
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
中断函数
void macESP8266_USART_INT_FUN ( void )
{       
        uint8_t ucCh;
        //获取RX中断状态
        if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET )
        {
                ucCh  = USART_ReceiveData( macESP8266_USARTx );//接收数据
               
                if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )   //长度判断  
                        //向BUF缓冲区中写入数据ucCh,FramLength 在不断增加
                        strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
        }
        //获取IDEL中断状态          ,数据帧接收完毕
        if ( USART_GetITStatus( macESP8266_USARTx, USART_IT_IDLE ) == SET )
        {
        strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;//条件置位
                ucCh = USART_ReceiveData( macESP8266_USARTx );                                                            
                ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
    }       
}

使用特权

评论回复
13
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
ESP8266使用流程
ESP8266的一般使用顺序,ESP8266连接当前环境的热点,与服务器建立TCP连接,传输数据。

AT+CWMODE=1:设置工作模式(STA模式)
AT+RST:模块重启(生效工作模式)
AT+CWJAP=“111”,“11111111”:连接当前环境的WIFI热点(热点名,密码)
AT+CIPMUX=0:设置单路连接模式
AT+CIPSTART=“TCP”,“xxx.xxx.xxx.xxx”,xxxx:建立TCP连接
AT+CIPMODE=1:开启透传模式
AT+CIPSEND:透传模式下,传输数据
+++:退出透传模式

使用特权

评论回复
14
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
程序的主处理流程

void ESP8266_StaTcpClient_UnvarnishTest ( void )
{
        uint8_t ucStatus;
        char cStr [ 100 ] = { 0 };
        //使能PD_CH
        macESP8266_CH_ENABLE();
        //AT测试
        ESP8266_AT_Test ();
        //选择网络模式
        ESP8266_Net_Mode_Choose ( STA );
    //连接AP
    while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );       
        //启动多连接关闭
        ESP8266_Enable_MultipleId ( DISABLE );
        //连接服务器IP 端口号
        while ( !        ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );
        //设置模式进入透传模式
        while ( ! ESP8266_UnvarnishSend () );

    while ( 1 )//进入循环
        {               
                //此处可以修改数据源,此处为一串字符串,也可以是从开发版上获取传感器数据,比如温湿度传感器
                sprintf ( cStr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" );
                ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 );  //发送数据
               
                Delay_ms ( 100 );
               
                if ( ucTcpClosedFlag )  //检测是否丢失链接
                {
                        ESP8266_ExitUnvarnishSend ();        //如果丢失,退出透传模式
                       
                        do ucStatus = ESP8266_Get_LinkStatus ();      //获取链接状态
                        while ( ! ucStatus );
                       
                        if ( ucStatus == 4 )                                             //失去链接后重连
                        {
                                while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
                                while ( !ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );                       
                        }
                        while ( ! ESP8266_UnvarnishSend () );               
                }
        }

使用特权

评论回复
15
略略u|  楼主 | 2024-6-30 23:35 | 只看该作者
发送AT指令函数
/*
cmd:待发送的命令,
reply1,reply2期待的回复
waittime 等待时间
*/
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{   
        strEsp8266_Fram_Record .InfBit .FramLength = 0;               //数据长度置零
        macESP8266_Usart ( "%s\r\n", cmd );
        if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //没有收到数据
                return true;
       
        Delay_ms ( waittime );    //延时函数
        //中断接收函数
        strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ]  = '\0';
        macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );
        if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
                return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ||
                                                 ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
        else if ( reply1 != 0 )
                return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );
        else
                return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
}

使用特权

评论回复
16
略略u|  楼主 | 2024-6-30 23:36 | 只看该作者
选择NET模式

bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{
        switch ( enumMode )
        {
                case STA:
                        return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 );
            case AP:
                    return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 );
            case STA_AP:
                    return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 );
            default:
                    return false;
  }
}

使用特权

评论回复
17
略略u|  楼主 | 2024-6-30 23:36 | 只看该作者
链接wifi, AT+CWJAP
/*
pSSID用户名
pPassWord 密码
*/
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{
        char cCmd [120];
        sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
        return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );
}

使用特权

评论回复
18
略略u|  楼主 | 2024-6-30 23:37 | 只看该作者
连接外部服务器 AT+CIPSTART

bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
{
        char cStr [100] = { 0 }, cCmd [120];
  switch (  enumE )
  {
                case enumTCP:
                  sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum );
                  break;
                case enumUDP:
                  sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum );
                  break;
                default:
                        break;
  }

  if ( id < 5 )
    sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr);
  else
          sprintf ( cCmd, "AT+CIPSTART=%s", cStr );
        return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );
}

使用特权

评论回复
19
略略u|  楼主 | 2024-6-30 23:37 | 只看该作者
获取链接状态AT+CIPSTATUS
uint8_t ESP8266_Get_LinkStatus ( void )
{
        if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) )
        {
                if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )
                        return 2;
                else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )
                        return 3;
                else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )
                        return 4;               
        }
        return 0;
}

使用特权

评论回复
20
略略u|  楼主 | 2024-6-30 23:37 | 只看该作者
发送数据"AT+CIPSEND=
/*
返回值
1,发送成功
0,发送失败
*/

bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{
        char cStr [20];
        bool bRet = false;
        if ( enumEnUnvarnishTx )
        {
                macESP8266_Usart ( "%s", pStr );
                bRet = true;
        }

        else
        {
                if ( ucId < 5 )
                        sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );
                else
                        sprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );
                ESP8266_Cmd ( cStr, "> ", 0, 1000 );
                bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );
  }
        return bRet;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

603

帖子

0

粉丝