树莓派学习 26.SPI通讯

一、SPI简介

SPI全称是串行外设接口(Serial Peripheral Interface),是由Motorola提出的一种全双工同步串行通信接口,通信波特率可以高达5Mbps,但具体速度大小取决于SPI硬件。SPI接口具有全双工操作,操作简单,数据传输速率较高的优点,但也存在没有指定的流控制,没有应答机制确认是否接收到数据的缺点。SPI总线只需四条线就可以完成MCU与各种外围器件的通讯:

  • SCLK:Serial Clock,(串行)时钟
  • MISO:Master In Slave Out,主设备输入,从设备输出
  • MOSI:Master Out Slave In,主设备输出,从设备输入
  • SS: Slave Select,选中从设备,片选,片选的其他别称[① CS(Chip Select)芯片选择、②CE(Chip Enable)芯片使能]

二、SPI通讯

1. 串行读写

SPI是[单主设备(single-master )]通信协议,这意味着总线中的只有一支中心设备能发起通信。当SPI主设备想读/写[从设备]时,它首先拉低[从设备]对应的SS线(SS是低电平有效),接着开始发送工作脉冲到时钟线上,在相应的脉冲时间上,[主设备]把信号发到MOSI实现“写”,同时可对MISO采样而实现“读”。

在这里插入图片描述

2. 数据交换

SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响,SPI主模块和与之通信的外设音时钟相位和极性应该一致。

  1. 如果CPOL=0,串行同步时钟的空闲状态为低电平;
  2. 如果CPOL=1,串行同步时钟的空闲状态为高电平;
  3. 时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。
  4. 如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;
  5. 如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样;

3. 数据传输

在一个SPI时钟周期内,会完成如下操作:

  1. 主设备通过MOSI线发送1位数据,从设备通过该线读取这1位数据;
  2. 从设备通过MISO线发送1位数据,主设备通过该线读取这1位数据。

这是通过移位寄存器来实现的。

4. 引脚

在这里插入图片描述

  • VCC----1
  • GND----6
  • 19 MOSI – master output slave input
  • 21 MISO – master input slave output
  • 23 SCLK – clock
  • 24 CE0 – chip enable 0
  • 26 CE1 – chip enable 1

5. 启用SPI

在设置里启用SPI。
sudo raspi-config
启用后可输入命令查看:

pi@ventilator:~ $ ls /dev/spidev0.*
/dev/spidev0.0  /dev/spidev0.1

树莓派只引出来一组spi(引脚19、21、23、24),对应的设备文件为/dev/spidev0.0。

三、代码实现

1. 回声测试:将MOSI 和 MISO短接。

源码地址

运行效果:
在这里插入图片描述

本文部分内容来源:https://blog.csdn.net/TAlice/article/details/83868713

2. 另一个测试代码:

wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
# 注意要将代码里的/dev/spidev1.1改为/dev/spidev0.1
gcc spidev_test.c
sudo ./a.out

输出:
在这里插入图片描述

3. 安装spidev

官网说明:https://pypi.org/project/spidev/3.1/

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-dev python3-dev
cd ~
git clone https://github.com/doceme/py-spidev.git
cd py-spidev
make
sudo make install
属性及方法
属性/函数作用
bits_per_word每个单词字节数
cshigh片选信息,默认为False
lsbfirst大小端,默认为False
max_speed_hz最大总线速度
modespi的工作模式,用来确定时钟和片选信号是上升还是下降沿开始读写,这个可能跟具体的芯片有关
函数 open(bus, device)打开设备,bus和device对应设备后面的数字:如图
xfer([values])向spi设备发送命令,这个函数返回一个列表,存放接收到的数据
xfer2([values])与上面函数作用相同,不同的是,xfer在当前片选引脚为高电平工作,xfer2在执行过程中将片选引脚保持低电平,在两次转换间让cs引脚保持为高电平。
使用spidev

python-spidev的使用方法:

# 导入库
import spidev

bus=0
device=0
# 打开spi设备,此处设备为/dev/spi-decv0.0
spi=SPI.SpiDev(bus,device)

# 从SPI设备读取n字节
spi.readbytes(n)

# 将列表的数据写到SPI设备
spi.writebytes(list of value)

# 执行SPI传输。
spi.xfer(list of values[, speed_hz, delay_usec, bits_per_word])

示例
import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 7629

# Split an integer input into a two byte array to send via SPI
def write_pot(input):
        msb = input >> 8
        lsb = input & 0xFF
        spi.xfer([msb, lsb])

# Repeatedly switch a MCP4151 digital pot off then on
while True:
        write_pot(0x1FF)
        time.sleep(0.5)
        write_pot(0x00)
        time.sleep(0.5)


SPI 速度值列表
Speed spi.max_speed_hzvalue
125.0 MHz125000000
62.5 MHz62500000
31.2 MHz31200000
15.6 MHz15600000
7.8 MHz7800000
3.9 MHz3900000
1953 kHz1953000
976 kHz976000
488 kHz488000
244 kHz244000
122 kHz122000
61 kHz61000
30.5 kHz30500
15.2 kHz15200
7629 Hz7629

文章参考:http://hfwudao.cn/a/raspberry-learn-26-SPI

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐