串行外围设备接口(SPI)是微控制器使用的同步串行数据协议,用于在短距离内快速与一个或多个外围设备进行通信。它也可以用于两个开发板之间相互的通信。
使用SPI连接,总是有一个主设备(通常是微控制器)来控制外围设备。通常,所有设备共用以下三条线:
每个从设备专用的一条线:
当从设备的CS引脚为低电平时,它与主机通信。同理CS引脚电平为高时,它将忽略连接到CS引脚的设备, 不与之进行数据交互。
使用之前使用以下语句进行Wire库声明
#include <SPI.h>
下表显示了SPI引脚在各种Arduino板上的位置。
Board |
SPI pins |
Uno |
11 (MOSI), 12 (MISO), 13(SCK), 10(SS) |
Mega2560 |
51 (MOSI), 50 (MISO), 52(SCK), 53(SS) |
Leonardo | ICSP-4 (MOSI), ICSP-1 (MISO), ICSP-3(SCK), -(SS) |
您可以根据自己的开发板类型进行连线
基于AVR的板上的从选择(SS)引脚的说明
所有基于AVR的板都有一个SS引脚,当它们充当由外部主机控制的从机时,该引脚很有用。由于该库仅支持主模式,因此该引脚应始终设置为OUTPUT,否则硬件会自动将SPI接口设置为从模式,从而使库无法工作。
此外,您也可以将任何引脚用作从设备的选择引脚(SS)。例如,Arduino以太网扩展板使用引脚10控制到板载SD卡的SPI连接,并使用引脚10控制到以太网控制器的连接。
函数 | 用途 | 参数说明 | 返回值 |
SPISettings( speedMaximum, dataOrder, dataMode) |
SPISettings对象用于为SPI设备配置SPI端口。 |
speedMaximum: 最高的通讯速度。 (对于额定频率高于20 MHz的SPI芯片,请使用20000000)。 dataOrder: 数据传输顺序选择MSBFIRST LSBFIRST dataMode :数据模式选择 SPI_MODE0(默认) SPI_MODE1 SPI_MODE2 SPI_MODE3 |
无 |
begin() |
SPI总线初始化。 即将SCK(Pin13),MOSI(Pin11)和SS(Pin10)默认引脚设置为输出模式,并将SCK和MOSI设置为低电平,SS为高电平。 |
无 | 无 |
beginTransaction( settings) |
使用SPISettings中的配置进行SPI总线初始化。 |
SPISettings:指定配置 |
无 |
end() |
停止使用SPI总线 (在初始化时设置的各个引脚输出模式将不会改变)。 |
无 | 无 |
endTransaction() |
停止使用SPI总线 (通常在禁用某引脚上的从设备后调用此函数,以允许其他库使用SPI总线)。 |
无 | 无 |
transfer(val) transfer16(val16) transfer(buffer, size) |
传输数据。 SPI传输是同时发送和接收的:接收到的数据以receivedVal(或receivedVal16)形式返回。在缓冲区传输的情况下,接收到的数据就地存储在缓冲区中(旧数据将替换为接收到的数据)。 |
val: 通过总线发送的字节 val16:通过总线发送的两个字节变量 buffer: 要传输的数据数组 |
接收到的数据 |
usingInterrupt( irqNo) |
如果你的SPI通讯是在中断中进行的,需要使用此函数来设置中断编号。 |
irqNo: 中断编号 |
无 |
两块Arduino UNO R3开发板通过SPI进行通讯,则需要其中一块作为主设备,另外一块(或多块)作为从设备,同时两块开发板需要共地连接,引脚接线方式如下:
UNO(主) UNO(从)
(MOSI) 11 11
(MISO) 12 12
(SCK) 13 13
(CS) 10 10
GND GND GND
主设备程序
#include <SPI.h>
void setup () {
Serial.begin(9600); //初始化串口波特率
digitalWrite(SS, HIGH); // 禁用从设备HIGH为禁用
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0));
}
void loop () {
char c;
digitalWrite(SS, LOW); //启用从设备
// 发送测试的字符串
for (const char * p = "Hello, world!\r" ; c = *p; p++) {
SPI.transfer(c);
Serial.print(c);
}
digitalWrite(SS, HIGH); // 发送完毕后再次禁用从设备
delay(2000);
}
从设备程序
#include <SPI.h>
char buff[50];
volatile byte indx;
volatile boolean process;
void setup () {
Serial.begin(9600);
pinMode(MISO, OUTPUT); //将MISO设置为输出以便数据发送主机
SPCR |= _BV(SPE); //在从机模式下打开SPI通讯
indx = 0; // 初始化变量
process = false;
SPI.attachInterrupt(); //打开中断
}
ISR (SPI_STC_vect) // SPI中断程序
{
byte c = SPDR; // 从SPI数据寄存器读取字节
if (indx < sizeof buff) {
buff [indx++] = c; // 将数据保存在数组buff中的下一个索引中
if (c == '\r') //检查是否是结尾字符,即检测字符是否是\r回车符
process = true;
}
}
void loop () {
if (process) {
process = false; //重置通讯过程
Serial.println (buff); //在串口监视器上打印接收到的buff数据
indx = 0; //重置index,即为重置buff索引
}
}
发光二极管,简称为LED,是一种常用的发光器件,通过电子与空穴复合释放能量发光, 发光二极管可高效地将电能转化为光能,在现代社会具有广泛的用途,如照明、平板显示、医疗器件等。
ESP32系列(包括ESP32-S3)搭载Xtensa双核处理器,默认情况下Arduino框架仅使用单核运行用户代码,通过多核编程,可以充分利用硬件资源来提升系统响应和性能。
在本文中,先解释 MSB(最高有效位)和 LSB(最低有效位)的概念,以及 MSBFIRST 和 LSBFIRST。然后展示了 MSBFIRST 和 LSBFIRST 的使用如何影响移位寄存器的输出。
TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速与方向,输入电压在3V~12V,因此在集成化、小型化的电机控制系统中,它可以作为理想的电机驱动器件。
Arduino-ESP32项目提供的Preferences库是一个专为ESP32设计的非易失性存储解决方案,它替代了传统的Arduino EEPROM库,提供了更强大、更可靠的数据存储功能。
在Arduino中,通过串行端口接收数字通常涉及使用Serial.read()、Serial.readString()、Serial.parseInt()等方法。
要生成随机数,可以使用Arduino随机数函数random()。
本文收集整理在Arduino环境下字符串的相关用法,供参考。
ESP32在Arduino中的GPIO模式。
ESP32EA-MOC 开发板介绍和Arduino环境配置。