打印
[应用相关]

STM32+ESP32-C3 WiFi开发测试案例

[复制链接]
212|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-10-27 09:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
WIFI
1 ESP32-C3
ESP32-C3 搭载 RISC-V 32 位单核处理器,时钟频率高达 160 MHz。具有 22 个可编程 GPIO 管脚、内置 400 KB SRAM。

2 项目准备
2.1 固件烧录工具下载
https://www.espressif.com.cn/zh- ... _type_tid%5B%5D=785



2.2 固件下载
https://docs.espressif.com/proje ... nloading_guide.html



2.3 烧录固件





2.4 关于AT指令
ESP-AT 提供了大量功能不同的 AT 命令,如 Wi-Fi 命令、TCP/IP 命令、Bluetooth LE 命令、Bluetooth 命令、MQTT 命令、HTTP 命令、Ethernet 命令等。

AT 命令以 “AT” 开始,代表 Attention,以新的一行 (CR LF) 为结尾。输入的每条命令都会返回 OK 或 ERROR 的响应,表示当前命令的最终执行结果。注意,所有 AT 命令均为串行执行,每次只能执行一条命令。因此,在使用 AT 命令时,应等待上一条命令执行完毕后,再发送下一条命令。如果上一条命令未执行完毕,又发送了新的命令,则会返回 busy p

3 案例
STM32通过串口UART2与ESP32-C3连接
3.1 案例1:测试AT指令
需求:测试AT指令,测试AT指令是否能够正常控制ESP32的wifi,比如重启,读取设备信息等。

CubeMX配置



Inf_ESP32.c
ESP32初始化
#include "Inf_ESP32.h"

uint8_t rBuff[128];
uint16_t rDataLength;

uint8_t responseBuff[1024];
uint16_t resDataLength;
// 需要使用的回调函数
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    // 健壮性判断
    if (huart->Instance == USART2)
    {
        // 此时是ESP32回复消息了
        rDataLength = Size;

        // 一次调用HAL_UARTEx_ReceiveToIdle_IT 只能触发一次回调
        HAL_UARTEx_ReceiveToIdle_IT(&huart2, rBuff, 128);

        // 最简单的方式  => 直接打印接收到的数据
        // 原则性问题:不能在中断处理中使用运行时间过长的函数
        // printf("接收到ESP32的消息:%s\n", rBuff);
    }
}

void Inf_Handle_Response(void)
{
    // 循环等待接收多次5消息 =>  一直到接收完毕 或者 收到OK或者ERROR
    uint8_t count = 5;
    /* 1. 初始化responseBuff */
    memset(responseBuff, 0, 1024);
    resDataLength = 0;
    do
    {
        // 将单次接收到的数据存放到responseBuff中
        while (rDataLength == 0)
            ;
        /* 2. 直到等到有数据过来  =>  存放到大的缓存中*/
        memcpy(&responseBuff[resDataLength], rBuff, rDataLength);
        resDataLength += rDataLength;
        rDataLength = 0;
        memset(rBuff, 0, 128);

    } while (count-- && (strstr((char *)responseBuff, "OK") == NULL) && (strstr((char *)responseBuff, "ERROR") == NULL));
    printf("%s\n",responseBuff);
    printf("-------------------\n");
}

void Inf_ESP32_SendCmd(uint8_t *cmd)
{
    // 直接使用USART2发送消息就是发送AT命令
    HAL_UART_Transmit(&huart2, cmd, strlen((char *)cmd), 1000);

    // 由于不能一次执行多个指令  => 挂起等待执行响应
    Inf_Handle_Response();
}

void Inf_ESP32_Init(void)
{
    /* 1. 初始化usart2 */
    MX_USART2_UART_Init();
    /* 2. 提前调用接收ESP32返回的消息的函数  => 会触发对应的回调函数 HAL_UARTEx_RxEventCallback*/
    HAL_UARTEx_ReceiveToIdle_IT(&huart2, rBuff, 128);
    /* 3. 发送AT指令让ESP32重置 */
    uint8_t *cmd = "AT+RST=0\r\n";
    Inf_ESP32_SendCmd(cmd);
    // 延时3s等待ESP32重启
    HAL_Delay(3000);
}




main.c
/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  // MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("hello wifi...\n");
  Inf_ESP32_Init();

  // 测试AT响应
  uint8_t *cmd = "AT\r\n";
  Inf_ESP32_SendCmd(cmd);
  // ESP32指令是串行的   不能同时执行两个指令
  // HAL_Delay(100);
  cmd = "AT+GMR\r\n";
  Inf_ESP32_SendCmd(cmd);

  /* USER CODE END 2 */



测试结果



3.2 案例2:TCP通讯
需求:TCP通讯,使用AT指令在ESP32上面启动一个TCP服务器,从而可以与其他TCP客户端实现TCP通讯。

项目开发
1. 初始化ESP32
(1) 初始化底层驱动 usart2

(2) 调用接收ESP32信息的函数

(3) 重置ESP32即可 => 延时3s

2. 初始化WIFI
(1) 设置充当的WIFI角色 => station 站点 => 用来连接别人的热点

注意:电脑开热点的时候一定要选2.4G的
(2) 连接热点 => 填写WIFI的账号和密码即可

3. 启动TCP服务端
(1) 开启多连接

(2) 创建TCP服务端

(3) 设置IPDInfo信息

4. 编写接收消息的函数
(1) +IPD,0,2,“192.168.137.1”,1179:OK 固定格式

(2) sscanf拆分匹配对应的数据

(3) strtok切分data数据

5. 编写发送数据的函数
(1) 发送需要发送数据的AT指令

AT+CIPSEND=id,length\r\n

(2) 使用USART2发送数据 => 长度达到length自动发送

Inf_ESP32.c
在上个案例的基础上加以下函数
准备好连接WiFi的名称和密码
void Inf_ESP32_WIFI_Init(void)
{
    /*1. 初始化ESP32*/
    Inf_ESP32_Init();
    /*2. 设置站点模式*/
    /*AT+CWMODE=<mode>
    <mode>:模式
        0: 无 Wi-Fi 模式,并且关闭 Wi-Fi RF
        1: Station 模式
        2: SoftAP 模式
        3: SoftAP+Station 模式*/
    uint8_t * cmd = "AT+CWMODE=1\r\n";
    Inf_ESP32_SendCmd(cmd);
    /*3. 连接AP热点*/
    cmd = "AT+CWJAP=\"DESKTOP-2UH9TD7\",\"<257M5x4\"\r\n";
    Inf_ESP32_SendCmd(cmd);
}

void Inf_ESP32_Start_TCP_server(void)
{
    /*1. 开启多链接模式*/
    uint8_t *cmd = "AT+CIPMUX=1\r\n";
    Inf_ESP32_SendCmd(cmd);

    /*2. 建立TCP连接*/
    cmd = "AT+CIPSERVER=1,8080\r\n";
    Inf_ESP32_SendCmd(cmd);

    /*3. 设置IPDInfo信息*/
    cmd = "AT+CIPDINFO=1\r\n";
    Inf_ESP32_SendCmd(cmd);
}

void Inf_ESP32_ReadData(uint8_t rxBuff[],uint8_t * id,uint16_t * recvDataLength,uint8_t * ip,uint16_t * port)
{
    //0. 健壮性判断
    if (rDataLength == 0)
    {
            return;
    }

    //1. 初始化rxBuff
    memset(rxBuff,0,sizeof(rxBuff));
    //2. 拆分匹配数据
    // %*忽略/r/n  +IPD,  %[^\"] 匹配字符串直到遇见"
    sscanf((char *)rBuff,"%*[\r\n]+IPD,%d,%d,\"%[^\"]\",%d",
            (int *)id,
            (int *)recvDataLength,
            ip,
            (int *)port);
    // 切分字符串
    strtok((char *)rBuff,":"); // 获取到切分之前的字符串
    memcpy(rxBuff,strtok(NULL,":"),*recvDataLength);

    //3. 接收数据清空
    memset(rBuff,0,128);
    rDataLength = 0;

}

void Inf_ESP32_SendData(uint8_t id,uint8_t data[],uint16_t dataSize)
{
    uint8_t cmd[100] = {0};
    sprintf((char *)cmd,"AT+CIPSEND=%d,%d\r\n",id,dataSize);
    // 1. 发送请求发送数据的命令
    Inf_ESP32_SendCmd(cmd);
    // 2. 发送数据 => 达到dataSize的长度固定开始发送
    HAL_UART_Transmit(&huart2,data,dataSize,1000);
}




main.c
/* USER CODE BEGIN 2 */
  printf("hello WIFI...\n");
  // Inf_ESP32_Init();

  Inf_ESP32_WIFI_Init();

  Inf_ESP32_Start_TCP_server();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  uint8_t rxBuff[128] = {0};
  uint8_t id = 0;
  uint8_t ip[16] = {0};
  uint16_t recvDataLength = 0;
  uint16_t port = 0;
  while (1)
  {
    Inf_ESP32_ReadData(rxBuff, &id, &recvDataLength, ip, &port);
    if (recvDataLength > 0)
    {
      printf("id:%d,ip:%s,port:%d,data:%s\n", id, ip, port, rxBuff);
      Inf_ESP32_SendData(id, rxBuff,recvDataLength);

          // 清空收到数据的长度  =>  给下次收数据做准备
          recvDataLength = 0;
    }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }



实验结果





————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_74967868/article/details/143098721

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1931

主题

15611

帖子

11

粉丝