国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ESP32S3系列--SPI主機(jī)驅(qū)動(dòng)詳解(一)

這篇具有很好參考價(jià)值的文章主要介紹了ESP32S3系列--SPI主機(jī)驅(qū)動(dòng)詳解(一)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、目的

SPI是一種串行同步接口,可用于與外圍設(shè)備進(jìn)行通信。

ESP32S3自帶4個(gè)SPI外設(shè),其中SPI0/SPI1內(nèi)部專用,共用一組信號(hào)線,通過(guò)一個(gè)仲裁器訪問(wèn)外部Flash和PSRAM;SPI2/3各自使用一組獨(dú)立的信號(hào)線;開發(fā)者可以使用SPI2/3控制外部SPI從設(shè)備(Slave device);其中SPI2作為主設(shè)備有6個(gè)片選,數(shù)據(jù)線最多可以有八根,SPI3作為主設(shè)備有3個(gè)片選,數(shù)據(jù)線最多可以有四根。SPI2/3既可以作為主機(jī)使用,也可以作為從機(jī)使用。

本篇主要介紹SPI主機(jī)驅(qū)動(dòng)的基本知識(shí),包括標(biāo)準(zhǔn)SPI(MISO/MOSI)/Dual SPI/Quad SPI以及Octal SPI的配置和使用。

關(guān)于標(biāo)準(zhǔn)SPI/Dual SPI/Quad SPI以及Octal SPI的區(qū)別請(qǐng)閱讀《理解SPI/Dual SPI/Quad SPI/QPI之間的區(qū)別》。

關(guān)于SPI2/3作為從機(jī)使用的知識(shí)點(diǎn)會(huì)在后續(xù)博文中詳細(xì)介紹。


為了方便開發(fā)者使用SPI外設(shè),ESP-IDF SDK中將SPI外設(shè)抽象為BUS(總線),一條總線上只有一個(gè)主設(shè)備,但是可以掛接多個(gè)從設(shè)備,每個(gè)從設(shè)備各自有獨(dú)立的一條片選線(CS),其他信號(hào)線共用;片選線用于選中設(shè)備進(jìn)行通信。

ESP32S3系列--SPI主機(jī)驅(qū)動(dòng)詳解(一)

總線框圖

上圖中slave?A和B共用一組信號(hào)線,使用的是標(biāo)準(zhǔn)SPI模式;每個(gè)設(shè)備有自己獨(dú)立的片選控制線;某個(gè)時(shí)刻只能控制一個(gè)設(shè)備,要么控制A,要么控制B;A和B分時(shí)使用SPI總線。

如果覺(jué)得博客寫得不錯(cuò),或?qū)δ阌袔椭?,接受打賞哦

二、介紹

參考資料

SPI Master Driver - ESP32-S3 - — ESP-IDF Programming Guide latest documentation (espressif.com)


SPI外設(shè)框圖

SPI即串行同步接口

ESP32S3系列--SPI主機(jī)驅(qū)動(dòng)詳解(一)

其中FSPI即SPI2,SPI2可以通過(guò)IOMUX或者GPIO Matrix進(jìn)行引腳配置,SPI3只能通過(guò)GPIO Matrix進(jìn)行引腳配置。

SPI2/3都支持DMA傳輸。


全雙工和半雙工區(qū)別

模式

說(shuō)明

全雙工

主機(jī)與從機(jī)之間的發(fā)送線和接收線各自獨(dú)立,發(fā)送數(shù)據(jù)和接收數(shù)據(jù)同時(shí)進(jìn)行。

半雙工

主機(jī)和從機(jī)只能有一方先發(fā)送數(shù)據(jù),另一方接收數(shù)據(jù)。發(fā)送數(shù)據(jù)和接收數(shù)據(jù)不能同時(shí)進(jìn)行。

四線全雙工

四線包括:時(shí)鐘線、片選線和兩條數(shù)據(jù)線。其中,可使用兩條數(shù)據(jù)線同時(shí)發(fā)送和接收數(shù)據(jù);一根數(shù)據(jù)線用于發(fā)送(MOSI),一根數(shù)據(jù)線用于接收(MISO)

四線半雙工

四線包括:時(shí)鐘線、片選線和兩條數(shù)據(jù)線。其中,分時(shí)使用兩條數(shù)據(jù)線,不可同時(shí)使用。

三線半雙工

三線包括:時(shí)鐘線、片選線和一條數(shù)據(jù)線。使用數(shù)據(jù)線分時(shí)發(fā)送和 接收數(shù)據(jù)。

專業(yè)術(shù)語(yǔ)

術(shù)語(yǔ)

描述

Host(主機(jī))

芯片內(nèi)部的SPI控制器外設(shè),用于主動(dòng)發(fā)起SPI傳輸

Device(設(shè)備)

SPI從設(shè)備,一條SPI總線可以連接多個(gè)從設(shè)備;每個(gè)設(shè)備分時(shí)共享信號(hào)線;每個(gè)設(shè)備都有一根獨(dú)立的片選控制線;當(dāng)主機(jī)需要控制某個(gè)設(shè)備時(shí),選中對(duì)應(yīng)的片選線即可(一般是拉低CS線)

Bus(總線)

多個(gè)設(shè)備共享的SPI信號(hào)線

MOSI(主機(jī)輸出從機(jī)輸入)

主機(jī)從此信號(hào)線輸出數(shù)據(jù),從設(shè)備從此信號(hào)線接收數(shù)據(jù);在四線/八線模式下作為Data0

MISO(主機(jī)輸入從機(jī)輸出)

主機(jī)從此信號(hào)線接收數(shù)據(jù),從設(shè)備從此信號(hào)線發(fā)送數(shù)據(jù);在四線/八線模式下作為Data1

SCLK(串行同步時(shí)鐘)

串行同步時(shí)鐘,數(shù)據(jù)的發(fā)送接收依賴此信號(hào)來(lái)同步

CS(片選)

片選信號(hào),每個(gè)從設(shè)備都有一個(gè)片選線

QUADWP(寫保護(hù))

寫保護(hù)信號(hào);在四線/八線模式下作為Data2

QUADHD(保持)

保持信號(hào);在四線/八線模式下作為Data3

DATA4

在八線模式下作為Data4

DATA5

在八線模式下作為Data5

DATA6

在八線模式下作為Data6

DATA7

在八線模式下作為Data7

Assertion

發(fā)起SPI傳輸(一般是拉低片選線),總線進(jìn)入忙狀態(tài)

De-assertion

SPI傳輸結(jié)束(一般是拉高片選線),總線進(jìn)入空閑狀態(tài)

Transaction(傳輸事務(wù))

一次完整的傳輸事務(wù):主機(jī)拉低從機(jī)的 CS 線,開始傳輸數(shù)據(jù),然 后再拉高從機(jī)的 CS 線。傳輸事務(wù)為原子操作,即不可打斷。

Transfer(傳輸)

SPI 主機(jī)與從機(jī)完成數(shù)據(jù)交換的一次完整過(guò)程。一次 SPI 傳輸可以 包含一個(gè)或多個(gè) SPI 傳輸事務(wù)。

單次傳輸

在這種傳輸模式下,一次SPI傳輸僅包含一次傳輸事務(wù)。

Launch edge(發(fā)射邊沿)

數(shù)據(jù)源寄存器(發(fā)送端)在此邊沿將數(shù)據(jù)比特發(fā)送至信號(hào)線上

Latch edge(鎖存邊沿)

數(shù)據(jù)目的寄存器(接收端)在此邊沿將數(shù)據(jù)比特鎖存下來(lái)


特性
  • 支持多線程環(huán)境使用

  • 支持CPU控制的傳輸模式以及DMA控制的傳輸模式

  • DMA讀寫過(guò)程用戶無(wú)感知

  • 自動(dòng)時(shí)分復(fù)用(不同時(shí)刻對(duì)不同設(shè)備進(jìn)行讀寫)

  • 時(shí)鐘最高80MHz(主機(jī)模式)


注意點(diǎn)
  • 同一個(gè)設(shè)備盡量在一個(gè)線程中操作

  • 同一個(gè)設(shè)備在不同線程中操作需要通過(guò)互斥鎖進(jìn)行保護(hù)


SPI事務(wù)描述

每次SPI傳輸可以包含五個(gè)階段,包括命令、地址、空周期、寫、讀階段,每個(gè)階段都是可選的。

階段

描述

Command(命令)

在此階段主機(jī)可以發(fā)送命令字段,長(zhǎng)度最多16bit

Address(地址)

在此階段主機(jī)可以發(fā)送地址字段,長(zhǎng)度最多32bit

Dummy(空周期)

此階段用于適配時(shí)序要求

Write(寫)

此階段主機(jī)發(fā)送數(shù)據(jù)給從設(shè)備

Read(讀)

此階段主機(jī)讀取從設(shè)備數(shù)據(jù)

?????

傳輸線模式配置(重要)

通過(guò)設(shè)置傳輸模式標(biāo)記可以控制每個(gè)階段的數(shù)據(jù)線的數(shù)目

模式

命令線寬度

地址線寬度

數(shù)據(jù)線寬度

Transaction Flag

Bus IO setting Flag

Normal SPI

1

1

1

0

0

Dual Output

(DOUT)

1

1

2

SPI_TRANS_MODE_DIO

SPICOMMON_BUSFLAG_DUAL

Dual I/O

(DIO)

1

2

2

SPI_TRANS_MODE_DIO | SPI_TRANS_MULTILINE_ADDR

Quad Output

(QOUT)

1

1

4

SPI_TRANS_MODE_QIO

SPICOMMON_BUSFLAG_QUAD

Quad I/O

(QIO)

1

4

4

SPI_TRANS_MODE_QIO | SPI_TRANS_MULTILINE_ADDR

Octal Output

1

1

8

SPI_TRANS_MODE_OCT

SPICOMMON_BUSFLAG_OCTAL

OPI

8

8

8

SPI_TRANS_MODE_OCT | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_MULTILINE_CMD

傳輸標(biāo)記說(shuō)明
#define SPI_TRANS_MODE_DIO            (1<<0)  ///< Transmit/receive data in 2-bit mode

收發(fā)數(shù)據(jù)階段使用雙線模式

#define SPI_TRANS_MODE_QIO            (1<<1)  ///< Transmit/receive data in 4-bit mode

收發(fā)數(shù)據(jù)階段使用四線模式

#define SPI_TRANS_MODE_DIOQIO_ADDR    (1<<4)  ///< Also transmit address in mode selected by SPI_MODE_DIO/SPI_MODE_QIO
#define SPI_TRANS_MULTILINE_ADDR      SPI_TRANS_MODE_DIOQIO_ADDR ///< The data lines used at address phase is the same as data phase (otherwise, only one data line is used at address phase)

地址階段使用和數(shù)據(jù)階段一樣的模式,如果未設(shè)置此標(biāo)記則地址階段使用一線模式

#define SPI_TRANS_MULTILINE_CMD       (1<<9)  ///< The data lines used at command phase is the same as data phase (otherwise, only one data line is used at command phase)

命令階段使用和數(shù)據(jù)階段一樣的模式,如果未設(shè)置此標(biāo)記則命令階段使用一線模式

#define SPI_TRANS_MODE_OCT            (1<<10) ///< Transmit/receive data in 8-bit mode

收發(fā)數(shù)據(jù)階段使用八線模式,配合SPI_TRANS_MULTILINE_CMD/SPI_TRANS_MULTILINE_ADDR可以所有階段都是八線模式

總線的初始化

在使用SPI總線之前必須先初始化

/**
 * @brief Initialize a SPI bus
 *
 * @warning SPI0/1 is not supported
 *
 * @param host_id       SPI peripheral that controls this bus
 * @param bus_config    Pointer to a spi_bus_config_t struct specifying how the host should be initialized
 * @param dma_chan      - Selecting a DMA channel for an SPI bus allows transactions on the bus with size only limited by the amount of internal memory.
 *                      - Selecting SPI_DMA_DISABLED limits the size of transactions.
 *                      - Set to SPI_DMA_DISABLED if only the SPI flash uses this bus.
 *                      - Set to SPI_DMA_CH_AUTO to let the driver to allocate the DMA channel.
 *
 * @warning If a DMA channel is selected, any transmit and receive buffer used should be allocated in
 *          DMA-capable memory.
 *
 * @warning The ISR of SPI is always executed on the core which calls this
 *          function. Never starve the ISR on this core or the SPI transactions will not
 *          be handled.
 *
 * @return
 *         - ESP_ERR_INVALID_ARG   if configuration is invalid
 *         - ESP_ERR_INVALID_STATE if host already is in use
 *         - ESP_ERR_NOT_FOUND     if there is no available DMA channel
 *         - ESP_ERR_NO_MEM        if out of memory
 *         - ESP_OK                on success
 */
esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *bus_config, spi_dma_chan_t dma_chan);

函數(shù)參數(shù)的說(shuō)明:

host_id:SPI外設(shè)索引號(hào)

bus_config:SPI總線參數(shù)

dma_chan:是否使能DMA傳輸并配置使用的傳輸通道


使能DMA傳輸?shù)淖⒁恻c(diǎn)
  • 傳輸buffer需要時(shí)dma-capable的內(nèi)部RAM

  • 必須32bit對(duì)齊并且長(zhǎng)度必須是4字節(jié)對(duì)齊

如果這兩個(gè)條件不滿足,驅(qū)動(dòng)內(nèi)部會(huì)自動(dòng)分配內(nèi)存然后進(jìn)行拷貝后再傳輸,故效率會(huì)降低;所以建議使能DMA傳輸時(shí)外部傳入的buffer盡可能是DMA屬性的內(nèi)存

// Region of memory accessible via DMA in internal memory. See esp_ptr_dma_capable().
#define SOC_DMA_LOW  0x3FC88000
#define SOC_DMA_HIGH 0x3FD00000

/**
 * @brief Check if the pointer is dma capable
 *
 * @param p pointer
 *
 * @return true: capable; false: not capable
 */
__attribute__((always_inline))
inline static bool esp_ptr_dma_capable(const void *p)
{
    return (intptr_t)p >= SOC_DMA_LOW && (intptr_t)p < SOC_DMA_HIGH;
}

static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma)
{
    *new_desc = (spi_trans_priv_t) { .trans = trans_desc, };

    // rx memory assign
    uint32_t* rcv_ptr;
    if ( trans_desc->flags & SPI_TRANS_USE_RXDATA ) {
        rcv_ptr = (uint32_t *)&trans_desc->rx_data[0];
    } else {
        //if not use RXDATA neither rx_buffer, buffer_to_rcv assigned to NULL
        rcv_ptr = trans_desc->rx_buffer;
    }
    if (rcv_ptr && isdma && (!esp_ptr_dma_capable(rcv_ptr) || ((int)rcv_ptr % 4 != 0))) {  //①
        //if rxbuf in the desc not DMA-capable, malloc a new one. The rx buffer need to be length of multiples of 32 bits to avoid heap corruption.
        ESP_LOGD(SPI_TAG, "Allocate RX buffer for DMA" );
        rcv_ptr = heap_caps_malloc((trans_desc->rxlength + 31) / 8, MALLOC_CAP_DMA);  //②
        if (rcv_ptr == NULL) goto clean_up;
    }
    new_desc->buffer_to_rcv = rcv_ptr;

    // tx memory assign
    const uint32_t *send_ptr;
    if ( trans_desc->flags & SPI_TRANS_USE_TXDATA ) {
        send_ptr = (uint32_t *)&trans_desc->tx_data[0];
    } else {
        //if not use TXDATA neither tx_buffer, tx data assigned to NULL
        send_ptr = trans_desc->tx_buffer ;
    }
    if (send_ptr && isdma && !esp_ptr_dma_capable( send_ptr )) {  //③
        //if txbuf in the desc not DMA-capable, malloc a new one
        ESP_LOGD(SPI_TAG, "Allocate TX buffer for DMA" );
        uint32_t *temp = heap_caps_malloc((trans_desc->length + 7) / 8, MALLOC_CAP_DMA);
        if (temp == NULL) goto clean_up;

        memcpy( temp, send_ptr, (trans_desc->length + 7) / 8 );
        send_ptr = temp;
    }
    new_desc->buffer_to_send = send_ptr;

    return ESP_OK;

clean_up:
    uninstall_priv_desc(new_desc);
    return ESP_ERR_NO_MEM;
}

spi_device_queue_trans和spi_device_polling_start函數(shù)中通過(guò)setup_priv_desc這個(gè)函數(shù)檢查rx_buffer/tx_buffer的屬性

①如果要接收則檢查rcv_ptr是否是DMA屬性的(在地址區(qū)間內(nèi))并且rcv_ptr指針的值是否是4字節(jié)對(duì)齊

②rcv_ptr不滿足dma要求則重新分配

③如果要發(fā)送則檢查send_ptr是否是DMA屬性的(注意發(fā)送的首地址可以不是四字節(jié)對(duì)齊)


SPI外設(shè)索引號(hào)

/**
 * @brief Enum with the three SPI peripherals that are software-accessible in it
 */
typedef enum {
//SPI1 can be used as GPSPI only on ESP32
    SPI1_HOST=0,    ///< SPI1
    SPI2_HOST=1,    ///< SPI2
    SPI3_HOST=2,    ///< SPI3
    SPI_HOST_MAX,   ///< invalid host value
} spi_host_device_t;

在ESP32S3上可以使用SPI2_HOST和SPI3_HOST


SPI總線參數(shù)說(shuō)明

/**
 * @brief This is a configuration structure for a SPI bus.
 *
 * You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the
 * GPIO matrix to route the signals. An exception is made when all signals either can be routed through
 * the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds.
 *
 * @note Be advised that the slave driver does not use the quadwp/quadhd lines and fields in spi_bus_config_t refering to these lines will be ignored and can thus safely be left uninitialized.
 */
typedef struct {
    union {
      int mosi_io_num;    ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
      int data0_io_num;   ///< GPIO pin for spi data0 signal in quad/octal mode, or -1 if not used.
    };
    union {
      int miso_io_num;    ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
      int data1_io_num;   ///< GPIO pin for spi data1 signal in quad/octal mode, or -1 if not used.
    };
    int sclk_io_num;      ///< GPIO pin for SPI Clock signal, or -1 if not used.
    union {
      int quadwp_io_num;  ///< GPIO pin for WP (Write Protect) signal, or -1 if not used.
      int data2_io_num;   ///< GPIO pin for spi data2 signal in quad/octal mode, or -1 if not used.
    };
    union {
      int quadhd_io_num;  ///< GPIO pin for HD (Hold) signal, or -1 if not used.
      int data3_io_num;   ///< GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used.
    };
    int data4_io_num;     ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used.
    int data5_io_num;     ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
    int data6_io_num;     ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
    int data7_io_num;     ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
    int max_transfer_sz;  ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled.
    uint32_t flags;       ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.
    int intr_flags;       /**< Interrupt flag for the bus to set the priority, and IRAM attribute, see
                           *  ``esp_intr_alloc.h``. Note that the EDGE, INTRDISABLED attribute are ignored
                           *  by the driver. Note that if ESP_INTR_FLAG_IRAM is set, ALL the callbacks of
                           *  the driver, and their callee functions, should be put in the IRAM.
                           */
} spi_bus_config_t;

各個(gè)字段含義:

mosi_io_num/data0_io_num:主機(jī)輸出從機(jī)輸入或者data0信號(hào)線IO引腳編號(hào)

miso_io_num/data1_io_num:主機(jī)輸入從機(jī)輸出或者data1信號(hào)線IO引腳編號(hào)

sclk_io_num:時(shí)鐘信號(hào)IO引腳編號(hào)

quadwp_io_num/data2_io_num:寫保護(hù)信號(hào)或者data2信號(hào)線IO引腳編號(hào)

quadhd_io_num/data3_io_num:保持信號(hào)或者data3信號(hào)線IO引腳編號(hào)

data4_io_num:data4信號(hào)線IO引腳編號(hào)

data5_io_num:data5信號(hào)線IO引腳編號(hào)

data6_io_num:data6信號(hào)線IO引腳編號(hào)

data7_io_num:data7信號(hào)線IO引腳編號(hào)

max_transfer_size:一次SPI傳輸最大的長(zhǎng)度;使能DMA傳輸時(shí),如果設(shè)置為0,則默認(rèn)限制為4092字節(jié);未使能DMA時(shí),如果設(shè)置為0,則默認(rèn)限制為SOC_SPI_MAXIMUM_BUFFER_SIZE(64字節(jié))。

flags:總線特征標(biāo)志,具體說(shuō)明請(qǐng)看下文

intr_flags:中斷特征標(biāo)志,如果設(shè)置為ESP_INTR_FLAG_IRAM則驅(qū)動(dòng)中涉及到的回調(diào)以及回調(diào)調(diào)用的函數(shù)也要是IRAM屬性的

其中數(shù)據(jù)線根據(jù)實(shí)際硬件需要設(shè)置,如果某些引腳不需要,設(shè)置為-1即可。

關(guān)于flags字段的說(shuō)明

#define SPICOMMON_BUSFLAG_SLAVE         0          ///< Initialize I/O in slave mode

設(shè)置從設(shè)備模式,內(nèi)部使用;通過(guò)spi_slave_initialize接口初始化默認(rèn)為從設(shè)備模式

#define SPICOMMON_BUSFLAG_MASTER        (1<<0)     ///< Initialize I/O in master mode

設(shè)置主設(shè)備模式,內(nèi)部使用;通過(guò)spi_bus_initialize接口初始化默認(rèn)為主設(shè)備模式

#define SPICOMMON_BUSFLAG_IOMUX_PINS    (1<<1)     ///< Check using iomux pins. Or indicates the pins are configured through the IO mux rather than GPIO matrix.

檢查是否使用IOMUX作為IO輸入輸出或者指示IO引腳是否是使用IOMUX進(jìn)行配置的

#define SPICOMMON_BUSFLAG_GPIO_PINS     (1<<2)     ///< Force the signals to be routed through GPIO matrix. Or indicates the pins are routed through the GPIO matrix.

強(qiáng)制使用GPIO Matrix作為IO輸入輸出或者指示IO引腳是否是使用GPIO Matrix進(jìn)行配置的

默認(rèn)情況下(SPICOMMON_BUSFLAG_IOMUX_PINS/SPICOMMON_BUSFLAG_GPIO_PINS標(biāo)志都不設(shè)置),SPI主機(jī)驅(qū)動(dòng)會(huì)使用GPIO矩陣來(lái)配置外設(shè)引腳;但是如果所有的信號(hào)都可以通過(guò)IOMUX進(jìn)行配置(或者某些信號(hào)不需要使用,設(shè)置為-1),那么就會(huì)使用IOMUX進(jìn)行引腳配置,優(yōu)點(diǎn)是傳輸時(shí)鐘頻率可以大于40MHz。

IO引腳配置說(shuō)明

如果在初始化時(shí)設(shè)置了SPICOMMON_BUSFLAG_GPIO_PINS標(biāo)記,那么內(nèi)部就使用IO矩陣進(jìn)行IO配置(即使需要的IO引腳可以通過(guò)IOMUX配置)如果設(shè)置了SPICOMMON_BUSFLAG_IOMUX_PINS,則內(nèi)部會(huì)檢查設(shè)置的IO引腳編號(hào)是否可以通過(guò)IOMUX配置,如果可以則初始化成功,否則初始化失敗;如果兩個(gè)標(biāo)記都沒(méi)有設(shè)置,那么內(nèi)部會(huì)檢查設(shè)置的IO引腳編號(hào)是否可以通過(guò)IOMUX配置,如果可以則使用IOMUX,否則使用IO Matrix。

一般情況下SPICOMMON_BUSFLAG_GPIO_PINS和SPICOMMON_BUSFLAG_IOMUX_PINS都不需要設(shè)置,只要我們?cè)O(shè)置的IO引腳是可以通過(guò)IOMUX配置的,默認(rèn)就會(huì)使用IOMUX配置;否則都是通過(guò)IO Matrix配置。

具體的內(nèi)部代碼邏輯如下

 //check if the selected pins correspond to the iomux pins of the peripheral
    bool use_iomux = !(flags & SPICOMMON_BUSFLAG_GPIO_PINS) && bus_uses_iomux_pins(host, bus_config);
    if (use_iomux) {
        temp_flag |= SPICOMMON_BUSFLAG_IOMUX_PINS;
    } else {
        temp_flag |= SPICOMMON_BUSFLAG_GPIO_PINS;
    }

    uint32_t missing_flag = flags & ~temp_flag;
    missing_flag &= ~SPICOMMON_BUSFLAG_MASTER;//don't check this flag

    if (missing_flag != 0) {
    //check pins existence
        if (missing_flag & SPICOMMON_BUSFLAG_SCLK) {
            ESP_LOGE(SPI_TAG, "sclk pin required.");
        }
        if (missing_flag & SPICOMMON_BUSFLAG_MOSI) {
            ESP_LOGE(SPI_TAG, "mosi pin required.");
        }
        if (missing_flag & SPICOMMON_BUSFLAG_MISO) {
            ESP_LOGE(SPI_TAG, "miso pin required.");
        }
        if (missing_flag & SPICOMMON_BUSFLAG_DUAL) {
            ESP_LOGE(SPI_TAG, "not both mosi and miso output capable");
        }
        if (missing_flag & SPICOMMON_BUSFLAG_WPHD) {
            ESP_LOGE(SPI_TAG, "both wp and hd required.");
        }
        if (missing_flag & SPICOMMON_BUSFLAG_IOMUX_PINS) {
            ESP_LOGE(SPI_TAG, "not using iomux pins");
        }
#if SOC_SPI_SUPPORT_OCT
        if (missing_flag & SPICOMMON_BUSFLAG_IO4_IO7) {
            ESP_LOGE(SPI_TAG, "spi data4 ~ spi data7 are required.");
        }
#endif
        SPI_CHECK(missing_flag == 0, "not all required capabilities satisfied.", ESP_ERR_INVALID_ARG);
    }

通過(guò)IOMUX配置的引腳配置

Pin Name

SPI2

SPI3

GPIO Number

CS0*

10

N/A

SCLK

12

N/A

MISO

13

N/A

MOSI

11

N/A

QUADWP

14

N/A

QUADHD

9

N/A

只有SPI2支持IOMUX進(jìn)行引腳配置,除非時(shí)鐘頻率很高,否則沒(méi)有必要糾結(jié)是使用IOMUX還是GPIO Matrix。

一般情況下際初始化總線上不需要設(shè)置SPICOMMON_BUSFLAG_GPIO_PINS和SPICOMMON_BUSFLAG_IOMUX_PINS這兩個(gè)標(biāo)志。


#define SPICOMMON_BUSFLAG_SCLK          (1<<3)     ///< Check existing of SCLK pin. Or indicates CLK line initialized.

檢查是否配置SCLK引腳,一般不使用此標(biāo)記;如果設(shè)置了此標(biāo)志,但是sclk_io_num字段為-1,則初始化出錯(cuò)。

#define SPICOMMON_BUSFLAG_MISO          (1<<4)     ///< Check existing of MISO pin. Or indicates MISO line initialized.
#define SPICOMMON_BUSFLAG_MOSI          (1<<5)     ///< Check existing of MOSI pin. Or indicates MOSI line initialized.

檢查是否配置MOSI/MISO引腳,一般不使用此標(biāo)記;如果設(shè)置了這些標(biāo)志,但是mosi_io_num/mosi_io_num字段為-1,則初始化出錯(cuò)。

#define SPICOMMON_BUSFLAG_DUAL          (1<<6)     ///< Check MOSI and MISO pins can output. Or indicates bus able to work under DIO mode.

檢查MOSI和MISO引腳可以輸出或者指示總線能夠工作在DIO模式,一般不使用此標(biāo)記;如果設(shè)置了這些標(biāo)記,但是mosi_io_num/mosi_io_num未都設(shè)置且合法,則初始化報(bào)錯(cuò)。

#define SPICOMMON_BUSFLAG_WPHD          (1<<7)     ///< Check existing of WP and HD pins. Or indicates WP & HD pins initialized.

檢查WP/HD信號(hào)的存在或者指示W(wǎng)P/HD引腳已經(jīng)初始化,一般不使用此標(biāo)記;如果設(shè)置了這些標(biāo)記,但是quadwp_io_num/quadhd_io_num未都設(shè)置且合法,則初始化報(bào)錯(cuò)。

#define SPICOMMON_BUSFLAG_QUAD          (SPICOMMON_BUSFLAG_DUAL|SPICOMMON_BUSFLAG_WPHD)     ///< Check existing of MOSI/MISO/WP/HD pins as output. Or indicates bus able to work under QIO mode.

檢查MOSI/MISO/WP/HD引腳可以輸出或者指示總線能夠工作在QIO模式

#define SPICOMMON_BUSFLAG_IO4_IO7       (1<<8)     ///< Check existing of IO4~IO7 pins. Or indicates IO4~IO7 pins initialized.

檢查IO4-IO7引腳存在或者指示IO4-IO7引腳已經(jīng)初始化

#define SPICOMMON_BUSFLAG_OCTAL         (SPICOMMON_BUSFLAG_QUAD|SPICOMMON_BUSFLAG_IO4_IO7)  ///< Check existing of MOSI/MISO/WP/HD/SPIIO4/SPIIO5/SPIIO6/SPIIO7 pins as output. Or indicates bus able to work under octal mode.

檢查MOSI/MISO/WP/HD/SPIIO4/SPIIO5/SPIIO6/SPIIO7引腳可以輸出或者指示可以工作在八線模式


SPI DMA通道說(shuō)明

/**
 * @brief SPI DMA channels
 */
typedef enum {
  SPI_DMA_DISABLED = 0,     ///< Do not enable DMA for SPI
#if CONFIG_IDF_TARGET_ESP32
  SPI_DMA_CH1      = 1,     ///< Enable DMA, select DMA Channel 1
  SPI_DMA_CH2      = 2,     ///< Enable DMA, select DMA Channel 2
#endif
  SPI_DMA_CH_AUTO  = 3,     ///< Enable DMA, channel is automatically selected by driver
} spi_common_dma_t;

使能DMA傳輸時(shí)傳輸?shù)臄?shù)據(jù)量不限制,max_transfer_sz如果設(shè)置為0則默認(rèn)為4092字節(jié);禁用DMA傳輸時(shí)會(huì)限制最大可傳輸?shù)臄?shù)據(jù)量,max_transfer_sz如果設(shè)置為0則默認(rèn)為64字節(jié)。

一般建議如果只是操作外部flash可以禁用DMA傳輸。

往總線添加設(shè)備

總線初始化成功后,就可以往總線上添加從設(shè)備

typedef struct spi_device_t *spi_device_handle_t;  ///< Handle for a device on a SPI bus
/**
 * @brief Allocate a device on a SPI bus
 *
 * This initializes the internal structures for a device, plus allocates a CS pin on the indicated SPI master
 * peripheral and routes it to the indicated GPIO. All SPI master devices have three CS pins and can thus control
 * up to three devices.
 *
 * @note While in general, speeds up to 80MHz on the dedicated SPI pins and 40MHz on GPIO-matrix-routed pins are
 *       supported, full-duplex transfers routed over the GPIO matrix only support speeds up to 26MHz.
 *
 * @param host_id SPI peripheral to allocate device on
 * @param dev_config SPI interface protocol config for the device
 * @param handle Pointer to variable to hold the device handle
 * @return
 *         - ESP_ERR_INVALID_ARG   if parameter is invalid
 *         - ESP_ERR_NOT_FOUND     if host doesn't have any free CS slots
 *         - ESP_ERR_NO_MEM        if out of memory
 *         - ESP_OK                on success
 */
esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interface_config_t *dev_config, spi_device_handle_t *handle);

各個(gè)參數(shù)說(shuō)明:

host_id:SPI外設(shè)索引號(hào)

dev_config:從設(shè)備配置信息

handle:從設(shè)備句柄

注意點(diǎn)

通過(guò)IOMUX配置外設(shè)引腳時(shí)鐘最大可以為80MHz(只有SPI2);通過(guò)GPIO Matrix的時(shí)鐘只能40MHz,并且全雙工通信時(shí)只能設(shè)置為26MHz.

設(shè)備配置信息
/**
 * @brief This is a configuration for a SPI slave device that is connected to one of the SPI buses.
 */
typedef struct {
    uint8_t command_bits;           ///< Default amount of bits in command phase (0-16), used when ``SPI_TRANS_VARIABLE_CMD`` is not used, otherwise ignored.
    uint8_t address_bits;           ///< Default amount of bits in address phase (0-64), used when ``SPI_TRANS_VARIABLE_ADDR`` is not used, otherwise ignored.
    uint8_t dummy_bits;             ///< Amount of dummy bits to insert between address and data phase
    uint8_t mode;                   /**< SPI mode, representing a pair of (CPOL, CPHA) configuration:
                                         - 0: (0, 0)
                                         - 1: (0, 1)
                                         - 2: (1, 0)
                                         - 3: (1, 1)
                                     */
    uint16_t duty_cycle_pos;         ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
    uint16_t cs_ena_pretrans;        ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
    uint8_t cs_ena_posttrans;       ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16)
    int clock_speed_hz;             ///< Clock speed, divisors of 80MHz, in Hz. See ``SPI_MASTER_FREQ_*``.
    int input_delay_ns;             /**< Maximum data valid time of slave. The time required between SCLK and MISO
        valid, including the possible clock delay from slave to master. The driver uses this value to give an extra
        delay before the MISO is ready on the line. Leave at 0 unless you know you need a delay. For better timing
        performance at high frequency (over 8MHz), it's suggest to have the right value.
        */
    int spics_io_num;               ///< CS GPIO pin for this device, or -1 if not used
    uint32_t flags;                 ///< Bitwise OR of SPI_DEVICE_* flags
    int queue_size;                 ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time
    transaction_cb_t pre_cb;   /**< Callback to be called before a transmission is started.
                                 *
                                 *  This callback is called within interrupt
                                 *  context should be in IRAM for best
                                 *  performance, see "Transferring Speed"
                                 *  section in the SPI Master documentation for
                                 *  full details. If not, the callback may crash
                                 *  during flash operation when the driver is
                                 *  initialized with ESP_INTR_FLAG_IRAM.
                                 */
    transaction_cb_t post_cb;  /**< Callback to be called after a transmission has completed.
                                 *
                                 *  This callback is called within interrupt
                                 *  context should be in IRAM for best
                                 *  performance, see "Transferring Speed"
                                 *  section in the SPI Master documentation for
                                 *  full details. If not, the callback may crash
                                 *  during flash operation when the driver is
                                 *  initialized with ESP_INTR_FLAG_IRAM.
                                 */
} spi_device_interface_config_t;

各個(gè)字段含義:

command_bits:命令階段傳輸?shù)腷it數(shù),最大16bit(可以通過(guò)SPI_TRANS_VARIABLE_CMD進(jìn)行覆蓋)

address_bits:地址階段傳輸?shù)腷it數(shù),最大64bit(可以通過(guò)SPI_TRANS_VARIABLE_ADDR進(jìn)行覆蓋)

dummy_bits:地址階段和數(shù)據(jù)階段的空周期數(shù)(可以通過(guò)SPI_TRANS_VARIABLE_DUMMY進(jìn)行覆蓋)

由于并不是每一個(gè)傳輸都需要命令、地址、空周期這些階段,一般情況下在添加從設(shè)備時(shí)這三個(gè)字段都是設(shè)置為0,在真正發(fā)起SPI傳輸時(shí)通過(guò)SPI_TRANS_VARIABLE_CMD、SPI_TRANS_VARIABLE_ADDR、SPI_TRANS_VARIABLE_DUMMY這些標(biāo)志位進(jìn)行設(shè)置。

mode:SPI時(shí)鐘的極性和相位關(guān)系,請(qǐng)閱讀《理解SPI/Dual SPI/Quad SPI/QPI之間的區(qū)別》中的時(shí)鐘極性和時(shí)鐘相位章節(jié)

/**< SPI mode, representing a pair of (CPOL, CPHA) configuration:
                                         - 0: (0, 0)
                                         - 1: (0, 1)
                                         - 2: (1, 0)
                                         - 3: (1, 1)
                                     */

duty_cycle_pos:時(shí)鐘占空比,默認(rèn)50%

cs_ena_pretrans:傳輸開始前CS信號(hào)提前有效的時(shí)間,只用在半雙工傳輸中(0-16)

cs_ena_posttrans:傳輸結(jié)束后CS保持有效的時(shí)間(0-16)

clock_speed_hz:時(shí)鐘頻率

input_delay_ns:從設(shè)備的數(shù)據(jù)有效時(shí)間,一般不設(shè)置

spics_io_num:片選IO引腳編號(hào),未使用時(shí)設(shè)置-1即可

flags:設(shè)備標(biāo)志

queue_size:傳輸隊(duì)列大小,使用spi_device_queue_trans接口可以將傳輸請(qǐng)求進(jìn)行排隊(duì)處理

pre_cb:傳輸開始前的回調(diào)函數(shù),在中斷中執(zhí)行

post_cb:傳輸結(jié)束后的回調(diào)函數(shù),在中斷中執(zhí)行

設(shè)備標(biāo)志說(shuō)明
#define SPI_DEVICE_TXBIT_LSBFIRST          (1<<0)  ///< Transmit command/address/data LSB first instead of the default MSB first

地址/命令/數(shù)據(jù)階段發(fā)送的比特位的順序?yàn)橄劝l(fā)送低比特位(默認(rèn)是先發(fā)送高比特位)

#define SPI_DEVICE_RXBIT_LSBFIRST          (1<<1)  ///< Receive data LSB first instead of the default MSB first

接收數(shù)據(jù)的比特位順序?yàn)橄冉邮盏捅忍匚唬J(rèn)是先接收高比特位)

#define SPI_DEVICE_BIT_LSBFIRST            (SPI_DEVICE_TXBIT_LSBFIRST|SPI_DEVICE_RXBIT_LSBFIRST) ///< Transmit and receive LSB first

收發(fā)都使用LSB

#define SPI_DEVICE_POSITIVE_CS             (1<<3)  ///< Make CS positive during a transaction instead of negative

默認(rèn)片段信號(hào)拉低有效,此標(biāo)記設(shè)置為拉高為選中設(shè)備

#define SPI_DEVICE_HALFDUPLEX              (1<<4)  ///< Transmit data before receiving it, instead of simultaneously

設(shè)置為半雙工模式,如果需要使用多線進(jìn)行數(shù)據(jù)收發(fā),必須在添加從設(shè)備時(shí)設(shè)置此字段


總線獲取

有些情況下需要獨(dú)占的使用總線,這個(gè)時(shí)候可以使用spi_device_acquire_bus()獨(dú)占總線;通過(guò)spi_device_release_bus()釋放總線


中斷傳輸和輪詢傳輸

通過(guò)spi_device_transmit()發(fā)起的傳輸是中斷傳輸,會(huì)阻塞當(dāng)前線程直到傳輸完成,此時(shí)CPU調(diào)度其他線程執(zhí)行;

通過(guò)spi_device_queue_trans可以發(fā)起多個(gè)傳輸,每個(gè)傳輸進(jìn)行排隊(duì),中斷中一個(gè)接一個(gè)的處理。

調(diào)用此接口后,當(dāng)前線程可以繼續(xù)執(zhí)行其他任務(wù),通過(guò)spi_device_get_trans_result()獲取傳輸結(jié)果。

示例代碼

? ? esp_err_t ret;
    int x;
    //Transaction descriptors. Declared static so they're not allocated on the stack; we need this memory even when this
    //function is finished because the SPI driver needs access to it even while we're already calculating the next line.
    static spi_transaction_t trans[6];

    //In theory, it's better to initialize trans and data only once and hang on to the initialized
    //variables. We allocate them on the stack, so we need to re-init them each call.
    for (x=0; x<6; x++) {
        memset(&trans[x], 0, sizeof(spi_transaction_t));
        if ((x&1)==0) {
            //Even transfers are commands
            trans[x].length=8;
            trans[x].user=(void*)0;
        } else {
            //Odd transfers are data
            trans[x].length=8*4;
            trans[x].user=(void*)1;
        }
        trans[x].flags=SPI_TRANS_USE_TXDATA;
    }
    trans[0].tx_data[0]=0x2A;           //Column Address Set
    trans[1].tx_data[0]=0;              //Start Col High
    trans[1].tx_data[1]=0;              //Start Col Low
    trans[1].tx_data[2]=(320)>>8;       //End Col High
    trans[1].tx_data[3]=(320)&0xff;     //End Col Low
    trans[2].tx_data[0]=0x2B;           //Page address set
    trans[3].tx_data[0]=ypos>>8;        //Start page high
    trans[3].tx_data[1]=ypos&0xff;      //start page low
    trans[3].tx_data[2]=(ypos+PARALLEL_LINES)>>8;    //end page high
    trans[3].tx_data[3]=(ypos+PARALLEL_LINES)&0xff;  //end page low
    trans[4].tx_data[0]=0x2C;           //memory write
    trans[5].tx_buffer=linedata;        //finally send the line data
    trans[5].length=320*2*8*PARALLEL_LINES;          //Data length, in bits
    trans[5].flags=0; //undo SPI_TRANS_USE_TXDATA flag

    //Queue all transactions.
    for (x=0; x<6; x++) {
        ret=spi_device_queue_trans(spi, &trans[x], portMAX_DELAY);
        assert(ret==ESP_OK);
    }

上述代碼片段采用排隊(duì)方式的中斷傳輸,一次發(fā)起6個(gè)SPI傳輸事務(wù)。

輪詢傳輸通過(guò)CPU查詢標(biāo)志位判斷傳輸是否完成,通過(guò)spi_device_polling_transmit()進(jìn)行

示例代碼

? ? spi_transaction_t t;
    memset(&t, 0, sizeof(t));
    t.length=8*3;
    t.flags = SPI_TRANS_USE_RXDATA;
    t.user = (void*)1;

    esp_err_t ret = spi_device_polling_transmit(spi, &t);
    assert( ret == ESP_OK );

至此我們介紹了SPI主機(jī)驅(qū)動(dòng)的基本知識(shí),關(guān)于spi_transaction_t結(jié)構(gòu)體的具體使用細(xì)節(jié)下篇講解。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-408377.html

到了這里,關(guān)于ESP32S3系列--SPI主機(jī)驅(qū)動(dòng)詳解(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【EPS32S3學(xué)習(xí)筆記】ESP32+OPENCV+人臉識(shí)別 本地部署

    【EPS32S3學(xué)習(xí)筆記】ESP32+OPENCV+人臉識(shí)別 本地部署

    提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加 例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用 提示:寫完文章后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔 提示:這里可以添加本文要記錄的大概內(nèi)容: 從https://github.com/joachimBurket/esp32-

    2024年02月09日
    瀏覽(31)
  • 【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話】

    【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話】

    圍繞ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話展開,首先串口輸入“1”字符,隨后麥克風(fēng)采集2s聲音數(shù)據(jù),對(duì)接百度在線語(yǔ)音識(shí)別,將返回文本結(jié)果丟入MiniMax模型,進(jìn)而返回第二次結(jié)果文本,實(shí)現(xiàn)語(yǔ)言對(duì)話文本效果。以上一共有兩次調(diào)用,后期只需加入tts模塊就可完整對(duì)話。

    2024年04月16日
    瀏覽(26)
  • 【EPS32S3學(xué)習(xí)筆記】ESP32+OPENCV+OV2640+LVGL

    【EPS32S3學(xué)習(xí)筆記】ESP32+OPENCV+OV2640+LVGL

    提示:這里可以添加系列文章的所有文章的目錄,目錄需要自己手動(dòng)添加 例如:第一章 Python 機(jī)器學(xué)習(xí)入門之pandas的使用 提示:寫完文章后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔 提示:這里可以添加本文要記錄的大概內(nèi)容: 前面已經(jīng)完成了ESP32S3+LVGL+OV2640的工

    2024年02月06日
    瀏覽(26)
  • ESP32S3學(xué)習(xí)——LEDC LED PWM 控制器

    ESP32S3學(xué)習(xí)——LEDC LED PWM 控制器

    芯片:esp32s3 開發(fā)環(huán)境:espidfv4.4 1)LED 控制器 (LEDC) 主要用于控制 LED,也可產(chǎn)生 PWM 信號(hào)用于 其他設(shè)備 的控制。 該控制器有 8 路通道 ,可以產(chǎn)生獨(dú)立的波形來(lái)驅(qū)動(dòng) RGB LED 等設(shè)備。 LED PWM 控制器可在 無(wú)需 CPU 干預(yù) 的情況下 自動(dòng)改變占 空比,實(shí)現(xiàn)亮度和顏色漸變(因?yàn)檫@個(gè)功能

    2024年02月06日
    瀏覽(23)
  • ESP32S3 ADC DMA使用記錄(坑記錄)(大牛歡迎給出建議)

    目前測(cè)到三個(gè)問(wèn)題: 一、ADC DMA采樣頻率sample_freq_hz取值范圍611-83333,雖然可以達(dá)到83333,但是只能是在while循環(huán)里面不停采樣才可以,如果想要隔一段時(shí)間采樣一次則不行,假如隔一段時(shí)間使用adc_digi_read_bytes讀取40byte數(shù)據(jù),結(jié)果經(jīng)常會(huì)返回ESP_ERR_INVALID_STATE,且經(jīng)常讀取的數(shù)據(jù)

    2024年02月11日
    瀏覽(40)
  • 視頻圖像處理算法opencv在esp32及esp32s3上面的移植,也可以移植openmv

    視頻圖像處理算法opencv在esp32及esp32s3上面的移植,也可以移植openmv

    opencv 在 esp32 及 esp32s3 上面的移植 Opencv 簡(jiǎn)介 ? ? ? OpenCV 是一個(gè)基于 Apache2.0 許可(開源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)軟件庫(kù),可以運(yùn)行在 Linux 、 Windows 、 Android 和 Mac OS 操作系統(tǒng)上,它輕量級(jí)而且高效—— 由一系列 C 函數(shù)和少量 C++ 類構(gòu)成,同時(shí)提供了 Python 、 R

    2024年02月09日
    瀏覽(17)
  • ESP32S3使用esp-iot-solution SDK開發(fā)USBHID鼠標(biāo)鍵盤教程

    ESP32S3使用esp-iot-solution SDK開發(fā)USBHID鼠標(biāo)鍵盤教程

    ? 手里最近翻到了一個(gè)ESP32S3開發(fā)板,于是想做個(gè)鼠標(biāo)鍵盤玩玩,這是我第二次接觸ESP32,上一次18年買的吃灰板子至今沒(méi)上過(guò)電。新找到的S3看手冊(cè)是支持OTG的,按照官方的教程搭建的WSL+VSCODE環(huán)境。然而一切準(zhǔn)備就緒發(fā)現(xiàn)ESP-IDF里面沒(méi)有USB-HIDdemo。沒(méi)有demo怎么玩。于是乎查找資

    2024年02月09日
    瀏覽(26)
  • 【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型+TTS模塊語(yǔ)音播報(bào)】

    【ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型+TTS模塊語(yǔ)音播報(bào)】

    講解視頻: ESP32S3 AI助手使用MiniMax大模型生產(chǎn)工具1 大家好,今天的教程將圍繞如何實(shí)現(xiàn)精準(zhǔn)的語(yǔ)音播報(bào)功能展開,我們用到了ESP32S3 Sense接入語(yǔ)音識(shí)別+MiniMax模型對(duì)話+SNR9816TTS模塊。 目前這是我使用的ESP32S3官方硬件??????(小小的身材有大大的力量)只需要35元加攝像頭麥

    2024年04月12日
    瀏覽(25)
  • ESP32開發(fā)——SPI驅(qū)動(dòng)水墨屏

    ESP32開發(fā)——SPI驅(qū)動(dòng)水墨屏

    怎么說(shuō)呢,感覺(jué)自己之前都白學(xué)了,又從頭到尾看了一遍。 主要參考廠家給的源碼,不過(guò)只有STM32的程序,但是大差不差,拿過(guò)來(lái)改一下就可以了,其次就是仔細(xì)查看芯片手冊(cè)。 好的,最大的收獲就是學(xué)會(huì)了如何翻手冊(cè),有問(wèn)題翻手冊(cè)??! 想要讓水墨屏顯示起來(lái),需要利用

    2024年02月04日
    瀏覽(32)
  • 【自用】ESP32-S3新板子 從零配置micropython環(huán)境(安裝CH343驅(qū)動(dòng)等)

    【自用】ESP32-S3新板子 從零配置micropython環(huán)境(安裝CH343驅(qū)動(dòng)等)

    1.安裝CH343驅(qū)動(dòng) 2.下載 microPython 固件 3.安裝燒錄軟件 flash_download_tool_3.9.3.exe 并開始燒錄 4.安裝 Thonny IDE 軟件 并配置編譯環(huán)境 1.驅(qū)動(dòng)下載 https://www.wch.cn/downloads/CH343SER_EXE.html 2.操作流程 步驟1: 通過(guò)Type-C數(shù)據(jù)線將ESP32S3與電腦連接(有坑) 一定要連接COM端口(如下圖所示 右側(cè)的

    2023年04月19日
    瀏覽(22)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包