您现在的位置是:网站首页> 硬件
Arduino常用的三种通信协议UART, I2C和SPI
- 硬件
- 2021-03-29
- 945人已阅读
UART协议UART的全称叫 Universal Asynchronous Reception and Transmission通用异步收发。从名字我们就可以知道,UART是异步串行通信的。利用UART协议传输数据时,需要两个数据引脚,一个用于传输数据的TX,另一个用于接收的RX。Arduino板上默认的RX和TX引脚分别是Pin0和Pin1。UART硬件层和软件层的功能都是Arduino集成的,一般我们不需要从底层操作数据。一个UART口(一组RX和TX)只能连接一个UART设备进行通信,我们需要这样就接线:
注意,一个设备的TX接的是另一设备的RX,反之RX接TX,最后需要将两个设备共地,共地是让它们的参考电压一致。下面,我们用两块Arduino实际实践一下。如图连接两个Arduino:
我们在Arduino A里烧录以下代码:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() { // put your main code here, to run repeatedly:
char s[]="I am Arduino A";//每隔1s发送一次字符数组s
Serial.print(s);
delay(1000);
}
再在Arduino B里烧录以下代码:
String a=""; //定义字符串,接收数据
void setup() { // put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
while(Serial.available())//当发现缓存中有数据时,将数据送至字符数组a中
{
a+=char(Serial.read());
delay(3);
}
if (a.length() > 0){
Serial.println(a);
a = ""
}
}
这样就A就通过UART向B发送了“ I am Arduino A”消息,B接收到以后输出。当然你可以修改A的代码实现双向数据传输,这里我们就点到即止了。UART是最常见的通信协议之一,它可以实现全双工传输,但它的传输速度比较慢,而且只能支持一对一的设备。 I2C协议I2C是Philips公司在1980年代发明的一种协议,全称是Inter-Integrated Circuit。I2C最常被应用于模块或者传感器之间的通信,因为I2C基于二根传输线,同步通信的半双工协议,而且协议也非常简单可靠。 I2C使用两根传输线实现一个主设备与多个从设备,甚至是多个主设备与对应从设备之间的通信。 这两根通讯线一根为控制时钟线,称之为SCL,用于同步设备间的数据传输时钟; 另一根为数据线,称之为SDA,用于携带数据。理论上,一条I2C总线上能支持挂载128台设备。
Arduino UNO的I2C引脚是A4(SDA), A5(SDL)。Arduino对I2C协议也进行了库封装:
https://www.arduino.cc/en/Reference/Wire
下面我们还是用两块Arduino来实践一下如何利用I2C协议来传输数据。如图连接好两块Arduino:
一台我们作为主设备(Master),烧录以下代码:
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),烧录以下代码:
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 (1 < Wire.available())
char c = Wire.read(); /* receive byte as a character */
Serial.print(c); /* print the character */
}
Serial.println("ok");
/* to newline */
}
//function that executes whenever data is requested from master
void requestEvent()
{
Wire.write("Hi Master"); /*send string on request */
}
这样,我们就实现了主从设备的双向传输。打开主机Arduino的串口监视器我们可以看见如下的输出:
从机Arduino的串口输出:
https://www.arduino.cc/en/reference/SPI
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);
}
从机烧录:
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
routineISR (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 routinevoid
loop (void)
{
if (process_it)
{
buf [pos] = 0;
Serial.println(buf);
pos = 0;
process_it = false;
}
// end of flag set
} // end of loop
协议 | 通信方式 | 通信方向 | 信号线 | 传输速率 | 主从模式 |
UART | 异步 | 全双工 | 最低 | 一对一 | |
I2C | 同步 | 半双工 | 低 | ||
SPI | 同步 | 全双工 | 高 | 一主多从 |
相关文章
- 什么是嵌入式工控机?嵌入式工控机品牌有哪些?带GPIO口的工控机
- Arduino通用研发信息收集
- PC是非intel厂家对IP的称呼,也就是说PC起始跟CS:IP是一回事儿。
- 3.7V4.2V1A锂电池聚合物充放电模块 5V升压板diy手机移动电源电路
- 六合一多功能转串口模块USB转UART CP2102 CH340 TTL 485 232 CAN
- AVR单片机和STM8S STM32 8051
- 433天线IPEX-1 转SMA
- 监控摄像头离录像机远
- 增强版高速USB转SPI PWM ADC GPIO UART CAN I2C IIC监控分析仪
- 如何通过 Arduino IDE 玩转乐鑫 ESP32 模块