106-ESP32_SDK开发-SPI

<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

 

说明

ESP32共有4路SPI, SPI0,SPI1,SPI2,SPI3

同时SPI2还取了个别名叫做 HSPI ;  同时SPI3还取了个别名叫做 VSPI

SPI0,SPI1是只访问缓存芯片使用,可以用来给模组用来扩容ram.

SPI0,SPI1的引脚分布在

GPIO6(SPI_CLK);  GPIO7(SPI_Q);  GPIO8(SPI_D);  GPIO9(SPI_HD);  GPIO10(SPI_WP);  GPIO11(SPI_CS0);

用户不要使用这些引脚作为普通IO使用.关于SPI0和SPI1的使用会在以后的教程里面.

这节教程是学习SPI2(HSPI)和SPI3(VSPI);   HSPI和VSPI使用是一样的哈.

如果按照下图分配引脚(不包含CS引脚), SPI的传输速率可以达到80M

咱们就以HSPI为例(基础使用)

1.配置HSPI信号线的参数

2.配置数据传输参数

3.设置传输的数据,和发送数据

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "driver/timer.h"
#include "esp_timer.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "driver/spi_master.h"


#define PIN_NUM_MISO 12
#define PIN_NUM_MOSI 13
#define PIN_NUM_CLK  14
#define PIN_NUM_CS   15

spi_device_handle_t spi_device;//存储所配置的SPI句柄

void app_main(void)
{
    esp_err_t ret;

    //配置SPI总线参数
    spi_bus_config_t buscfg={
        .miso_io_num = PIN_NUM_MISO,//设置主机输入从机输出引脚(接收数据引脚)
        .mosi_io_num = PIN_NUM_MOSI,//设置主机输出从机输入引脚(发送数据引脚)
        .sclk_io_num = PIN_NUM_CLK,//设置时钟引脚
        .quadwp_io_num = -1,//不使用wp信号线
        .quadhd_io_num = -1,//不使用hd信号线
        .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE,//一次性最大传输字节个数;默认为SOC_SPI_MAXIMUM_BUFFER_SIZE(启用DMA时需要设置为0)
    };
    //初始化配置SPI总线(配置HSPI);最后设置为0为不启用DMA
    ret = spi_bus_initialize(HSPI_HOST, &buscfg, 0);
    ESP_ERROR_CHECK(ret);


    //配置SPI数据传输参数(可以新建多个这种结构体变量,相当于挂载SPI设备,一个SPI最多挂载3个设备,需要设置不同的片选引脚)
    spi_device_interface_config_t devcfg={
        .address_bits=0,                        //不需要地址数据
        .clock_speed_hz=40*1000*1000,           //频率40M
        .command_bits=0,                        //不需要命令数据
        .mode=0,                                //SPI模式(0,1,2,3)
        .spics_io_num=PIN_NUM_CS,               //设置CS引脚
        .queue_size=1,                          //传输(事务)队列大小(必须设置,先设置1,后面会说明这个有什么用)
    };
    //把传输参数配置进SPI总线
    ret = spi_bus_add_device(HSPI_HOST, &devcfg, &spi_device);
    ESP_ERROR_CHECK(ret);


    /*设置传输的数据*/
    const char spi_data[2]={0xaa,0x55};//2字节数据
    /*传输事务*/
    spi_transaction_t spi_transaction;
    memset(&spi_transaction, 0, sizeof(spi_transaction)); 

    spi_transaction.tx_buffer=spi_data; //发送的数据地址
    spi_transaction.length=2*8;         //传输数据大小(以数据位为单位);传两字节数据所以是2*8
    
    while(1){
        spi_device_transmit(spi_device, &spi_transaction);//使用SPI发送数据

        vTaskDelay(1000 / portTICK_PERIOD_MS); 
    }
}

3.关于上面的  配置SPI数据传输参数  里面的 命令和地址数据个数

在SPI传输的时候就是使用SPI传输的数据, 有时候咱想访问一个芯片,假设是读取芯片上的某个地址上的数据;

那个芯片的手册上一般会说需要先使用SPI发送个什么命令,然后再发送个什么地址,然后就可以读取到数据了.

实际上就是使用SPI发送个数据然后再使用SPI发送个数据嘛.只不过发送的第一个数据叫做xxxx命令

第二个数据就做xxx地址...............

假设在传输上面的0xAA和0x55之前,想先发送个0x11命令数据

假设在传输上面的0xAA和0x55之前,想先发送个0x11命令数据,然后再发送个地址数据0x22

4.关于传输事务大小

假设我们需要传输多条数据,那个传输事务大小就起作用了

我设置的为8,就是队列最大可以保存8条要传输的事务.

下面增加了一个传输事务.

传输的时候把要传输的事务放到 spi_device_polling_transmit 函数就可以了

底层默认传输事务之间的时间间隔为35us左右

 

原文地址:https://www.cnblogs.com/yangfengwu/p/15145812.html