STM32玩转物联网07-WIFI实验

前言
上一节我们学习了串口的简单使用,本节我们增加难度,做一个demo通过AT指令控制ESP8266,使用DMA方式接收ESP8266发来的数据,后续我们便开始通过ESP8266连接物联网云平台,敬请关注。
一、准备
1. ESP8266硬件准备
准备ESP8266模块,本实验使用便宜好用的ESP-01s模块,某宝只需要5RMB左右,很适合新手测试使用,ESP-01S默认支持AT指令,所谓AT指令是说WIFI厂商把复杂的TCP/IP协议坐在了ESP8266芯片内部了,单片机只需要通过串口发送AT+CMD形式的指令即可达到调用TCP/IP协议栈的功能,极大的降低了学习和开发成本。
在这里插入图片描述

2. ESP8266固件准备
更新AT MQTT固件,进入安信可官网,下载MQTT透传固件(固件号:1471),参考之前文章即可轻松完成烧录。
在这里插入图片描述

3. 硬件连接
注意串口2连接ESP01S模块,串口1连接串口工具
在这里插入图片描述

二、实例
1. 建立工程
将上节串口实验代码复制并修改名字为:7.WiFi,通过CubeMx关闭Usart2,打开Usart3,并设置DMA方法方式接收数据。
在这里插入图片描述
取消勾选USART3 global interrupt中断回调,打开DMA1 channel3 global interrupt。
在这里插入图片描述
Keil打开工程,查看stm32f1xx_it.c中相关配置如下:

/**
  * @brief This function handles DMA1 channel3 global interrupt.
  */
void DMA1_Channel3_IRQHandler(void)
{
   
  /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */

  /* USER CODE END DMA1_Channel3_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_rx);
  /* USER CODE BEGIN DMA1_Channel3_IRQn 1 */

  /* USER CODE END DMA1_Channel3_IRQn 1 */
}

按照下图顺序,创建Application/User/Driver文件夹。
在这里插入图片描述

同时在本地根目录中创建User文件夹,文件夹中创建esp8266.c和esp8266.h两个文件。
在这里插入图片描述

在Keil中Application/User/Driver处右击选择Add Existing Files to Group ‘Application/user/Driver’…选择上述创建的esp8266.c文件,将文件加入到工程。
在这里插入图片描述

将/User文件路径按照下图方式添加到工程,以便能访问到esp8266.h文件,
在这里插入图片描述

编辑esp8266.h内容如下,增加#ifndef #define #endif格式文件,防止因为重复包含头文件导致错误;重点关注Uart_Frame_Record_t结构体,该结构体内部访问共用体,希望结构体直接访问共用体内元素,需要增加#pragma anon_unions。

#ifndef __ESP8266_H
#define __ESP8266_H 

#include "main.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>


#pragma anon_unions


// ESP8266 printf
#define ESP8266_USART(fmt, ...)  USART_printf (fmt, ##__VA_ARGS__)    
#define PC_USART(fmt, ...)       printf(fmt, ##__VA_ARGS__)       //这是串口打印函数,串口1,执行printf后会自动执行fput函数,重定向了printf。

#define RX_BUF_MAX_LEN 1024       //最大字节数

//ESP8266模式选择
typedef enum
{
   
    STA,
    AP,
    STA_AP  
}ENUM_Net_ModeTypeDef;

//网络传输层协议,枚举类型
typedef enum{
   
     enumTCP,
     enumUDP,
} ENUM_NetPro_TypeDef;
//连接号,指定为该连接号可以防止其他计算机访问同一端口而发生错误
typedef enum{
   
    Multiple_ID_0 = 0,
    Multiple_ID_1 = 1,
    Multiple_ID_2 = 2,
    Multiple_ID_3 = 3,
    Multiple_ID_4 = 4,
    Single_ID_0 = 5,
} ENUM_ID_NO_TypeDef;

//网络状态
typedef enum{
   
    WIFI_DISCONNECT= 0,
    WIFI_CONNECTED = 1,
    WIFI_GOT_IP = 2,
    WIFI_CLOUD_CONNECTED = 3,
    WIFI_CLOUD_FAILED = 4,
} ENUM_WIFI_STATUS_TypeDef;

typedef struct _Uart_Frame_Record_t   //数据帧结构体
{
   
    char Data_RX_BUF[RX_BUF_MAX_LEN];
    union 
    {
   
        __IO uint16_t InfAll;
    __IO uint16_t FramLength;
    }; 
    
}Uart_Frame_Record_t;

extern Uart_Frame_Record_t Uart_Frame_Record;

extern volatile int wifi_connect_status;


//初始化和TCP功能函数
void ESP8266_Init(uint32_t bound);
void ESP8266_ATE0(void);
bool ESP8266_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,uint32_t time);
bool ESP8266_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode);
bool ESP8266_JoinAP( char * pSSID, char * pPassWord );
bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx );
bool ESP8266_Link_Server(ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id);
bool ESP8266_UnvarnishSend ( void );
void ESP8266_ExitUnvarnishSend ( void );
uint8_t ESP8266_Get_LinkStatus ( void );

uint8_t AT_Printf(char* fmt,...);
uint8_t ESP8266_SendCMD(uint8_t *cmd, uint8_t *ack, uint16_t waittime);
uint8_t ESP8266_SendData(uint8_t *tbuf, uint16_t len);
uint8_t ESP8266_APInit(char *name, char *password);
uint8_t ESP8266_STAInit(void);
uint8_t ESP8266_STAConnect(char *name, char *password);

#endif

esp8266.c中内容如下所示:

#include "esp8266.h"
#include "usart.h"

volatile int wifi_connect_status = 0;  

Uart_Frame_Record_t Uart_Frame_Record= {
    0 };  //定义了一个数据帧结构体

//对ESP8266模块发送AT指令
// cmd 待发送的指令
// ack1,ack2;期待的响应,为NULL表不需响应,两者为或逻辑关系
// time 等待响应时间
//返回1发送成功, 0失败
bool ESP8266_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,uint32_t time)
{
   
    Uart_Frame_Record.FramLength = 0; //重新接收新的数据包
    AT_Printf("%s\r\n", cmd);
    if(ack1==0&&ack2==0)     //不需要接收数据
    {
   
        return true;
    }
    delay_ms(time);   //延时
    Uart_Frame_Record.Data_RX_BUF[Uart_Frame_Record.FramLength ] = '\0';
        
    printf("------ %s", Uart_Frame_Record.Data_RX_BUF);
    if(ack1!=0&&ack2!=0)
    {
   
        return ( ( bool ) strstr 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值