ESP32 Arduino SPI
1.SPI1.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接线方式示例使用ESP32S3SCK 连接到Arduino的13号引脚。MISO 连接到Arduino的12号引脚。MOSI 连接到Arduino的11号引脚。SS 连接到Arduino的10号引脚。请确保连接的外部设备也正确接线从设备的SCK、MISO、MOSI、SS引脚连接到相应的ESP32引脚。3.相关API3.1 初始化SPIvoid 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 配置并启动SPIvoid 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为1LSB为0。LSBleast significant bit 表示二进制数据的最低位MSB : most significant bit 表示二进制数据的最高位spi传输数据时有两种方式MSB first 和LSB firstdataMode 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); }