wifi模块基于AT指令集实现收发功能(笔记记录)

wifi模块基于AT指令集实现收发功能(笔记记录)

几个我参考的链接:

1、ESP8266笔记 ---- 常用AT指令_esp8266 at-优快云博客
2、esp8266WIFI模块教程:正点原子ATK-ESP8266进行网络通信,单片机与电脑,单片机与手机发送数据_正点原子esp8266-优快云博客
3、【常用模块】ESP8266 WIFI串口通信模块使用详解(实例:附STM32详细代码)_正点原子wifiesp8266提供代码-优快云博客
最有用的是乐鑫官方给的AT指令操作示例:
4、TCP-IP AT 示例 - ESP32 - — ESP-AT 用户指南 latest 文档 (espressif.com)
在这里插入图片描述
主要参考esp32做tcp客户端,建立单连接,实现uart wifi透传
注意:
1、模块可能没有下载AT指令集的固件,可能需要烧录一下对应的固件,参考链接在这里:
ESP开发(一)ESP8266-01烧录AT固件_esp 01固件-优快云博客
2、B站有一个视频教程:
快速了解wifi模块 这个视频就够了 ESP8266_哔哩哔哩_bilibili
看完这个视频就可以上手wifi模块了,30分钟可以两倍速看。

AT固件下载

首先是ESP32引脚分布(这里要注意烧录模式的时候和正常工作模式GPIO0的接线不同,还有一个注意点就是GPIO15必须接到低),有关ESP32的详细引脚定义可以参照下面这个链接:esp-12f_product_specification_zh_v1.0.pdf (ai-thinker.com)
在这里插入图片描述

模组启动模式说明
在这里插入图片描述
推荐的电路连接方式(正常工作模式)
在这里插入图片描述

如何下载?

下载模式需要把只需要把GPIO0接到地,rst先浮空,配置好flash下载软件之后,先点击擦除,之后会等待上电复位,将rst用杜邦线触碰一下地,即可开始烧录,此时等待烧录完毕,将GPIO接到高电平,重新上电即可正常使用AT指令集。
1、使用ESP12F飞线图
在这里插入图片描述

2、Flash下载软件参数配置
在这里插入图片描述

注意:目前只测试了安信可的固件可以下载成功,并且这个使用起来功能一切正常,固件存放位置在目录固件下载下面。偏移地址一定是0x0000,先选erase,上电复位之后自动开始烧录程序。

判断是否烧录成功?

使用串口助手调试(波特率是115200,具体参数配置见下图),上电之后会有复位信息输出,并且返回会有个ready字符串,同时发送AT\r\n(使用串口助手发送新行可以不用\r\n)会自动返回AT OK,表示烧录成功,之后可以正常使用了。
在这里插入图片描述

AT指令简单使用

就是在用单片机操作之前会先用串口调试助手,测试一下这个wifi芯片是不是好的,同时也可以熟悉一下,at常用的几条指令的返回值是什么。同样这里也有一个链接:
简单记录ESP8266WIFI模块网络调试过程,测试通过。_esp8266 ch340 联网测试-优快云博客

使用战舰V3实现wifi连接的收发

收发演示视频

wifi模块演示

程序实现

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "mywifi.h"

// 全局变量定义
u8 receive_number = 0; // 记录接收长度
u8 temp_rec_num = 0;
u8 rev_finish_flag = 0;					// 接收完成标志
u8 wifi_connect_flag = 0;				// 1表示wifi连接成功
char mywifi_recv_buf[MAX_LENGTH] = {0}; // 接收数组

/**
 * @description: 功能描述
 * 1、初始化延时函数 led灯
 * 2、wifi芯片自检
 * 3、自检成功之后会软件复位一下wifi芯片,之后关闭指令回环显示
 * 4、设置wifi芯片为站点模式,按照定义好的wifi账号的密码连接热点,这个热点可以是电脑也可以时候,只要电脑和手机连上一个wifi就可以,注意频段是2.4G
 * 5、查看一下wifi芯片分配到ip地址,可能每次分配的地址不一样,这样要配置的上位机服务器的ip就要随之改变一下,这个到时候我教你嘿嘿
 * 6、根据上位机服务器ip地址,连接上服务器
 * 7、开启wifi芯片透传 和透输模式,这个时候它就和一个串口无差异了,可以把之前的485写的协议往上套了
 * 8、在透传模式下给服务器发送20次你好之后,推出透传模式,断开和服务器的连接
 * 9、结束
 * @return {*}
 */
int main(void)
{
	delay_init(); // 延时函数初始化
	LED_Init();	  // 初始化与LED连接的硬件接口
	uart_init(115200);
	mywifi_uart_init();
	int rec = 0;
	int num = 0;
	u8 test[] = {"hello!\r\n"}; // 打印测试数据
	delay_ms(5000);
	if (mywifi_self_test())
	{
		mywifi_soft_rst();
		delay_ms(500);
		mywifi_polldispaly(0);
		delay_ms(20);
		mywifi_set_mode(1);		   // 设置站点模式
		mywifi_connect_host();	   // 连接之后需要判断是否连接成功,由于连接需要一定时间
		mywifi_get_ip();		   // 获取站点动态分配地址,注意在合理只进行了打印,没有存储,带busy等待。
		mywifi_connect_sever();	   // 连接服务器
		mywifi_set_transparent(1); // 开启透传模式
		LED1 = 0;				   // wifi芯片自检成功会亮灯,但是不一定会连上wifi,wifi是否连上通过串口1打印结果
	}
	while (1)
	{
		LED0 = 0;	   // 0表示灯亮
		delay_ms(300); // 延时300ms
		LED0 = 1;
		delay_ms(300);								  // 延时300ms
		u8 nums[10] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 2}; // 自定义数据
		// mywifi_data_send(nums, sizeof(nums) / sizeof(nums[0]));//数据发送测试
		mywifi_data_send(test, sizeof(test) / sizeof(test[0])); // 字符发送测试
		num++;
		if (num > 20)
		{
			delay_ms(2000);			   // 需要等待一秒,结束透传
			mywifi_set_transparent(0); // 透传关闭测试成功
			break;
		}
#if 0
// 前期搭建测试用
// rec = USART_ReceiveData(USART2); // 接收也没问题
// USART_SendData(USART2, rec);	 // 发送测试
//  printf("test ok");
//  mywifi_send_nbytes("nihaoya\n\r",10);
//  mywifi_send_at_cmd(test, "nihaone", 30,sizeof(test)/sizeof(test[0]));//sizeof不能对传入的参数进行求长度
//  int flag=mywifi_send_at_cmd(test, "AT\r\nOK", 20, sizeof(test) / sizeof(test[0]));// 发送AT测试成功,第一次可能会失败,需要多测试几次、
//  // 测试成功之后给这个东东软件复位一下,复位之后不用接收这个里面的数据了
#endif
	}
	while (1)
	{
		LED0 = 0;	   // 0表示灯亮
		delay_ms(300); // 延时300ms
		LED0 = 1;
		delay_ms(300);
	}
}

mywifi.h

/*
 * @Author: <lan> <1791060296@qq.com>
 * @Date: 2024-01-04 20:23:27
 * @LastEditors: <lan> <1791060296@qq.com>
 * @LastEditTime: 2024-01-05 16:03:18
 * @FilePath: \实验1 跑马灯实验\HARDWARE\MYWIFI\mywifi.h
 * @Description:
 *
 * Copyright (c) 2024 by ${git_name_email}, All Rights Reserved.
 */
#ifndef __MYWIFI_H
#define __MYWIFI_H

#include "sys.h"
#include "stdbool.h"

// 使用AT指令连接电脑热点,wifi模块作为客户端,电脑作为服务器
// 实现两边数据收发
// AT指令定义,注意这里发送的时候是asiic码发送,结束要以换行结束
// 从wifi芯片的接收还是用到空闲中断,判断空闲之后开始处理数据
// 这里要做wifi初始化(正式传输数据前)和数据传输两个区分(后续通透模式传输数据),设置两个标志位
// 上电之后发送一个AT测试wifi芯片是否正常
// 存在一个问题,就是进入透传模式之后没有推出,之后的指令都没用了,需要给wifi芯片重启
// 所以需要手动断开透传模式,断开和服务器的连接

// 注意这里介个宏定义目前没有用到,热点名称,密码等是在函数定义上方,需要按照你电脑分配的自行修改
#define DEMO_WIFI_SSID "ALIENTEK-YF"     // 热点名称,注意这里频段要设置在2.4G
#define DEMO_WIFI_PWD "15902020353"      // 热点密码
#define DEMO_TCP_SERVER_IP "192.168.1.3" // 服务器IP地址,TCP协议
#define DEMO_TCP_SERVER_PORT "8080"      // 主机访问端口号

// MyWIFI 状态
#define MYWIFI_OK 1
#define MYWIFI_ERROR 0

#define MAX_LENGTH 200
extern u8 receive_number;                // 记录接收长度
extern u8 temp_rec_num;                  // 用于测试的临时长度记录
extern u8 rev_finish_flag;               // 接收完成标志
extern u8 wifi_connect_flag;             // 1表示连接成功
extern char mywifi_recv_buf[MAX_LENGTH]; // 接收数组

void mywifi_uart_init(void); // 默认波特率为115200
void mywifi_send_nbytes(char *data, u8 len);

u8 mywifi_send_at_cmd(char *cmd, char *ack, u32 timeout, u8 len); // 发送指令,期待应答指令,等待时间
u8 mywifi_recv_data(char *data);                                  // 接收数据函数
u8 mywifi_self_test(void);                                        // wifi芯片自动检测
void mywifi_soft_rst(void);                                       // wifi软件复位
void mywifi_polldispaly(u8 flag);                                 // wifi回显开关
void mywifi_set_mode(u8 mode);                                    // wifi设置工作模式,站点模式 Or AP模式
bool mywifi_connect_host(void);                                   // 芯片连接到热点,这里我默认是我电脑的热点
void mywifi_get_ip(void);                                         // 获取wifi连接分配的ip地址
void mywifi_set_one_node(void);                                   // 设置单路连接
bool mywifi_judge_host_connect(void);                             // 判断热点是否连接
void mywifi_connect_sever(void);                                  // 连接到服务器
void mywifi_set_transparent(u8 flag);                             // 设置透传模式
void mywifi_data_send(u8 *data, u8 len);                          // wifi数据传输
void mywifi_close_tcp_connection(void);                           // 关闭tcp连接
void mywifi_judge_tranfer_end(void);                              // 判断是否结束透传
void mywifi_char_printf(char *fmt, ...);                          // 用于打印+++,退出透传模式
#endif

mywifi.c

#include "mywifi.h"
#include <string.h>
#include <stdio.h>
#include "delay.h"
#include "usart.h"
#include <stdarg.h> // 用来重定向

/**
 * @description: wifi用到串口初始化
 * @return {*}
 */
void mywifi_uart_init(void)
{
    // GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能USART2,GPIOA时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    // USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // PA.2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);          // 初始化GPIOA.2

    // USART1_RX	  GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;             // PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                // 初始化GPIOA.3

    // Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        // 子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           // 根据指定的参数初始化VIC寄存器

    // USART 初始化设置
    USART_InitStructure.USART_BaudRate = 115200;                                    // 串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     // 字长为8位数据格式
    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(USART2, &USART_InitStructure);      // 初始化串口2
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 开启串口接受中断
    USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // 开启串口空闲中断
    USART_Cmd(USART2, ENABLE);                     // 使能串口1
}

/**
 * @description: 给wifi芯片传输指定长度数据
 * @param {char} *data 传输数据
 * @param {u8} len 传输数据长度
 * @return {*}
 */
void mywifi_send_nbytes(char *data, u8 len)
{
    for (int i = 0; i < len; i++)
    {
        USART_SendData(USART2, data[i]); // 发送测试
        while (!USART_GetFlagStatus(USART2, USART_FLAG_TC))
            ; // 等待发送完成
    }
}

/**
 * @description: wifi发送数据
 * @param {char} *cmd数据
 * @param {char} *ack期待的应答
 * @param {u32} timeout超时
 * @param {u8} len数据长度
 * @return {*}
 */
u8 mywifi_send_at_cmd(char *cmd, char *ack, u32 timeout, u8 len)
{
    char *ret = NULL; // 用于接收数据

    //    atk_mw8266d_uart_rx_restart();
    // 正点原子有一个硬件复位的过程,这里没设置了,
    mywifi_send_nbytes(cmd, len);

    if ((ack == NULL) || (timeout == 0))
    {
        return MYWIFI_OK;
    }
    else
    {
        while (timeout > 0)
        {

            if (mywifi_recv_data(ret))
            {
                if (strstr((const char *)mywifi_recv_buf, ack) != NULL) // ack 作为子串去查询
                {
                    // mywifi_send_nbytes(mywifi_recv_buf, sizeof(mywifi_recv_buf));
                    return MYWIFI_OK;
                }
                else
                {
                    // 不同则复位
                    // atk_mw8266d_uart_rx_restart();
                }
            }
            timeout--;
            delay_ms(1);
        }

        return MYWIFI_ERROR; // 这里代表超时
    }
}

/**
 * @description: 接收数据
 * @param {char} *data
 * @return {*} 返回当前是否完成了数据接收
 */
u8 mywifi_recv_data(char *data)
{
    char temp[MAX_LENGTH] = {0}; // 测试使用
    if (rev_finish_flag == 1)
    {
        // 当前接收完成
        data = mywifi_recv_buf; // 先预留的,目前我没有用到
        strncpy(temp, mywifi_recv_buf, receive_number);
        rev_finish_flag = 0;
        receive_number = 0;
        //        printf("the rec data : \r\n");
        //        printf("%s", temp);
        return 1;
    }
    else
        return 0;
}

/**
 * @description: wifi自检测
 * @return {*} 自检成功返回1
 */
u8 mywifi_self_test(void)
{
    char test[] = {"AT\r\n"};
    char ack[] = {"OK"};
    u8 flag = 0;
    for (u8 i = 0; i < 50; i++)
    {
        flag = mywifi_send_at_cmd(test, (char *)ack, 20, sizeof(test) / sizeof(test[0]));
        char temp[MAX_LENGTH] = {0};
        while (strstr((const char *)temp, "busy") != NULL) // 等待忙完成
        {
            // 等待不忙,才执行后面的,这里写的有点问题,没有达到预期的效果
            memset(temp, 0, MAX_LENGTH);
            strncpy(temp, mywifi_recv_buf, temp_rec_num);
            flag = mywifi_send_at_cmd(test, (char *)ack, 20, sizeof(test) / sizeof(test[0]));
            rev_finish_flag = 0;
            temp_rec_num = 0;
            // 开机都忙等待的话直接给它硬件复位
        }
        if (flag)
            return flag;
    }
    return flag; // 自检测5次,最后一次成功表示成功
}

/**
 * @description: wifi软件重启,这个操作在自检测成功之后
 * @return {*}
 */
char soft_rst[] = {"AT+RST\r\n"};
void mywifi_soft_rst(void)
{
    mywifi_send_at_cmd(soft_rst, NULL, 20, sizeof(soft_rst) / sizeof(soft_rst[0]));
}

/**
 * @description: WiFi回显开关
 * @param {u8} flag
 * @return {*}
 */
char polldispaly0[] = {"ATE0\r\n"};
char polldispaly1[] = {"ATE1\r\n"};
void mywifi_polldispaly(u8 flag)
{
    mywifi_send_at_cmd(flag ? polldispaly0 : polldispaly1, "OK", 20, sizeof(polldispaly0) / sizeof(polldispaly0[0]));
}

/**
 * @description: wifi设置工作模式,站点模式 Or AP模式
 * @param {u8} mode 1表示设置为站点模式
 * @return {*}
 */
char set_mode0[] = {"AT+CWMODE=0\r\n"};
char set_mode1[] = {"AT+CWMODE=1\r\n"};
void mywifi_set_mode(u8 mode)
{
    mywifi_send_at_cmd(mode ? set_mode1 : set_mode0, "OK", 20, sizeof(set_mode0) / sizeof(set_mode0[0]));
}

/**
 * @description: 芯片连接到热点,这里我默认是我电脑的热点
 * @return {*}
 */
char connecet_host[] = {"AT+CWJAP=\"mldesk\",\"12345671\"\r\n"};
bool mywifi_connect_host(void)
{
    mywifi_send_at_cmd(connecet_host, "OK", 4000, sizeof(connecet_host) / sizeof(connecet_host[0]));
    delay_ms(4000);
    return true;
}

/**
 * @description: 获取wifi连接获取的ip地址
 * @return {*}
 */
char get_ip[] = {"AT+CIPSTA?\r\n"};
void mywifi_get_ip(void)
{
    char temp[MAX_LENGTH] = {0};
    while (strstr((const char *)temp, "OK") == NULL)
    {
        // 等待不忙,才执行后面的
        memset(temp, 0, MAX_LENGTH);
        strncpy(temp, mywifi_recv_buf, temp_rec_num);
        rev_finish_flag = 0;
        temp_rec_num = 0;
    }
    mywifi_send_at_cmd(get_ip, NULL, 2000, sizeof(get_ip) / sizeof(get_ip[0]));
    delay_ms(1000);
    // 获取ip号先保存起来之后使用,这个打来之后是会调硬件错误的,可能是数组超了
    //    if (rev_finish_flag == 1)
    //    {
    //        // 当前接收完成
    //        u8 i = 0;
    //        rev_finish_flag = 0;

    //        for (; i < temp_rec_num; i++)
    //        {
    //            if ((mywifi_recv_buf[i] == 0x69) && (mywifi_recv_buf[i + 1] == 0x70))
    //                break;
    //        }
    //        // 找到了ip地址的位置
    //        memset(temp, 0, MAX_LENGTH);
    //        strncpy(temp, mywifi_recv_buf + i + 4, 15);
    //        temp_rec_num = 0;
    //        //printf("%s",temp);
    //    }
}

/**
 * @description: 判断热点是否连接
 * @return {*}
 */
bool mywifi_judge_host_connect(void)
{
    if ((strstr((const char *)mywifi_recv_buf, "CONNCETED") != NULL) ||
        (strstr((const char *)mywifi_recv_buf, "GOT") != NULL))
    {
        printf("\r\nconnecet_host ok\r\n");
        // 成功之后设置相应的标志位,比如可以用来连接tcp服务器
        wifi_connect_flag = 1; // wifi 连接成功

        return true;
    }
    else if ((strstr((const char *)mywifi_recv_buf, "DISCONNECT") != NULL))
    {
        printf("\r\nconnecet_host error\r\n");
        // 失败时候需要将相应标志位清除,显示连接丢失
        wifi_connect_flag = 0; // wifi 连接失败
        return false;
    }
    return false;
}

/**
 * @description: wifi芯片作为client 连接到服务器
 * @return {*}
 */
char connecet_sever[] = {"AT+CIPSTART=\"TCP\",\"192.168.137.1\",8080\r\n"};
void mywifi_connect_sever(void)
{
    if (wifi_connect_flag) // 需要保证wifi连接成功之后设置tcpip单路连接
    {
        char temp[MAX_LENGTH] = {0};
        while (strstr((const char *)temp, "OK") == NULL)
        {
            // 等待上一次指令完成,才执行后面的
            memset(temp, 0, MAX_LENGTH);
            strncpy(temp, mywifi_recv_buf, temp_rec_num);
            rev_finish_flag = 0;
            temp_rec_num = 0;
        }
        mywifi_send_at_cmd(connecet_sever, "OK", 2000, sizeof(connecet_sever) / sizeof(connecet_sever[0]));
        delay_ms(1000);
    }
}

/**
 * @description: 设置透传模式
 * @param {u8} flag 1 表示透传 0 表示关闭透传发送+++
 * @return {*}
 */
char open_transparent[] = {"AT+CIPMODE=1\r\n"};
char close_transparent[] = {"AT+CIPMODE=0\r\n"};
char send_data_cmd[] = {"AT+CIPSEND\r\n"};
char fade_transparent[] = {"+++"};
void mywifi_set_transparent(u8 flag)
{
    if (flag)
    {
        mywifi_send_at_cmd(open_transparent, "OK", 200, sizeof(open_transparent) / sizeof(open_transparent[0]));
        delay_ms(1000);
        mywifi_send_at_cmd(send_data_cmd, ">", 200, sizeof(send_data_cmd) / sizeof(send_data_cmd[0]));
    }
    else
    {
        delay_ms(2000);            // 需要等待一秒,结束透传
        mywifi_char_printf("+++"); // 发送结束标志
        delay_ms(4000);            // 需要等待一秒,结束透传
        mywifi_send_at_cmd("\r\n", NULL, 200, 0);
        mywifi_send_at_cmd(close_transparent, "OK", 200, sizeof(close_transparent) / sizeof(close_transparent[0]));
        mywifi_close_tcp_connection(); // 断开tcp连接
    }
}

/**
 * @description: 通过透传模式进行输出传输
 * @param {u8} *data
 * @param {u8} len
 * @return {*}
 */

void mywifi_data_send(u8 *data, u8 len)
{
    if (wifi_connect_flag) // 需要保证wifi连接成功,服务器连接成功,才能进行输出传输
    {
        mywifi_send_at_cmd(data, NULL, 0, len); // 数据发送,需要等待
    }
}

/**
 * @description: 断开tcp连接
 * @return {*}
 */
char close_tcp[] = {"AT+CIPCLOSE\r\n"};
void mywifi_close_tcp_connection(void)
{
    mywifi_send_at_cmd(close_tcp, "OK", 200, sizeof(close_tcp) / sizeof(close_tcp[0]));
}

/**
 * @description: 判断是否结束透传,需要通过服务器发送+++,判断
 * @return {*}
 */
void mywifi_judge_tranfer_end(void)
{
}

/**
 * @description: 用于打印+++,推出透传模式
 * @param {char} *fmt
 * @return {*}
 */
void mywifi_char_printf(char *fmt, ...)
{
    va_list ap;
    uint16_t len;
    char cmd[MAX_LENGTH] = {0};

    va_start(ap, fmt);
    vsprintf((char *)cmd, fmt, ap);
    va_end(ap);

    len = strlen((const char *)cmd);
    mywifi_send_nbytes(cmd, len);
}

/**
 * @description: 串口2中断回调函数
 * @return {*}
 */
void USART2_IRQHandler()
{
    static char res; // 静态变量防止堆栈溢出
    static u32 temp;
    char temp1[MAX_LENGTH] = {0}; // 静态变量防止堆栈溢出
    if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
        res = USART_ReceiveData(USART2);  // 读取接收到的数据
        if (receive_number >= MAX_LENGTH) // 防止刷爆
            receive_number = MAX_LENGTH - 1;
        mywifi_recv_buf[receive_number] = res;
        receive_number++;
        USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    }
    if (USART_GetFlagStatus(USART2, USART_FLAG_IDLE) != RESET) // 命中空闲中断
    {
        /*---------------使用串口1打印从wifi芯片接收到的数据--------*/
        strncpy(temp1, mywifi_recv_buf, receive_number);
        temp_rec_num = receive_number;
        printf("%s", temp1);
        /*----------------end-------------------------------------*/
        rev_finish_flag = 1;
        // 判断wifi是否断开连接
        mywifi_judge_host_connect();
        // 判断服务器是否断开连接
        // ------还没实现,可以通过各个指令不同的返回值去判定

        // 下面这个操作是必要的,清除空闲中断标志位
        temp = USART2->SR;
        temp = USART2->DR;
        USART_ClearITPendingBit(USART2, USART_IT_IDLE); // 清除空闲中断标志位
        receive_number = 0;
    }
}

标记一下这里要注意的几个点

1、 当前程序可实现收发,具体看wifi演示视频
(我的编程习惯不是很好,可能写的有点乱)
2、 程序参考了正点原子的,所以把它的程序也丢到压缩包了
3、 使用串口助手调试的时候,所有的指令都是要加上换行符的,这个是AT指令集规定的,不加就会返回error
4、 网络调试助手要选择TCP 服务器模式,它的IP号的选择,要通过wifi芯片所被分配的ip地址选择,比如下面这种张图片,通过查询ip地址,返回的IP地址是192.168.137.89,掩码是255.255.255.0,那么服务器的ip地址的前三个数据也应该是192.168.137,那么就可在网络调试助手里面选择对应的IP号了,然后使用默认的通道号就可以。
插播一点点TCP\IP的知识,但是只要了解就可以
在这里插入图片描述
在这里插入图片描述

5、 有一点没有做好的就是,wifi芯片连接热点是有时间要求的,而且每次不一样,我做了一个等待上一次指令完成的操作,就是如果上一次是指令传输,那么成功的话就会返回OK,在执行当前指令前,先判断接收buffer里面是不是存在OK这个字符,如果是则表示上一次传输完成,但其实如果是出错的话会有个ERROR返回,这个没有加上去。需要你自己加上去了。
6、 还有一点是每次关机之后,好像这个芯片内部电容还有电一样,会保持几秒钟的连接时间。如果掉电立马复位,发送指令它会一直显示正忙,这里我没有找到解决办法,现象如下
在这里插入图片描述
7、 我测试的条件
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值