Arduino常用的三种通信协议 2

电子说

1.3w人已加入

描述

下面我们还是用两块Arduino来实践一下如何利用I2C协议来传输数据。如图连接好两块Arduino:

uart

一台我们作为主设备(Master),烧录以下代码:

#include 


void setup() {
 Serial.begin(9600); /* begin serial comm. */
 Wire.begin(); /* join i2c bus as master */
 Serial.println("I am I2C Master");
}


void loop() {
 Wire.beginTransmission(8); /* begin with device address 8 */
 Wire.write("Hello Slave");  /* sends hello string */
 Wire.endTransmission();    /* stop transmitting */


 Wire.requestFrom(8, 9); /* request & read data of size 9 from slave */
 while(Wire.available()){
    char c = Wire.read();/* read data received from slave */
  Serial.print(c);
 }
 Serial.println();
 delay(1000);
}

另一块作为从设备(Slave),烧录以下代码:

#include 


void setup() {
 Wire.begin(8);                /* join i2c bus with address 8 */
 Wire.onReceive(receiveEvent); /* register receive event */
 Wire.onRequest(requestEvent); /* register request event */
 Serial.begin(9600);           /* start serial comm. */
 Serial.println("I am I2C Slave");
}


void loop() {
 delay(100);
}


// function that executes whenever data is received from master
void receiveEvent(int howMany) {
 while (0 char c = Wire.read();      /* receive byte as a character */
    Serial.print(c);           /* print the character */
  }
 Serial.println();             /* to newline */
}


// function that executes whenever data is requested from master
void requestEvent() {
 Wire.write("Hi Master");  /*send string on request */
}

这样,我们就实现了主从设备的双向传输。打开主机Arduino的串口监视器我们可以看见如下的输出:

uart

从机Arduino的串口输出:

uart

I2C虽然只需要两根线,就能支持多主机多从机的数据传输,但由于只有一根用于数据传输,它通过在“接收”和“传输”两种状态之间但切换实现了双向传输,但牺牲了不少传输速率。I2C还有典型的开漏问题,总线需要加上拉电阻。

SPI协议

最后,我们来看一下SPI协议。SPI全称Serial Peripheral Interface(串行外设接口),由摩托罗拉公司提出的一种同步串行数据传输协议。SPI类似I2C也是同步通信的协议,但是全双工,支持数据的同时输出和输入。这两个特征使SPI的传输速率比UART和I2C都高,这对于像SD卡、或者屏幕等数据型模块来说,是非常具有优势的。

uart

SPI支持一主多从的模式,但SPI也是三种协议中需要线最多的协议,一共需要4条信号线:

uart

但Arduino UNO默认的SPI引脚分别为D13(SCK), D12(MISO), D11(MOSI), D10(SS),其中SS是从机选择引脚,没有强制要求,你也可以选其他的引脚。uart

同样,我们来实践一下用SPI实现数据传输。

uart

uart

如图连接好两块Arduino UNO。还是一块作为主机(Master), 另一块作为从机(Slave)。Arduino对SPI协议也做了类封装:

https://www.arduino.cc/en/reference/SPI

主机烧录以下代码:

#include 


void setup (void)
{
  Serial.begin(115200);
  digitalWrite(SS, HIGH);
  SPI.begin ();
  SPI.setClockDivider(SPI_CLOCK_DIV8);
}


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

从机烧录:

#include 
char buf [100];
volatile byte pos;
volatile boolean process_it;

void setup (void)
{
  Serial.begin (115200);   // debugging
  // turn on SPI in slave mode
  SPCR |= bit (SPE);
  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;
  // now turn on interrupts
  SPI.attachInterrupt();
}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register
  // add to buffer if room
  if (pos < sizeof buf)
  {
    buf [pos++] = c;
    // example: newline means time to process buffer
    if (c == '\\n')
      process_it = true;
  }  // end of room available
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  if (process_it)
  {
    buf [pos] = 0;
    Serial.println(buf);
    pos = 0;
    process_it = false;
  }  // end of flag set

}  // end of loop

这样从机就能接受到主机发过来的消息了。

总结

今天,我们粗略地介绍了一下Arduino数据通信中最常用的三种协议:UART、I2C和SPI。

| **协议

** | **通信方式

** | **通信方向

** | **信号线

** | **传输速率

** | **主从模式

**
UART
异步
全双工 2线RX、TX 最低
一对一
I2C
同步
半双工
2线SDA、SCL,以地址选择从机
多主机多从机
SPI
同步
全双工 4线MOSI、MISO、SCLK、CS(或SS),以CS选择从机
一主多从

它们各自都有自己的优缺点和适用的场景,并没有绝对的好坏,这也是这三种协议经久不衰的原因。只有了解并掌握它们,我们才能在具体的应用场景里选择最合适的协议。当然在嵌入式世界里,还有其他很多协议,小编以后再介绍吧。如果对这三种协议的底层感兴趣的朋友,也可以自己再去深入了解。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分