【实验】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);   /* 填充立方体活动区域 */
}

实验效果

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值