【stm32】wifi ESP8266的AT指令 实验一(HAL库开发)

零、前言

任务:这一周,想学习esp8266wifi模块的使用个驱动,学习mqtt,学会阿里云物联网的服务器使用,将自己的智能设备挂载到阿里云上,服务器可以发送指令给我的开发板,开发板完成相应功能。

而这第一步就是:先能把wifi模块驱动起来,我开发板的wifi模块是ESP8266,实验一:开发板发送AT,能够收到回复OK。就这么简单。参考的野火的资料,用的是标准固件库,而我想用HAL库开发,所以需要改一下下。

完成了程序之后,才理解了一些资料。

总结下来就是:我使用的方法就是AT指令,ESP8266烧写好固件,不需要我写wifi固件了,这里不像蓝牙芯片,之前写蓝牙芯片的程序需要考虑透传协议等等之类的,而ESP8266芯片内部集成了很多例如lwip协议等很多,很多事情不需要做,只需要给ESP8266上电,配置好串口,使能一些引脚(RST、CH_PD),最后通过串口给esp8266发送 AT指令就好了。8266会自己去解析AT指令并将结果返回给stm32.

嗯 ,听起来是不很简单,就是这么简单的一个AT指令测试程序我写了好久,卡在了好几个地方。

卡的第一个:是板载的模块上有个EN引脚要接3.3V,我是真的不知道要接,一直驱动不起来,看了下原理图查了查资料才发现这里要给它供电。然后去实验室用电烙铁直接上锡,简单粗暴。

卡的第二个:写程序的时候,没将esp8266的串口引脚和stm32的串口3引脚接正确,程序里配置错uart的tx和rx了,导致串口3驱动不起来,程序运行不出结果。

卡的第三个:串口3的波特率,tmd忘了配置了,哎我真的是!这种问题找了好久好久。。。

一、ESP8266的一些资料

二、程序代码:

bsp_uart.h


#ifndef BSP_USART_H
#define BSP_USART_H

#include "stm32f1xx.h"
#include <stdio.h>

//串口波特率
#define DEBUG_USART_BAUDRATE                    115200
#define WIFI_USART_BAUDRATE                     115200


/*******************************************************/ /*********************************************************/
//引脚定义 串口1
#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK_ENABLE()                __HAL_RCC_USART1_CLK_ENABLE()

#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_RX_PIN                      GPIO_PIN_10

#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_TX_PIN                      GPIO_PIN_9

#define DEBUG_USART_IRQHandler                  USART1_IRQHandler
#define DEBUG_USART_IRQ                 		USART1_IRQn


void Usart_SendString(UART_HandleTypeDef *usarthandle ,uint8_t *str);
void DEBUG_USART_Config(void);
int fputc(int ch, FILE *f);
int fgetc(FILE *f);

extern UART_HandleTypeDef DebugUartHandle;
extern UART_HandleTypeDef WifiUartHandle;
/*********************************************************/ /*********************************************************/

//引脚定义:串口3
#define WIFI_USART                              USART3
#define WIFI_USART_CLK_ENABLE()                 __HAL_RCC_USART3_CLK_ENABLE()

#define WIFI_USART_RX_GPIO_PORT                 GPIOB
#define WIFI_USART_RX_GPIO_PIN                  GPIO_PIN_11 //PB11(UART RXD) <--> ESP8266 UTXD
#define WIFI_USART_RX_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOB_CLK_ENABLE()

#define WIFI_USART_TX_GPIO_PORT                 GPIOB
#define WIFI_USART_TX_GPIO_PIN                  GPIO_PIN_10 //PB10(UART TXD) <--> ESP8266 URXD
#define WIFI_USART_TX_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOB_CLK_ENABLE()

#define WIFI_USART_IRQHandle                    USART3_IRQHandler
#define WIFI_UASRT_IRQ                          USART3_IRQn

void WIFI_USART_Config(void);

#endif

bsp_uart.c

#include "bsp_usart.h"

//DebugUartHandle管理串口所有配置
UART_HandleTypeDef DebugUartHandle;
//WifiUart
UART_HandleTypeDef WifiUartHandle;

//配置与硬件底层无关内容:如串口协议,其中包括波特率,奇偶校验,停止位
void DEBUG_USART_Config()
{
    DebugUartHandle.Instance = DEBUG_USART;
    
    //波特率,8位字长,1停止位,无奇偶校验,无硬件控制,收发模式
    DebugUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
    DebugUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    DebugUartHandle.Init.StopBits = UART_STOPBITS_1;//stm32f1xx_hal_uart.h
    DebugUartHandle.Init.Parity = UART_PARITY_NONE;
    DebugUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    DebugUartHandle.Init.Mode = UART_MODE_TX_RX;
    
    HAL_UART_Init(&DebugUartHandle);
    
    //使能串口接收
    __HAL_UART_ENABLE_IT(&DebugUartHandle,UART_IT_RXNE);  
}

//配置WiFi的通信的uart3
void WIFI_USART_Config()
{
    WifiUartHandle.Instance = WIFI_USART;

    WifiUartHandle.Init.BaudRate = DEBUG_USART_BAUDRATE;
    WifiUartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    WifiUartHandle.Init.StopBits = UART_STOPBITS_1;//stm32f1xx_hal_uart.h
    WifiUartHandle.Init.Parity = UART_PARITY_NONE;
    WifiUartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    WifiUartHandle.Init.Mode = UART_MODE_TX_RX;

    HAL_UART_Init(&WifiUartHandle);

    //使能串口接收
    __HAL_UART_ENABLE_IT(&WifiUartHandle,UART_IT_RXNE);
}

// mcu 底层硬件相关的配置如引脚、时钟、DMA、中断
//实际被HAL_UART_Init(stm32f1xx_hal_uart.c)该函数调用
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        GPIO_InitTypeDef GPIO_Init1;
        
        //串口1时钟 GPIO时钟
        DEBUG_USART_CLK_ENABLE();
        DEBUG_USART_RX_GPIO_CLK_ENABLE();
        DEBUG_USART_TX_GPIO_CLK_ENABLE();
        
        //配置引脚复用功能 TX 
        GPIO_Init1.Pin = DEBUG_USART_TX_PIN;
        GPIO_Init1.Mode = GPIO_MODE_AF_PP;
        GPIO_Init1.Pull = GPIO_PULLUP;
        GPIO_Init1.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_Init1);
        
        //配置Rx
        GPIO_Init1.Pin = DEBUG_USART_RX_PIN;
        GPIO_Init1.Mode = GPIO_MODE_AF_INPUT;//复用输入模式
        HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_Init1); 
        
        HAL_NVIC_SetPriority(DEBUG_USART_IRQ ,0,1);	//抢占优先级0,子优先级1
        HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );		    //使能USART1中断通道 
    }
    
    if(huart->Instance == USART3)
    {
        //串口3的配置
        GPIO_InitTypeDef GPIO_Init3;
        
        WIFI_USART_CLK_ENABLE();
        WIFI_USART_RX_GPIO_CLK_ENABLE();
        WIFI_USART_TX_GPIO_CLK_ENABLE();
        //配置Tx引脚复用功能
        GPIO_Init3.Pin = WIFI_USART_TX_GPIO_PIN;
        GPIO_Init3.Mode = GPIO_MODE_AF_PP;
        GPIO_Init3.Pull = GPIO_PULLUP;
        GPIO_Init3.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(WIFI_USART_TX_GPIO_PORT, &GPIO_Init3);
        
        //配置Rx
        GPIO_Init3.Pin = WIFI_USART_RX_GPIO_PIN;
        GPIO_Init3.Mode = GPIO_MODE_AF_INPUT;
        HAL_GPIO_Init(WIFI_USART_RX_GPIO_PORT, &GPIO_Init3); 
        
        HAL_NVIC_SetPriority(WIFI_UASRT_IRQ ,0,1);	//抢占优先级0,子优先级1
        HAL_NVIC_EnableIRQ(WIFI_UASRT_IRQ );		    //使能USART3中断通道 
    }
}





/*****************  发送字符串 **********************/
/*  HAL_UART_Transmit 函数(这是一个阻塞的发送函数,无需重复判断串口是否发送完成)
    发送每个字符,直到遇到
    空字符才停止发送。*/
void Usart_SendString(UART_HandleTypeDef *usarthandle,uint8_t *str)
{
	unsigned int k=0;
  do 
  {
      HAL_UART_Transmit(usarthandle,(uint8_t *)(str + k) ,1,1000);
      k++;
  } while(*(str + k)!='\0');
  
}
//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
	/* 发送一个字节数据到串口DEBUG_USART */
	HAL_UART_Transmit(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
	
	return (ch);
}

//重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{		
	int ch;
	HAL_UART_Receive(&DebugUartHandle, (uint8_t *)&ch, 1, 1000);
	return (ch);
}

esp8266.h

#ifndef ESP8266_H
#define ESP8266_H

#include "stm32f1xx.h"
#include <stdio.h>
/* 
ESP8266 IO  <------>    STM32 IO
URXD                    PB10(tx)
UTXD                    PB11 (rx)
CH-PD                   PB8
RST                     PB9
*/
/******* ESP8266 pins *************/
//8266 CH_PD引脚  
#define ESP8266_CH_PD_PORT                         GPIOB
#define ESP8266_CH_PD_PIN                          GPIO_PIN_8
#define ESP8266_CH_PD_CLK_ENABLE()                 __HAL_RCC_GPIOB_CLK_ENABLE()

//8266 RST引脚
#define ESP8266_RST_PORT                           GPIOB
#define ESP8266_RST_PIN                            GPIO_PIN_9
#define ESP8266_RST_CLK_ENABLE()                    __HAL_RCC_GPIOB_CLK_ENABLE()

#define ESP8266_CH_PD_ENABLE()                     HAL_GPIO_WritePin(ESP8266_CH_PD_PORT,ESP8266_CH_PD_PIN,GPIO_PIN_SET)
#define ESP8266_RST_ENABLE()                       HAL_GPIO_WritePin(ESP8266_RST_PORT,ESP8266_RST_PIN,GPIO_PIN_SET)

//functions
extern UART_HandleTypeDef WifiUartHandle;

void ESP8266_GPIO_Config(void);
void ESP8266_Init(void);


#endif

esp8266.c

#include "esp8266.h"
#include "bsp_usart.h"

//CH-PD 和RST 引脚配置
void ESP8266_GPIO_Config()
{
    //GPIO结构体
    GPIO_InitTypeDef  GPIO_InitStruct;
    //开启外设时钟
    ESP8266_CH_PD_CLK_ENABLE();
    ESP8266_RST_CLK_ENABLE();
    
    GPIO_InitStruct.Pin = ESP8266_CH_PD_PIN;	
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;  
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(ESP8266_CH_PD_PORT,&GPIO_InitStruct);
    
    GPIO_InitStruct.Pin = ESP8266_RST_PIN;
    HAL_GPIO_Init(ESP8266_RST_PORT,&GPIO_InitStruct);
}

//esp8266初始化 main调用
void ESP8266_Init(void)
{
    ESP8266_GPIO_Config();
    WIFI_USART_Config();

    //CHPD RST 初始化为高电平
    ESP8266_CH_PD_ENABLE();
    ESP8266_RST_ENABLE();
}

stm32f1xx_it.c

//串口1中断函数:stm32接收到上位机的数据
void DEBUG_USART_IRQHandler(void)
{
    uint8_t ch = 1;
    if (__HAL_UART_GET_FLAG( &DebugUartHandle, UART_FLAG_RXNE ) != RESET) 
    {
        //读寄存器
        ch=( uint16_t)READ_REG(DebugUartHandle.Instance->DR);

        //将串口1的数据 写入串口3(串口3将数据 -> esp8266)
        WRITE_REG ( WifiUartHandle.Instance->DR,ch);
    }
}

//串口3中断函数:stm32接收到esp8266的数据
void WIFI_USART_IRQHandle(void)
{
    uint8_t ch = 1;
    if (__HAL_UART_GET_FLAG( &WifiUartHandle, UART_FLAG_RXNE ) != RESET) 
    {
        ch=( uint16_t)READ_REG(WifiUartHandle.Instance->DR);

        //给串口1 
        WRITE_REG ( DebugUartHandle.Instance->DR,ch);
    }
}

main函数


int main(void)
{
    HAL_Init();
    
     /* 系统时钟初始化成72 MHz */
    SystemClock_Config();

    /* LED 端口初始化 */
    LED_GPIO_Config();
    
    //按键中断初始化
    EXTI_Key_Config();
    
    //初始化串口1
    DEBUG_USART_Config();
    
    printf("zdw is testing Wifi.....\n\n");
    
    //初始化esp8266
    ESP8266_Init();
    HAL_Delay(3000);
    
    while (1)
    {
        HAL_Delay(1000);
    }
}

三、实验结果:

能够正确相应AT指令,之后就可以调用AT指令,让wifi模块工作啦。

[20:17:33.756]收←◆zdw is testing Wifi.....

sl\0l湊s宐鉵?€l?p寍巸熿p挒帓滌?p宲騨瀄0lnn?bbp寧cl`rlp騨鄠淺0儚lbo忖ol??b寍~騨?l寧\0l`?nnl`nr彃焥bl`p髇鄠淺0r寽挏?bo忖o鞆煂弍寍騨?l`?onl`nr彃焥倻鉲`p騨鄠淺0s寽挏囔€co忏n巶?p寍~髇颸0l`?nnl?rlnr彃焥bl`r挓sbl`rl寣o淺0宲~騨焅0専鉩rnnn?\0l宐`宲弆bl\0靗€搇靗€搾??\0巰lll~rl\0靗€搶lln??\0l拰髄l\0靗€拰寪psn靗bc挏\0?\0弿co瀝ll挒r?寍掆ol瀼挏?l`rl
[20:17:33.884]收←◆?諄MEM CHECK FAIL!!!

[20:17:34.103]收←◆鋜l??
ready

[20:19:26.041]发→◇AT









□
[20:19:26.045]收←◆AT

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

OK

[20:19:31.767]收←◆
[20:19:45.765]发→◇AT+CWMODE=1










□
[20:19:45.772]收←◆AT+CWMODE=1

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

OK

[20:19:53.749]发→◇AT+CWLAP










□
[20:19:53.755]收←◆AT+CWLAP

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

busy p...

[20:19:55.885]收←◆+CWLAP:(3,"HUAWEI Mate 30 Pro 5G",-77,"46:45:84:e6:66:5c",1)
+CWLAP:(0,"HelloBike",-75,"7c:57:3c:db:a9:40",1)
+CWLAP:(0,"HelloBike-Guest",-77,"7c:57:3c:db:a9:41",1)
+CWLAP:(0,"HelloBike",-67,"48:4a:e9:5a:b9:a0",1)
+CWLAP:(0,"HelloBike-Guest",-67,"48:4a:e9:5a:b9:a1",1)
+CWLAP:(0,"ESP_1C5CE0",-78,"ca:2b:96:1c:5c:e0",1)
+CWLAP:(0,"HelloBike",-61,"48:4a:e9:5a:a9:00",6)
+CWLAP:(0,"HelloBike-Guest",-61,"48:4a:e9:5a:a9:01",6)
+CWLAP:(4,"MastermindWorld",-91,"30:0d:9e:b9:cb:b1",6)
+CWLAP:(3,"qianruan",-69,"20:76:93:40:f6:54",6)
+CWLAP:(3,"DIRECT-1GWINDOWS-9ESQKK9msGW",-80,"c2:b6:f9:3e:b2:73",6)
+CWLAP:(0,"HelloBike",-82,"48:4a:e9:5a:b4:a0",11)
+CWLAP:(0,"HelloBike-Guest",-80,"48:4a:e9:5a:b4:a1",11)
+CWLAP:(0,"HelloBike",-91,"48:4a:e9:5a:ae:00",11)
+CWLAP:(0,"HelloBike-Guest",-91,"48:4a:e9:5a:ae:01",11)
+CWLAP:(0,"HelloBike",-81,"48:4a:e9:5a:ab:20",11)
+CWLAP:(0,"HelloBike",-83,"48:4a:e9:5a:b4:00",11)
+CWLAP:(0,"HelloBike-Guest",-84,"48:4a:e9:5a:b4:01",11)

OK

四、总结

所谓万事开头难,这篇博客就只是一个wifi学习的开头,只是正确配置了wifi模块的串口,正确使能了相应的引脚,能让wifi模块工作。只是能给WiFi发送AT,esp8266回复OK。后面的实验,要把esp8266的功能函数(AT指令)封装好,发送字符串、透传模式、连接热点、使用指定协议(TCP/UDP)连接到服务器、主动和服务器断开连接、mqtt协议实现...........

猜你喜欢

转载自blog.csdn.net/zDavid_2018/article/details/108349593