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

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-hans/support/download/other-tools?keys=&field_type_tid%5B%5D=785

在这里插入图片描述

2.2 固件下载

https://docs.espressif.com/projects/esp-at/zh_CN/release-v3.2.0.0/esp32c3/Get_Started/Downloading_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 */
  }
实验结果

在这里插入图片描述

在这里插入图片描述

### STM32ESP32-C3蓝牙使用教程及集成方案 #### 1. **STM32蓝牙功能实现** STM32本身并不具备内置的蓝牙功能,因此需要借助外部蓝牙模块来完成蓝牙通信的任务。常见的做法是通过UART接口连接一个独立的BLE(Bluetooth Low Energy)模块,例如HC-05、HC-06或者更先进的BLE模块如Bluefruit EZ-Key等。 为了使STM32能够控制蓝牙模块并与其交互,通常采用以下方式: - 利用STM32的标准外设库或HAL库配置串口通信协议栈。 - 编写AT指令集解析器以便于发送命令给蓝牙模块以及接收其返回的数据流[^2]。 ```c // 初始化USART用于和蓝牙模块通讯 void USART_Init(void){ // 配置代码省略... } // 发送数据至蓝牙模块函数示例 void SendDataToBT(uint8_t *pData, uint16_t length){ HAL_UART_Transmit(&huart1, pData, length, HAL_MAX_DELAY); } ``` #### 2. **ESP32-C3蓝牙功能概述及其优势** 相比之下,ESP32-C3是一款高度集成化的SoC芯片,它不仅支持Wi-Fi还自带经典蓝牙(BR/EDR)与低功耗蓝牙(LE),这使得开发人员无需额外增加任何硬件即可快速构建具有双模无线能力的产品原型[^1]。 对于希望减少物料清单成本同时简化PCB布局的设计来说,选择像WT32C3-S5这样的基于ESP32-C3平台构建的一体化模块是非常明智的选择。这类产品已经预先完成了射频电路匹配网络设计等工作,并经过严格测试验证以确保性能稳定可靠。 以下是关于如何启动ESP32-C3上的蓝牙服务的一个简单例子: ```cpp #include <esp_bt.h> #include <esp_gap_ble_api.h> extern "C" void app_main(){ esp_err_t ret; /* Initialize NVS */ ret = nvs_flash_init(); /* Enable BLE stack */ esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); /* Set device name and start advertising */ const char* dev_name = "ESP32_C3"; ret = esp_ble_gap_set_device_name(dev_name); ret = esp_ble_gap_start_advertising(...); } ``` 值得注意的是,在实际项目实施过程中可能会遇到一些常见错误情况比如因引脚定义不当而导致调试困难等问题。这就提醒我们在规划初期就要充分考虑所有可能涉及到的关键信号线路安排以免后期修改带来不必要的麻烦[^3]。 #### 结论 综上所述,虽然两者都可以满足特定条件下对蓝牙的支持需求,但从易用性和资源利用率角度来看,显然ESP32-C3凭借其强大的片上特性占据了明显的优势地位;而另一方面,如果目标系统架构允许并且预算充足的话,则可以考虑将专用MCU(如某些型号高性能ARM Cortex-M系列单片机)搭配专业级短距离无线电收发单元组合起来形成更加灵活多变的应用框架结构。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值