SPI同步串行通信
UART串口通信中的数据只能一位一位的传输,如果数据量比较大的时候,传输速率会受到很大影响,此时我们就可以考虑使用同步串行通信了,比如SPI。
SPI通信原理
SPI,全称是Serial Peripheral Interface,也就是串行外设接口,同样是一种通信协议,在很多芯片中都有集成。
相比之前学习的UART串口通信,他多了两根线,其中一个是时钟信号,另一个是设备使能信号,用来控制设备是否启用,所以也产生了主从设备的概念。
-
MISO:Master Input Slave Output,主设备数据输入,从设备数据输出;
-
MOSI:Master Output Slave Input,主设备数据输出,从设备数据输入;
-
SCLK:Serial Clock,时钟信号,由主设备产生;
-
CS:Chip Select,从设备使能信号,由主设备控制。
这样,在一组SPI通信的系统中,可以连接多个设备,想要和哪个设备通信时,就使能这个设备,除能其他设备。
我们在开发中常见的SPI设备会有一些传感器,还有电阻屏之类的。
硬件连线
在SPI的通信中,有一个管脚负责发送,另外一个管脚负责接收,如果我们把同一组SPI的发送和接收接到一起,岂不是能接收到自己发送的数据吗?
我们不妨来试一试,这里使用一个跳线帽直接把19,21两个SPI的通信管脚短接。
运行示例程序
大家来运行例程,看看会发生什么?
在旭日X3派的终端中,输入运行例程的指令,接下来我们就可以看到通过SPI传输并收到的数据啦,相当于是左手传递给右手,自己给自己循环传输数据了。
代码解析
test_spi.py:
#!/usr/bin/env python3
import sys
import os
import time
# 导入spidev模块
import spidev
def BytesToHex(Bytes):
return ''.join(["0x%02X " % x for x in Bytes]).strip()
def spidevTest():
# 设置spi的bus号(0, 1, 2)和片选(0, 1)
spi_bus = input("Please input SPI bus num:")
spi_device = input("Please input SPI cs num:")
# 创建spidev类的对象以访问基于spidev的Python函数。
spi=spidev.SpiDev()
# 打开spi总线句柄
spi.open(int(spi_bus), int(spi_device))
# 设置 spi 频率为 12MHz
spi.max_speed_hz = 12000000
print("Starting demo now! Press CTRL+C to exit")
# 发送 [0x55, 0xAA], 接收的数据应该也是 [0x55, 0xAA]
try:
while True:
resp = spi.xfer2([0x55, 0xAA])
print(BytesToHex(resp))
time.sleep(1)
except KeyboardInterrupt:
spi.close()
if __name__ == '__main__':
print("List of enabled spi controllers:")
os.system('ls /dev/spidev*')
spidevTest()
在python中使用spidev这个库,初始化X3Pi的SPI,之后使用xerf2发送数据,同时接收数据,并打印出来,会发现打印出来的就是我们发送的。