ESP32 Arduino SPI

1.SPI

1.1 简介

spi是串行外围设备接口,是一种同步、全双工、主从式接口。

产生时钟信号的设备为"主机"。

芯片的管脚上只占用四根线:

        MOSI:  主设备数据输出,从设备数据输入。

        MISO:  从设备数据输出,主设备数据输入。

        SCK:  时钟信号,由主设备发出。

        CS(NSS):  从设备选择信号,由主设备控制。CS为低电平时选择从设备。

三线制SPI没有MISO,或者MISO和MOSI共线。

1.2 IIC与SPI区别

1. IIC只需要两根信号线,而标准的SPI需要4根信号线,若存在多个从设备,信号需要很多,虽然SPI由三线制,但是片选线需要一对一。

2.如果要使用高速数据传输,那么SPI是必然的选择。因为SPI是全双工,而IIC不是。SPI没定义速度限制,一般的实现通常能达到甚至超过10Mbps。IIC最高速度也就快速模式(1Mbps)和高速模式(3.4Mbps)。

SPI的缺陷

SPI有一个非常大的缺陷,没有标准的协议,SPI比较混乱,所以衍生出多个版本,但是没有本质差异。

2.SPI接线

以下是一个常见的SPI接线方式示例,使用ESP32S3:

  • SCK: 连接到Arduino的13号引脚。
  • MISO: 连接到Arduino的12号引脚。
  • MOSI: 连接到Arduino的11号引脚。
  • SS: 连接到Arduino的10号引脚。

请确保连接的外部设备也正确接线,从设备的SCK、MISO、MOSI、SS引脚连接到相应的ESP32引脚。

3.相关API

3.1 初始化SPI

void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
  • 四个参数分别对应SPI的四根信号线,缺省时为默认值。

3.2 配置SPI

//设置高低位先行
void setBitOrder(uint8_t bitOrder);
//设置SPI模式
void setDataMode(uint8_t dataMode);
//设置频率
void setFrequency(uint32_t freq);
//设置分频,和设置频率任选其一即可
void setClockDivider(uint32_t clockDiv)

3.3 配置并启动SPI

void SPIClass::beginTransaction(SPISettings settings)

SPISettings() :_clock(1000000), _bitOrder(SPI_MSBFIRST), _dataMode(SPI_MODE0) {}
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) :_clock(clock), _bitOrder(bitOrder), _dataMode(dataMode) {}
  • clock    时钟频率。
  • bitOrder     高位先行或者低位先行,MSB为1,LSB为0。

LSB:least significant bit 表示二进制数据的最低位

MSB : most significant bit 表示二进制数据的最高位

spi传输数据时有两种方式:MSB first 和LSB first

  • dataMode    SPI模式,如下。

使用方法: 

SPI.beginTransaction(SPISettings(1000000, SPI_MSBFIRST, SPI_MODE0));

3.4 发送数据并接收返回数据

uint8_t SPIClass::transfer(uint8_t data)

uint16_t SPIClass::transfer16(uint16_t data)

uint32_t SPIClass::transfer32(uint32_t data)

3.5 片选控制

void SPIClass::setHwCs(bool use)

4.示例

这里以w25q128读取设备ID为例:

void SPI_W25Q128_init(void)
{
  //片选线引脚初始化
  pinMode(SS,OUTPUT);
  //SPI引脚配置为默认引脚
  SPI.begin();
  //配置SPI
  SPI.beginTransaction(SPISettings(1000000, SPI_MSBFIRST, SPI_MODE0));
}
void SPI_W25Q128(void)
{
  //选择从设备
  digitalWrite(SS,LOW);
  //要发送的数据
  uint8_t sendData = 0x90;
  //发送数据并接受返回数据
  SPI.transfer(sendData);
  SPI.write(0);
  SPI.write16(0);
  uint16_t receivedData = SPI.transfer16(0xffff);
  //取消选择从设备
  digitalWrite(SS,HIGH);

    // 打印输出到串口
  Serial.print("Sent Data: ");
  Serial.println(sendData, HEX);
  Serial.print("Received Data: ");
  Serial.println(receivedData, HEX);

  // 延时等待
  delay(1000);
}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值