Arduino进阶07.Arduino 串行外设接口

串行外设接口(SPI)总线是用于串行通信的系统,最多可使用四个导体,通常为三个。一个导体用于数据接收,一个导体用于数据发送,一个导体用于同步,另一个导体用于选择与之通信的设备。它是一个全双工连接,这意味着数据是同时发送和接收的。最大波特率高于I2C通信系统中的波特率。

串行外设接口(SPI)总线是用于串行通信的系统,最多可使用四个导体,通常为三个。一个导体用于数据接收,一个导体用于数据发送,一个导体用于同步,另一个导体用于选择与之通信的设备。它是一个全双工连接,这意味着数据是同时发送和接收的。最大波特率高于I2C通信系统中的波特率。

板的SPI引脚

SPI使用以下四条线:

  • SCK – 这是由主机驱动的串行时钟。
  • MOSI – 这是由主机驱动的主输出/从输入。
  • MISO – 这是由主机驱动的主输入/从输出。
  • SS – 这是从机选择线。

使用以下函数,必须包括SPI.h.

  • SPI.begin() – 通过将SCK,MOSI和SS设置为输出来初始化SPI总线,将SCK和MOSI拉低,将SS拉高。
  • SPI.setClockDivider(分频器) – 相对于系统时钟设置SPI时钟分频器。在基于AVR的板上,可用的分频器为2,4,8,16,32,64或128。默认设置为SPI_CLOCK_DIV4,它将SPI时钟设置为系统时钟的四分之一(对于20 MHz的电路板为5 Mhz)。
  • Divider – 它可以是(SPI_CLOCK_DIV2,SPI_CLOCK_DIV4,SPI_CLOCK_DIV8,SPI_CLOCK_DIV16,SPI_CLOCK_DIV32,SPI_CLOCK_DIV64,SPI_CLOCK_DIV128)。
  • SPI.transfer(val) – SPI传输基于同时发送和接收:接收的数据在receivedVal中返回。
  • SPI.beginTransaction(SPISettings(speedMaximum,dataOrder,dataMode)) – speedMaximum是时钟,dataOrder(MSBFIRST或LSBFIRST),dataMode(SPI_MODE0,SPI_MODE1,SPI_MODE2或SPI_MODE3)。

SPI中有四种操作模式,如下所示:

  • 模式0(默认值) – 时钟通常为低电平(CPOL = 0),数据在从低电平到高电平(前沿)(CPHA = 0)的转换时采样。
  • 模式1 – 时钟通常为低电平(CPOL = 0),数据在从高电平到低电平(后沿)(CPHA = 1)的转换时采样。
  • 模式2 – 时钟通常为高电平(CPOL = 1),数据在从高电平到低电平(前沿)(CPHA = 0)的转换时采样。
  • 模式3 – 时钟通常为高电平(CPOL = 1),数据在从低电平到高电平(后沿)(CPHA = 1)的转换时采样。
  • SPI.attachInterrupt(handler) – 当从设备从主设备接收数据时调用的函数。

现在,我们将两个Arduino UNO板连接在一起;一个作为主机,另一个作为从机。

  • (SS):引脚10
  • (MOSI):引脚11
  • (MISO):引脚12
  • (SCK):引脚13

接地是常见的。以下是两个电路板之间的连接的图示:

两个电路板之间的连接

让我们看看SPI作为主机和SPI作为从机的例子。

SPI为主机

例子

#include <SPI.h>

void setup (void) {
   Serial.begin(115200); //set baud rate to 115200 for usart
   digitalWrite(SS, HIGH); // disable Slave Select
   SPI.begin ();
   SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
}

void loop (void) {
   char c;
   digitalWrite(SS, LOW); // enable Slave Select
   // send test string
   for (const char * p = "Hello, world!\r" ; c = *p; p++) {
      SPI.transfer (c);
      Serial.print(c);
   }
   digitalWrite(SS, HIGH); // disable Slave Select
   delay(2000);
}

SPI为从机

例子

#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;

void setup (void) {
   Serial.begin (115200);
   pinMode(MISO, OUTPUT); // have to send on master in so it set as output
   SPCR |= _BV(SPE); // turn on SPI in slave mode
   indx = 0; // buffer empty
   process = false;
   SPI.attachInterrupt(); // turn on interrupt
}
ISR (SPI_STC_vect) // SPI interrupt routine { 
   byte c = SPDR; // read byte from SPI Data Register
   if (indx < sizeof buff) {
      buff [indx++] = c; // save data in the next index in the array buff
      if (c == '\r') //check for the end of the word
      process = true;
   }
}

void loop (void) {
   if (process) {
      process = false; //reset the process
      Serial.println (buff); //print the array on serial monitor
      indx= 0; //reset button to zero
   }
}

发布者:suiyublg,转转请注明出处:https://huibian.net/1307-2/

(115)
suiyublg的头像suiyublg
上一篇 2017年4月10日 15:24
下一篇 2017年4月12日 16:42

相关推荐

  • Arduino教程35.Arduino 多维数组

    具有两个维度(即,下标)的数组通常表示由排列在行和列中的信息组成的值的表格。 以下是多维数组的关键特性: 下图说明了一个二维数组 a 。该数组包含三行四列,因此它是一个3乘4的数组。通常,具有 m 行和 n 列的数组称为 m乘n数组。 数组 a 中的每个元素都由&nbs…

    2017年3月30日
    44100
  • Arduino电机控制03.Arduino 步进电机

    步进电机是无刷同步电机,它将完整的旋转分成多个步骤。与无刷直流电机不同,当向其施加固定的直流电压时,它将连续旋转,步进电机以不连续的步进角旋转。 因此,步进电机被制造成具有每转12,24,72,144,180和200的步长,从而产生每步30°,15°,5°,2.5°,2°和1.8°的步进角。步进电机可以有或没有反馈控制。 想象一下在RC飞机上的电机。电机在一…

    2017年4月28日
    80600
  • Arduino电机控制01.Arduino 直流电机

    在本章中,我们将使用Arduino板(UNO)连接不同类型的电机,并向你展示如何连接电机并从电路板上驱动它。 有三种不同类型的电机: 直流电机(DC—Direct Current motor)是最常见的电机类型。直流电动机通常只有两个引线,一个正极和一个负极。如果将这两根引线直接连接到电池,电机将旋转。如果切换引线,电机将以相反的方向旋转…

    2017年4月26日
    1.0K00
  • Arduino教程19.Arduino 复合运算符

    假设变量A为10,变量B为20,则: 运算符名称 运算符简写 描述 例子 自增 ++ 自增运算符,将整数值增加1 A++ 将得出11 自减 — 自减运算符,将整数值减1 A– 将得出9 复合加 += 加且赋值运算符。把右边操作数加上左边操作数的结果赋值给左边操作数。 B += A等效于B = B + A 复合减 -= 减且赋…

    2017年3月23日
    40100
  • Arduino教程33.Arduino micros()函数

    micros()函数返回Arduino板开始运行当前程序时的微秒数。该数字在大约70分钟后溢出,即回到零。在16 MHz Arduino板(例如Duemilanove和Nano)上,此函数的分辨率为4微秒(即返回值总是4的倍数)。在8 MHz Arduino板(例如LilyPad)上,此函数的分辨率为8微秒。 micros()函数语法 micros () ;…

    2017年3月29日
    38600

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

评论列表(6条)

  • atubo的头像
    atubo 2017年6月1日 12:01

    我喜欢这个主题

    • 995392470的头像
      995392470 2017年11月24日 14:53

      @atubojhgcf

  • 995392470的头像
    995392470 2017年11月24日 14:53

    jjh

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
欢迎大家来到大雄学编程!