【实验】ESP32S3的SPI通信

ESP32-S3 通讯口资源简介

本次实验我们选用的是图灵哥TRGESP32S3拓展板,板子上搭载的是乐鑫科技ESP32-S3-N16R8这颗SOC,同时还用到图灵哥科技的2.4寸屏模块,接口方便接插。

ESP32-S3-N16R8是乐鑫信息科技(Espressif Systems)推出的一款高性能、低功耗的Wi-Fi和蓝牙双模芯片。它继承了ESP32系列的传统,并引入了更为强大的处理能力和丰富的外设资源。

以下是ESP32-S3-N16R8芯片的主要通讯口资源:

  1. Wi-Fi接口:
    • 支持802.11b/g/n协议
    • 支持WPA3安全协议
    • 支持Station、SoftAP、Station+SoftAP三种模式
  2. 蓝牙接口:
    • 支持蓝牙5.0,包括经典蓝牙和BLE(蓝牙低功耗)
    • 支持多种蓝牙Profile,例如SPP、A2DP、HID等
  3. USB OTG接口:支持USB 2.0 OTG(On-The-Go)功能,可以作为USB设备或USB主机使用;
  4. SPI接口:2个SPI控制器,可用于连接外部Flash存储器、显示屏、传感器等设备
  5. I2C接口:2个I2C控制器,用于连接各种I2C设备,如传感器、EEPROM等
  6. UART接口:3个UART接口,可用于与外部设备进行串行通信,或者用于调试目的
  7. I2S接口:2个I2S接口,用于音频信号传输,可以连接外部DAC或ADC,支持I2S或PCM格式
  8. SD/SDIO/MMC接口:支持SD卡、SDIO和MMC协议,可用于扩展存储
  9. PWM接口:8个PWM控制器,可用于电机控制、调光等应用
  10. GPIO接口:丰富的通用输入输出接口48个,可以配置为数字输入/输出,或者复用为上述提到的各种通讯接口
  11. Ethernet接口:支持通过外接以太网物理层(PHY)芯片实现以太网连接虽然ESP32-S3-N16R8没有内置以太网MAC/PHY,但它可以通过外部PHY芯片和RMII接口来支持以太网连接

SPI通讯的基本原理

SPI通讯涉及以下几个主要信号线

  1. SCLK(时钟线):由主设备(通常是ESP32)提供,用于同步数据的传输
  2. MOSI(主设备输出从设备输入):用于主设备向从设备发送数据
  3. MISO(主设备输入从设备输出):用于从设备向主设备发送数据
  4. SS/CS(从设备选择/片选线):由主设备控制,用于选择要通信的从设备

ESP32S3的SPI通讯特点:

  1. 支持多个SPI接口:ESP32提供了多个SPI控制器,可以同时支持多个SPI设备
  2. 可配置的时钟频率:ESP32的SPI时钟频率可调,最高可达80MHz
  3. 全双工通信:可以同时进行数据的发送和接收
  4. 支持DMA(直接内存访问):可以减少CPU的负担,提高数据传输效率
  5. 可配置的数据位宽:支持8位、16位、32位等不同的数据位宽

SPI通讯配置步骤

  1. 初始化SPI主机:配置SPI总线的模式、时钟频率、数据位宽等参数
  2. 设置片选线:配置SS/CS线,用于选择从设备
  3. 数据传输:通过MOSI和MISO线进行数据的发送和接收
  4. 关闭SPI主机:在数据传输完成后,关闭SPI主机以节省资源

主要程序源码

demo_show.cpp

/**
 ****************************************************************************************************
 * @file      demo_show.cpp
 * @author    Turinger Software
 * @version   V1.0
 * @date      2024-09-20
 * @brief     SPILCD展示代码
 * 实验平台    图灵哥 TRGESP32S3探索板
 *
 ****************************************************************************************************
 */

#include "demo_show.h" 
#include "spilcd.h"
#include <math.h>

#define PI (float)(3.1415926)

static float cube[8][3] = {
    {-16, -16, -16},
    {-16, +16, -16},
    {+16, +16, -16},
    {+16, -16, -16},
    {-16, -16, +16},
    {-16, +16, +16},
    {+16, +16, +16},
    {+16, -16, +16}
};

static uint8_t line_id[24] = {
    1, 2, 2, 3,
    3, 4, 4, 1,
    5, 6, 6, 7,
    7, 8, 8, 5,
    8, 4, 7, 3,
    6, 2, 5, 1
};

/**
 * @brief     计算矩阵乘法
 * @param       a      : 矩阵a
 *              b[3][3]: 矩阵b
 * @retval      计算结果
 */
static float *demo_matconv(float *a, float b[3][3])
{
    float res[3];
    uint8_t res_index;
    uint8_t a_index;
    
    for (res_index = 0; res_index < 3; res_index++)
    {
        res[res_index] = b[res_index][0] * a[0] + b[res_index][1] * a[1] + b[res_index][2] * a[2];
    }
    
    for (a_index = 0; a_index < 3; a_index++)
    {
        a[a_index] = res[a_index];
    }
    
    return a;
}

/**
 * @brief     旋转向量
 * @param       point: 需要旋转的向量
 *              x    : X轴旋转量
 *              y    : Y轴旋转量
 *              z    : Z轴旋转量
 * @retval      计算结果
 */
static void demo_rotate(float *point, float x, float y, float z)
{
    float rx[3][3];
    float ry[3][3];
    float rz[3][3];
    
    x /= PI;
    y /= PI;
    z /= PI;
    
    rx[0][0] = cos(x);
    rx[0][1] = 0;
    rx[0][2] = sin(x);
    rx[1][0] = 0;
    rx[1][1] = 1;
    rx[1][2] = 0;
    rx[2][0] = -sin(x);
    rx[2][1] = 0;
    rx[2][2] = cos(x);
    
    ry[0][0] = 1;
    ry[0][1] = 0;
    ry[0][2] = 0;
    ry[1][0] = 0;
    ry[1][1] = cos(y);
    ry[1][2] = -sin(y);
    ry[2][0] = 0;
    ry[2][1] = sin(y);
    ry[2][2] = cos(y);
    
    rz[0][0] = cos(z);
    rz[0][1] = -sin(z);
    rz[0][2] = 0;
    rz[1][0] = sin(z);
    rz[1][1] = cos(z);
    rz[1][2] = 0;
    rz[2][0] = 0;
    rz[2][1] = 0;
    rz[2][2] = 1;
    
    demo_matconv(demo_matconv(demo_matconv(point, rz), ry), rx);
}

/**
 * @brief     演示立方体3D旋转
 * @param       无
 * @retval      无
 */
void demo_show_cube(void)
{
    uint8_t point_index;
    uint8_t line_index;
    
    for (point_index = 0; point_index < 8; point_index++)
    {
        demo_rotate(cube[point_index], 0.5f, 0.3f, 0.2f);
    }
    
    for (line_index = 0; line_index < 24; line_index += 2)
    {
        /* LCD画线段 */
        lcd_draw_line(120 + cube[line_id[line_index] - 1][0],
                      210 + cube[line_id[line_index] - 1][1],
                      120 + cube[line_id[line_index + 1] - 1][0],
                      210 + cube[line_id[line_index + 1] - 1][1],
                      BLUE);
    }
    
    delay(100);
    
    lcd_fill(92, 182, 148, 238, WHITE);   /* 填充立方体活动区域 */
}

实验效果

实验到此结束,感谢观看。

### 使用Python绘制YOLOv8模型性能对比曲线图 为了实现这一目标,可以采用Matplotlib库来创建高质量的图表。下面提供了一个完整的解决方案,包括数据准备、绘图设置以及最终图形展示。 #### 数据结构定义 首先,需要准备好用于比较的数据集,这里假设已经拥有了不同版本YOLO模型的关键指标(如mAP, Params, FPS, GFlops)。这些数据通常存储在一个列表或字典中以便于处理: ```python import matplotlib.pyplot as plt import numpy as np # 假设这是从实验获得的不同YOLO变体的各项性能指标 data = { &#39;Model&#39;: [&#39;YOLOv3&#39;, &#39;YOLOv4&#39;, &#39;YOLOv5&#39;, &#39;YOLOv6&#39;, &#39;YOLOv8&#39;], &#39;mAP@[.5:.95]&#39;: [28.0, 45.7, 47.3, 48.1, 50.2], &#39;Params (M)&#39;: [61., 62., 66., 71., 70.], &#39;FPS&#39;: [20, 35, 40, 45, 50], &#39;GFLOPs&#39;: [10.6, 14.2, 15.6, 16.5, 17.0] } ``` #### 创建子图布局并配置样式 接下来构建一个多面板图表,分别显示各个维度上的差异,并调整美观性和可读性的参数: ```python fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 8)) axes = axes.ravel() # 将二维数组展平为一维方便遍历 for idx, metric in enumerate([&#39;mAP@[.5:.95]&#39;, &#39;Params (M)&#39;, &#39;FPS&#39;, &#39;GFLOPs&#39;]): ax = axes[idx] bars = ax.bar(data[&#39;Model&#39;], data[metric], color=&#39;skyblue&#39;) # 添加数值标签到柱状图顶部 for bar in bars: yval = bar.get_height() ax.text(bar.get_x() + bar.get_width()/2, yval, round(yval, 1), ha=&#39;center&#39;, va=&#39;bottom&#39;) ax.set_title(f&#39;Comparison of {metric}&#39;, fontsize=12) ax.set_xlabel(&#39;Models&#39;, fontsize=10) ax.set_ylabel(metric, fontsize=10) plt.tight_layout(pad=2.0) # 自动调整各子图间距 plt.show() ``` 上述代码片段展示了如何利用`matplotlib`中的条形图函数`bar()`快速生成直观易懂的结果可视化[^1]。 对于更复杂的场景,比如想要模仿学术会议论文里的专业外观,则可能还需要进一步定制化字体大小、颜色方案等方面;另外也可以考虑引入Seaborn这样的高级封装包简化某些特定类型的统计图形制作过程[^2]。 如果追求更高分辨率输出以适应出版需求的话,MATLAB确实是一个不错的选择因为它支持直接导出PDF格式而不会损失图像质量[^3]。不过通过适当调节DPI参数同样可以在Python环境下得到满意的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值