基于stm32f103c8t6标准库的ESP01S的WiFi模块代码

ESP01S.h

#ifndef ESP01S_H
#define ESP01S_H

#include "stm32f10x.h"

#define ESP_BUFFER_SIZE 1024  // 接收缓冲区大小
#define USART2_BAUDRATE 115200  // 串口波特率


void ESP01S_Init(void);

void ESP01S_Send_ATCmd(char *cmd);

void ESP01S_Clear_DataBuffer(void);

unsigned char ESP01S_Get_RECDataFlag(void);

void ESP01S_Get_RECData(char result[ESP_BUFFER_SIZE]);

#endif

ESP01S.c

#include "ESP01S.h"

unsigned char RecTempByte;  // 临时存储接收到的字节
unsigned char ESP_RECBuffer[ESP_BUFFER_SIZE];  // 接收缓冲区
int Buffer_Num = 0;  // 接收缓冲区索引

/**
 * 初始化USART2
 * @note TXD=PA2, RXD=PA3, 波特率:115200
 */
void ESP01S_Init(void)
{
    // 开启时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // GPIO初始化
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  // PA2配置为复用推挽输出

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  // PA3配置为上拉输入

    // USART2初始化
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = USART2_BAUDRATE;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART2, &USART_InitStructure);

    // 配置中断
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    // 配置NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);

    // 使能USART2
    USART_Cmd(USART2, ENABLE);
}

/**
 * 发送单个字节
 * @param Byte:要发送的字节
 */
void ESP01S_SendByte(unsigned char Byte)
{
    USART_SendData(USART2, Byte);
    while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);  // 等待发送完成
}

/**
 * 发送AT指令
 * @param cmd:AT指令字符串
 */
void ESP01S_Send_ATCmd(char *cmd)
{
    while (*cmd != '\0')
    {
        ESP01S_SendByte(*cmd++);
    }
}

/**
 * 清空接收缓冲区
 */
void ESP01S_Clear_DataBuffer(void)
{
    Buffer_Num = 0;
}

/**
 * 检查是否接收到数据
 * @return 0:无数据,1:有数据
 */
unsigned char ESP01S_Get_RECDataFlag(void)
{
    return Buffer_Num > 0 ? 1 : 0;
}

/**
 * 获取接收数据
 * @param result:存储接收数据的数组
 */
void ESP01S_Get_RECData(char result[ESP_BUFFER_SIZE])
{
    int i;
    for (i = 0; i < Buffer_Num && i < ESP_BUFFER_SIZE; i++)
    {
        result[i] = ESP_RECBuffer[i];
    }
    result[i] = '\0';  // 添加字符串结束符
    ESP01S_Clear_DataBuffer();  // 清空缓冲区
}

/**
 * USART2中断处理函数
 */
void USART2_IRQHandler(void)
{
    if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET)
    {
        RecTempByte = USART_ReceiveData(USART2);  // 读取接收到的数据
        if (Buffer_Num < ESP_BUFFER_SIZE)
        {
            ESP_RECBuffer[Buffer_Num++] = RecTempByte;  // 存储到缓冲区
        }
        else
        {
            // 缓冲区溢出保护
            Buffer_Num = ESP_BUFFER_SIZE;  // 防止溢出
        }
        USART_ClearITPendingBit(USART2, USART_IT_RXNE);  // 清除中断标志位
    }
}

说明

使用的是安可信的AT固件

ESP01S_AT_CMD.h

#ifndef ESP01S_ATCMD_H_
#define ESP01S_ATCMD_H_

#include "ESP01S.h"

#define ESP01S_TIMEOUT 5000  // 重启命令的超时时间(毫秒)

int ESP_AT_RST(void);

int ESP_AT_Get_WIFI_Name(char *wifiname);

int ESP_AT_Link_WIFI(char *wifiname, char *wifipwd);

int ESP_AT_Exit_WIFI(void);

int ESP_AT_Get_IP(char *cmd);

#endif

ESP01S_AT_CMD.c

#include "ESP01S_AT_CMD.h"
#include "Delay.h"
#include <stdio.h>
#include <string.h>

/**
 * 重启 ESP01S 模块
 * 
 * 发送 `AT+RST` 命令以重启模块,并检查返回的 `OK` 以确认重启成功。
 * 
 * @return 1:重启成功,0:重启失败
 */
int ESP_AT_RST(void) {
    unsigned char result = 0;  // 初始化结果为失败
    char response[ESP_BUFFER_SIZE];  // 用于存储模块返回的数据

    // 清空接收缓冲区
    ESP01S_Clear_DataBuffer();

    // 发送重启命令
    ESP01S_Send_ATCmd("AT+RST\r\n");

    // 等待模块响应
    Delay_s(1); 

    // 再次清空缓冲区,确保之前的响应被清空
    ESP01S_Clear_DataBuffer();

    // 发送测试命令以检查模块是否重启成功
    ESP01S_Send_ATCmd("AT\r\n");

    // 等待模块响应
    Delay_ms(500);

    // 检查是否有返回数据
    if (ESP01S_Get_RECDataFlag()) {
        ESP01S_Get_RECData(response);  // 获取返回数据
        if (strstr(response, "OK") != NULL) {
            result = 1;  // 如果包含 "OK",则重启成功
        }
    }

    return result;  // 返回重启结果
}

/**
 * 获取当前连接的 WiFi 网络名称(SSID)
 * 
 * 发送 `AT+CWJAP?` 命令以获取当前连接的 WiFi 信息,并解析返回的 SSID。
 * 
 * @param wifiname 用于存储 WiFi 名称的字符串
 * @return 1:成功获取 WiFi 名称,0:失败
 */
int ESP_AT_Get_WIFI_Name(char *wifiname) {
    unsigned char result = 0;  // 初始化结果为失败
    char response[ESP_BUFFER_SIZE];  // 用于存储模块返回的数据

    // 清空接收缓冲区
    ESP01S_Clear_DataBuffer();

    // 发送命令
    ESP01S_Send_ATCmd("AT+CWJAP?\r\n");

    // 等待模块响应
    Delay_ms(100);

    // 检查是否有返回数据
    if (ESP01S_Get_RECDataFlag()) {
        ESP01S_Get_RECData(response);  // 获取返回数据

        // 检查是否包含 WiFi 信息
        if (strstr(response, "+CWJAP:") != NULL) {
            // 解析 WiFi 名称
            char *start = strstr(response, "+CWJAP:\"") + 8;  // 找到 "+CWJAP:" 后的位置
            if (start != NULL) {
                char *end = strchr(start, '"');  // 找到第一个结束引号位置
                if (end != NULL) {
                    *end = '\0';  // 将结束引号替换为字符串结束符
                    strcpy(wifiname, start);  // 复制 WiFi 名称到 wifiname
                    result = 1;  // 获取成功
                }
            }
        } else if (strstr(response, "ERROR") != NULL) {
            result = 0;  // 如果返回 "ERROR",则获取失败
        }
    }

    return result;
}

/**
 * 连接到指定的 WiFi 网络
 * 
 * 发送 `AT+CWJAP=<ssid>,<pwd>` 命令以连接到指定的 WiFi 网络,并检查返回的 `WIFI CONNECTED` 以确认连接成功。
 * 
 * @param wifiname WiFi 名称(SSID)
 * @param wifipwd WiFi 密码
 * @return 1:连接成功,0:连接失败
 */
int ESP_AT_Link_WIFI(char *wifiname, char *wifipwd) {
    char cmd[128];  // 用于存储 AT 命令的缓冲区
    char response[ESP_BUFFER_SIZE];  // 用于存储模块返回的数据

    // 清空接收缓冲区
    ESP01S_Clear_DataBuffer();

    // 构造 AT+CWJAP 命令
    sprintf(cmd, "AT+CWJAP=\"%s\",\"%s\"\r\n", wifiname, wifipwd);

    // 发送连接命令
    ESP01S_Send_ATCmd(cmd);

    // 等待模块响应
    Delay_s(5);

    // 检查是否有返回数据
    if (ESP01S_Get_RECDataFlag()) {
        ESP01S_Get_RECData(response);  // 获取返回数据

        // 检查是否连接成功
        if (strstr(response, "WIFI CONNECTED") != NULL) {
            return 1;  // 如果返回 "WIFI CONNECTED",则连接成功
        } else if (strstr(response, "ERROR") != NULL || strstr(response, "FAIL") != NULL) {
            return 0;  // 如果返回 "ERROR" 或 "FAIL",则连接失败
        }
    }

    return 0;  // 如果超时仍未连接成功,返回失败
}

/**
 * 断开当前连接的 WiFi 网络
 * 
 * 发送 `AT+CWQAP` 命令以断开当前连接的 WiFi,并检查返回的 `WIFI DISCONNECT` 或 `OK` 以确认断开成功。
 * 
 * @return 1:断开成功,0:断开失败
 */
int ESP_AT_Exit_WIFI(void) {
    unsigned char result = 0;  // 初始化结果为失败
    char response[ESP_BUFFER_SIZE];  // 用于存储模块返回的数据

    // 清空接收缓冲区
    ESP01S_Clear_DataBuffer();

    // 发送断开命令
    ESP01S_Send_ATCmd("AT+CWQAP\r\n");

    // 等待模块响应
    Delay_ms(100);

    // 检查是否有返回数据
    if (ESP01S_Get_RECDataFlag()) {
        ESP01S_Get_RECData(response);  // 获取返回数据

        // 检查是否断开成功
        if (strstr(response, "WIFI DISCONNECT") != NULL || strstr(response, "OK") != NULL) {
            result = 1;  // 如果返回 "WIFI DISCONNECT" 或 "OK",则断开成功
        } else if (strstr(response, "ERROR") != NULL) {
            result = 0;  // 如果返回 "ERROR",则断开失败
        }
    }

    return result;
}

/**
 * 获取模块的 IP 地址
 * 
 * 发送 `AT+CIFSR` 命令以获取模块的 IP 地址,并解析返回的 `STAIP` 以确认获取成功。
 * 
 * @param RES_IP 用于存储获取到的 IP 地址的字符串
 * @return 1:成功获取 IP 地址,2:未连接 WiFi,0:失败
 */
int ESP_AT_Get_IP(char *RES_IP) {
    unsigned char result = 0;  // 初始化结果为失败
    char response[ESP_BUFFER_SIZE];  // 用于存储模块返回的数据

    // 清空接收缓冲区
    ESP01S_Clear_DataBuffer();

    // 发送获取 IP 地址的命令
    ESP01S_Send_ATCmd("AT+CIFSR\r\n");

    // 等待模块响应
    Delay_ms(100);

    // 检查是否有返回数据
    if (ESP01S_Get_RECDataFlag()) {
        ESP01S_Get_RECData(response);  // 获取返回数据

        // 检查是否包含 STAIP
        if (strstr(response, "STAIP") != NULL) {
            // 解析 IP 地址
            char *start = strstr(response, "STAIP,\"") + 7;  // 找到 "STAIP," 后的引号位置
            if (start != NULL) {
                char *end = strchr(start, '"');  // 找到结束引号位置
                if (end != NULL) {
                    *end = '\0';  // 将结束引号替换为字符串结束符
                    strcpy(RES_IP, start);  // 复制 IP 地址到 RES_IP

                    // 检查是否为 0.0.0.0
                    if (strcmp(RES_IP, "0.0.0.0") == 0) {
                        result = 2;  // 未连接 WiFi
                    } else {
                        result = 1;  // 获取成功
                    }
                }
            }
        }
    }

    return result;  // 返回结果
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值