STM32 (十五)ESP8266WIFI

简介

1 ESP8266wifi 模块

低功耗串口WiFi模块ESP8266内置一个Tensilica(泰思立达) Xtensa架构的32位处理器L106,具有5级流水线(ARM CortexM3是3级流水线),最大时钟速度为160MHz,可以使用高达16MB的外部SPI Flash。 该模块采用串口与MCU(或其他串口设备)通信,内置 TCP/IP协议栈,能够实现串口与 WIFI 之间的转换。通过该模块,传统的串口设备只需要简单的串口配置,即可通过WiFi传输自己的数据。

STM32 (十五)ESP8266WIFI_第1张图片

wifi模块具有两种模式:AP模式 、Station模式

AP模式:就是我们平常用的热点,如无线路由器,手机热点。

Station模式:就是我们连接这些热点的设备,如手机,iPad,笔记本电脑。

2AT命令介绍

我们想要与esp8266wifi模块进行通信,那么就需要AT命令进行。就好比我们要和英国国人进行交流时,我们就要用英语交流。在这里,就需要用到esp8266的AT指令进行和pc之间的通信。

AT 即Attention,它由拨号调制解调器(Modem)的发明者贺氏公司(Hayes)为了控制Modem发明的控制协议。协议本身采用文本,每个命令均以AT打头,因此得名。90年代初,AT指令仅被用于Modem操作。

几年后,主要的移动电话生产厂商诺基亚、爱立信、摩托罗拉和HP共同为GSM 研制了一整套AT指令,其中就包括对SMS的控制。AT指令在此基础上演化并被加入GSM 07.05标准以及现在的GSM07.07标准,其中拨打电话、收发短信、收发传真等全部由AT命令实现。而在随后的GPRS控制,3G模块,以及工业上常用的PDU,均采用AT命令集来控制,这样AT指令也就成为了完全标准化和比较健全的标准。

3AT命令格式

AT指令是以AT作为开头,\r\n字符结束的字符串,每个指令执行成功与否都有相应的返回。其他的一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提示,接收端可做相应的处理。

STM32 (十五)ESP8266WIFI_第2张图片

注意:不同模块的AT命令可能不一样的,这要对着模块的AT指令手册来查看。可以通过esp8266应答的信息来判断你们之间是否建立通信了。(每当发送一个AT指令之后,相应地就会在结尾给PC发 OK或者ERROR)

4 常用的AT指令

这里讲解一下我们ESP8266 01S常用的AT指令:

4.1.AT+RST

重启、复位ESP8266命令

4.2.AT

AT确认模块是否正常工作

4.3.AT+CWMODE_CUR=1

设置WiFi为Station模式和使能DHCP服务

4.4 AT+CWJAP_CUR=“输入WiFiID”

输入路由器连接密码” 连接无线路由器

4.5 AT+CWJAP_CUR=“输入WiFiID”

4.6 AT+CIPSERVER=1,8080",

设置端口8080

工程创建

1 高速时钟选择外部8Mhz的晶振

STM32 (十五)ESP8266WIFI_第3张图片

2 开启debug调试功能

STM32 (十五)ESP8266WIFI_第4张图片

3 时钟树

STM32 (十五)ESP8266WIFI_第5张图片

4 打开串口2设置

STM32 (十五)ESP8266WIFI_第6张图片

5 并且使能串口中断

STM32 (十五)ESP8266WIFI_第7张图片

6.选择LED

STM32 (十五)ESP8266WIFI_第8张图片

7选择MDK_ARM编译器

STM32 (十五)ESP8266WIFI_第9张图片

8生成文件库的选择

STM32 (十五)ESP8266WIFI_第10张图片

代码讲解:

代码修改

1 添加My_esp8266.c

#include "My_esp8266.h"
#include "string.h"
#include "usart.h"
 
void u2_printf(char* fmt);
char esp8266_send_cmd(char *cmd,char *ack,u16 waittime); 
 
 
void esp8266_test(void)//测试
{
if(esp8266_send_cmd("AT","OK",50));
 
}
 
char esp8266_send_cmd(char *cmd,char *ack,u16 waittime)//发送指令和检查接收
{
 
    u2_printf(cmd);
    
    if(ack&&waittime)        
    {
            while(--waittime)    
            {
                HAL_Delay(10);
                if(strstr((const char*)RxBuffer,(const char*)ack)) //输入on,LED0亮
                {
                    Uart2_Rx_Cnt=0;
                    memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组    
                    return 1;
         
                }
            }
 
    }
 
    return 0;
}
 
 
void esp8266_start_trans(void)//ESP8266初始化
{
    
    esp8266_send_cmd("AT+CWMODE=2","OK",50);//设置为AP模式
 
    esp8266_send_cmd("AT+RST","ready",20);//重启
    
    HAL_Delay(1000);       
    HAL_Delay(1000);
    HAL_Delay(1000);
    HAL_Delay(1000);
    
    esp8266_send_cmd("AT+CWSAP=\"ESP8266\",\"12345678\",1,4","OK",200);//设置WiFi名称、密码,模式
    esp8266_send_cmd("AT+CIPMUX=1","OK",20);//进入透传模式
    esp8266_send_cmd("AT+CIPSERVER=1,8080","OK",200);//设置端口8080
    esp8266_send_cmd("AT+CIPSEND","OK",50);//开始发送数据
}
 
uint8_t esp8266_quit_trans(void)//退出透传模式
{
    uint8_t result=1;
    u2_printf("+++");
    HAL_Delay(1000);                    
    result=esp8266_send_cmd("AT","OK",20);
    return result;
 
}
 
 
void u2_printf(char* fmt)  
{  
 
    uint8_t num=0;
  char my_ch[50]={0};
    while(*fmt!=0)
    my_ch[num++]=*fmt++;
    
    my_ch[num++]='\r';
    my_ch[num++]='\n';
    
    HAL_UART_Transmit(&huart2, (uint8_t *)my_ch,num, 0xffff);
   while(HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);
 
}
 
 


2.添加My_esp8266.h

#ifndef __My_esp8266_H__
#define __My_esp8266_H__
 
#include "main.h"
 
typedef uint16_t u16  ;
 
 
extern void esp8266_test(void);
extern void u2_printf(char* fmt);
extern char esp8266_send_cmd(char *cmd,char *ack,u16 waittime); 
extern void esp8266_start_trans(void);
 
#endif

3.main.h的Exported types中添加代码

/* USER CODE BEGIN ET */
extern char RxBuffer[256];
extern uint8_t Uart2_Rx_Cnt;
/* USER CODE END ET */

4.main.c的Private includes中添加代码

/* USER CODE BEGIN Includes */
#include 
#include "My_esp8266.h"
/* USER CODE END Includes */

5. main.c的Private variables中添加代码

/* USER CODE BEGIN PV */
#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;            //接收中断缓冲
uint8_t Uart2_Rx_Cnt = 0;        //接收缓冲计数
uint8_t my_test_v = 0 ;
char my_order[15]={0};
char receive_flag=0;
/* USER CODE END PV */

6.main.c主函数下面的USER CODE BEGIN 4下面添加中断回调函数,如下

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
 
    if(Uart2_Rx_Cnt >= 255)  //溢出判断
    {
        Uart2_Rx_Cnt = 0;
        memset(RxBuffer,0x00,sizeof(RxBuffer));            
    }
    else
    {
        static uint8_t Uart2_count=0;
        
        RxBuffer[Uart2_Rx_Cnt] = aRxBuffer;   //接收数据转存
        if(receive_flag==0)
        {
        if(RxBuffer[Uart2_Rx_Cnt-Uart2_count]=='<')
        {    
            Uart2_count++;
        if((RxBuffer[Uart2_Rx_Cnt]=='>')||Uart2_count>=14)
        {
            uint8_t My_i=0;
        for(int i=Uart2_Rx_Cnt-Uart2_count+1;i

7.主函数代码

int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
esp8266_start_trans();
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
     //     HAL_Delay(20);
        if(receive_flag)
    {
        receive_flag=0;
        if(strstr((const char*)my_order,(const char*)"")) //输入on,LED0亮
        {
            Uart2_Rx_Cnt=0;
            memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组    
            memset(RxBuffer,0x00,sizeof(my_order)); //清空数组    
            my_test_v=1;
        }
        else if(strstr((const char*)my_order,(const char*)""))
        {
                    Uart2_Rx_Cnt=0;
            memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组    
            memset(RxBuffer,0x00,sizeof(my_order)); //清空数组    
          my_test_v=0;
        }
        else
            {
            Uart2_Rx_Cnt=0;
            memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组    
            memset(RxBuffer,0x00,sizeof(my_order)); //清空数组    
        
        }
            
     }
        if(my_test_v==1)    
            HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
        else
          HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET );
            
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

手机端控制

1.esp8266和核心板的连接只需要四个引脚,vcc(3.7—5v的稳定电源,不稳定的话会不断重启),gnd,rx,tx。其中,模块的rx接核心板的tx,tx接核心板的rx。

2. 初始化(4s)后,模块就会发出名字为esp8266的热点,密码为12345678。

STM32 (十五)ESP8266WIFI_第11张图片

3 手机接入后打开“tcp连接”app(这个热点没有网络,有些手机连接后一会儿后自动就断开了,所以要设置下,我是直接把数据流量关了就行了)

STM32 (十五)ESP8266WIFI_第12张图片

4 连接(IP地址一般是192.168.4.1不正确的话需要用串口助手给wifi模块发送AT指令查看连接设备的地址,当然也可以程序上发送后在线调试看数组)

STM32 (十五)ESP8266WIFI_第13张图片

5 发送数据,记住要加英文输入法的“<>”,就能控制灯的亮灭了。

STM32 (十五)ESP8266WIFI_第14张图片

需要注意的是,esp8266wifi模块相当于一个下好程序的核心板,你只需要通过给它发送串口的AT指令来进行控制它的各种动作。初始化也不是对引脚初始化,是通过串口对它发送AT指令。所以初始化后如果不给esp8266断电的话是不用再次初始化的,因为每次初始化后重启会话4s的时间,所以想不断下程序来调试的话,可以把初始化函数(esp8266_start_trans();)注释了,就不用每次都额外等4s的时间了。

你可能感兴趣的:(STM32,CubeMX,stm32)