0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

树莓派Pico的数字通信协议:I2C和SPI介绍

jf_zGNBEhbi 来源:趣无尽 2023-11-14 15:05 次阅读

前面的章节中,我们已经了解了如何使用一些常见的硬件,但随着构建的项目越来越多,你可能想要扩展到使用各种不同的传感器和显示器。要如何与这些设备通信

有时,你可能会发现有一个 MicroPython 库可以使用,其中有人已经将低级函数转换为易于使用的接口。然而,情况并不总是这样。幸运的是,有一些连接低级数字设备的标准方法在 MicroPython 中通过 I2C 和 串行外设接口(SPI)得以实现。

I2C 和 SPI 在许多方面非常相似,因为它们都定义了一种将两个设备之间的双向接口连接的方式。事实上,许多部件都有这两种版本接口,这样你就可以选择一个适合你的项目的接口。在这两种情况下,都需要一个主控设备来控制通信(树莓派 Pico)和一个或多个设备等待来自主控设备的指令。然而,也有一些不同之处。我们会时不时地对比这两种协议帮助你从中作出合适的选择

I2C

I2C 的通信在两条线上进行:一个时钟(通常标记为 SCL)和一个数据通道(通常标记为SDA)。

65272854-82bb-11ee-939d-92fbcf53809c.png

这两个引脚都必须连接到 Pico 的特定引脚上。Pico 上有两个 I2C 总线(I2C0 和 I2C1),你可以使用其中一种。在我们的示例中,我们将使用 I2C0—GP0 用于 SDA,GP1 用于 SCL。

为了演示这些协议,我们将使用 SparkFun 的 SerLCD 模块。这样做的优点是它同时拥有 I2C 和 SPI 接口,因此我们可以看到在相同的硬件下这两种方法之间的区别。如果只使用 I2C 接口,也可以使用带 I2C 接口的 LCD1602 液晶屏模块替代。

这个液晶显示器可以显示两行,每一行最多 16 个字符。它是一种有用的设备,可以输出关于我们系统的信息。让我们看看如何使用它。

将 Pico 上的 SDA 引脚与 LCD 上的 SDA 引脚连接,SCL 引脚与 LCD 上的 SCL 引脚连接。由于 I2C 处理通信的方式,还需要一个电阻连接 SDA 到 3.3V 和 SCL 到 3.3V。通常是 4.7kΩ。然而,我们的设备已经包含了这些电阻,所以我们不需要添加任何额外的电阻。

653985d0-82bb-11ee-939d-92fbcf53809c.png

图为 I2C 连接一个串行 LCD 模块,编程让它显示信息非常简单:

import machine
sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)
i2c.writeto(114, 'x7C')
i2c.writeto(114, 'x2D')
i2c.writeto(114, "hello world")

这段代码并没有做很多事情。它连接到 I2C 设备并发送一些数据。然而,也有一些看起来有点不寻常。writeto() 行中的 114 指的是 I2C 设备的地址。你可以将许多设备连接到 I2C 总线,每次要发送或接收数据时,都需要指定要与之通信的设备的地址。这个地址是硬连接到设备上的。

你应该在设备的文档中找到设备的地址,你也可以扫描 I2C 总线来查看当前使用的地址。设置好 I2C 总线后,可以运行 scan 方法输出当前使用的地址:

import machine
sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)
print(i2c.scan())

下一个看起来有点奇怪的位是写入的 x7C 和 x2D 命令。每一个 I2C 设备需要以特定格式发送数据。这方面没有标准,所以你必须参考设备的文档了解你正在设置的 I2C 设备。每一个开头的 x 告诉 MicroPython,我们正在发送一个十六进制字符串,这是一种常见的方式,以确保你正在发送你想要的确切数据。对于我们的液晶显示器,7C 进入命令模式,2D 清空液晶显示器,并将光标设置到开始。接下来,我们可以发送数据显示到屏幕上:

file.close()

当然,在屏幕上只显示 Hello World 并没有多大用处,所以让我们看看如何把它变成一个更有用的东西——温度计。在之前的系列教程中,我们学习了如何使用 Pico 的内部温度传感器使用 ADC 读取温度。现在,我们可以在此代码的基础上构建一个独立的温度计,它不需要计算机读取输出。在你的 LCD 仍然像之前一样连接,运行以下代码:

import machine
import utime


sda=machine.Pin(0)
scl=machine.Pin(1)
i2c=machine.I2C(0,sda=sda, scl=scl, freq=400000)


adc = machine.ADC(4)
conversion_factor = 3.3 / (65535)


while True:
  reading = adc.read_u16() * conversion_factor
  temperature = 25 - (reading - 0.706)/0.001721
  i2c.writeto(114, 'x7C')
  i2c.writeto(114, 'x2D')
  out_string = "Temp: " + str(temperature)
  i2c.writeto(114, out_string)
  utime.sleep(2)

这看起来应该很熟悉。对之前的温度代码的唯一细微变化是,在输出计算结果之前,LCD 需要显示字符,因此我们使用 str 函数将数字转换为字符串。然后,我们可以将它与 “Temp:” 组合起来,将其构建为一个信息更丰富的输出。

如你所见,I2C 是一种将其他硬件链接到 Pico 的简单方法。你需要确保你有任何你想要连接的设备的设备文档,让你知道什么命令做什么,但只要你知道这一点,你可以很容易地添加各种各样的比特和鲍勃到你的 Pico 和创建令人印象深刻的构建。

串行外围接口

我们已经了解了 I2C 的工作原理,现在让我们来看看 SPI。我们将使用完全相同的 LCD,因此命令和其他一切都是相同的,只是我们发送数据的协议不同 SPI 有四个连接:SCLK、MOSI、MISO 和 CS(有时标记为SS)。SCLK 是时钟,MOSI 是将数据从你的 Pico 到外围设备。MISO 将数据从外围设备发送到 Pico。CS 代表芯片选择用于将多个设备连接到单个 SPI 总线。你可以把 CS 到 GPIO 引脚并切换这个开关来启用和禁用显示,但由于我们只有一个设备,我们可以简单地将它连接到 GND,以保持它的启用。因此,SerLCD 的电源线连接到 VBUS 和 GND,我们只需要连接 itsSDO 到 Pico 的 MISO (GP4/SPI0 RX),SDI 接到 MOSI (GP3/SPI0 TX),SCK 接到 SCLK(GP2/SPI0 TX),SCK 和 CS 接到 GND。

654d53a8-82bb-11ee-939d-92fbcf53809c.png

SPI 需要四个连接:一个从主服务器获取数据设备到从设备,另一个在相反的方向上获取数据,加上电源和 GND。两根数据线意味着数据可以同时在两个方向上旅行。这些通常被称为 Master Out Slave In (MOSI) 和 Master In Slave Out (MISO)。然而,你会见到不同的叫法。如果你看一下 Raspberry Pi Pico 引脚图,它们被称为 SPI TX(发送)和 SPI RX(接收)。这是因为 Pico 可以是两者之一主设备或从设备,所以无论这些连接是 MOSI 还是 MISO,取决于 Pico 的当前功能。在我们使用的液晶显示器上,它们被标记为 SDI(串行数据输入)和 SDO(串行数据输出)SPI 中没有地址,所以我们可以直接写代码:

import machine


spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi_rx=machine.Pin(4)


spi=machine.SPI(0,baudrate=100000,sck=spi_sck, mosi=spi_tx, miso=spi_rx)


spi.write('x7C')
spi.write('x2D')
spi.write("hello world")

在这种情况下,我们使用的是 SPI0,一组可用的引脚是 GP2、GP3 和 GP4。大多数类型的串行通信有一个速度或波特率,这基本上是多少每秒可以通过信道传输的数据位。很多事情都会影响这个,比如连接的两个设备的能力和它们之间的连接(多长时间)如果有其他设备的干扰。如果你发现数据错误或丢失问题,那么你可能需要减少它。对于我们的小屏幕,我们只发送一个字节的数据字符,因此我们发送它的速度并不重要,但是对于其他一些SPI设备,微调波特率可能很重要。

让我们看看下面我们的使用的温度计代码:

import machine
import utime


spi_sck=machine.Pin(2)
spi_tx=machine.Pin(3)
spi_rx=machine.Pin(4)


spi=machine.SPI(0,baudrate=100000,sck=spi_sck, mosi=spi_tx, miso=spi_rx)


adc = machine.ADC(4)
conversion_factor = 3.3 / (65535)


while True:
  reading = adc.read_u16() * conversion_factor
  temperature = 25 - (reading - 0.706)/0.001721
  spi.write('x7C')
  spi.write('x2D')
  out_string = "Temp: " + str(temperature)
  spi.write(out_string)
  utime.sleep(2)

正如你所看到的,I2C 和 SPI 之间的代码实际上差别很小。一旦你完成了电路和代码,唯一的真正改变是与 I2C 你指定的地址发送数据。

那么,既然它们如此相似,在构建项目时你应该选择哪种协议呢?有需要考虑的几个因素。第一个是你想要附加的东西的可用性。有时,一个传感器只能支持 I2C 或 SPI,所以你必须使用它。但是,如果你有选择的话对于硬件来说,当你使用多个额外的设备时,影响最大。通过 I2C 你可以在一个 I2C 总线上连接多达 128 个设备;然而,它们都需要有一个单独的地址。这些地址是硬连接的。如果你想要更多相同类型的传感器,你可能会受到传感器的 I2C 地址数量的限制。在本例中,SPI 也许是更好的选择。

另外,SPI 可以有无限数量的设备连接;然而,每一个都必须有自己的 CS 引脚。在 Pico 上,有 26 个 GPIO 引脚。所以这意味着有 23 哥可用的 CS 引脚。这是假设你不需要任何其他东西。如果可用的 GPIO 非常紧缺,那么你可能需要考虑 I2C。

实际上,对于许多项目,你都可以随意地使用其中任何一种协议,你可能会发现这选择使用哪一个更多的是与你在零件箱里找到的零件有关,而不是两者在技术上的区别。





审核编辑:刘清

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

    关注

    28

    文章

    743

    浏览量

    39853
  • 树莓派
    +关注

    关注

    113

    文章

    1646

    浏览量

    104815

原文标题:树莓派 Pico 的数字通信协议:I2C 和 SPI

文章出处:【微信号:趣无尽,微信公众号:趣无尽】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    数字通信协议中,什么是I2CSPI总线协议

    现今,在低端数字通信应用领域,我们随处可见IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种
    的头像 发表于 11-12 09:28 1.1w次阅读
    <b class='flag-5'>数字通信协议</b>中,什么是<b class='flag-5'>I2C</b>和<b class='flag-5'>SPI</b>总线<b class='flag-5'>协议</b>?

    3分钟理解通信协议I2C总线 #通信协议

    通信协议I2CI2C总线总线/接口技术
    硬声课堂
    发布于 :2021年10月18日 10:39:12

    I2C通信协议手册找不到广为流传的内容

    在学习I2C通信协议的时候,翻了一遍I2C协议手册,却找不到:“在进行I2C通信发送数据的时候,
    发表于 04-05 00:27

    I2C通信协议介绍

    的串行通信协议主要有EIA-232、EIA-232、EIA-485、USB、IEEE 1394几种: 以下着重介绍I2C总线:一、I2C总线概述:I
    发表于 07-19 02:36

    i2c通信协议

    1.1 i2c通信协议通信协议:用来实现数据传输。i2c物理总线:SCL(时钟线) SDA(数据线)i2c
    发表于 03-06 16:15

    I2C通信协议硬软件

    目录12C通信协议硬软件I2CAHT20测温湿度参考12C通信协议I2C
    发表于 08-23 07:42

    I2C通信协议简介

    一.I2C通信协议简介1.物理层I2C物理层有以下特点:I2C是支持多设备的总线,支持多个通讯主机、多个通讯从机I2C使用两条总线线路,SD
    发表于 01-13 07:20

    I2C协议介绍

    多个寄存器I2C 连续读多个寄存器I2C数据仲裁介绍I2C 调查标准I2C协议
    发表于 01-20 08:04

    linux移植MPU6050的I2C驱动过程分享

    有MPU6050的例程,测试后很好用,如下图(梦幻联动一下:树莓PICO+freeRTOS)因为pico上有现成的能用的例程,所以改一改之后直接移植到linux上首先
    发表于 02-10 06:48

    SPI通信协议讲解相关资料推荐

    SPI通信协议讲解SPI通信概念SPI通信SPI
    发表于 02-17 06:09

    I2C通信协议的原理是什么

    I2C通信协议I2C通信原理I2C通信原理:I2C
    发表于 02-17 07:16

    I2C总线通信协议的相关资料下载

    基于I2C总线通信协议的温度采集实验(基于AHT20) I2C总线通信协议简介 AHT20简介 一.项目说明1)实战目标:2)实战元件: 二
    发表于 02-22 07:37

    spii2c总线协议的对比分析

    现今,在低端数字通信应用领域,我们随处可见I2C (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种
    发表于 12-06 11:57 1921次阅读

    SPI通信协议讲解

    SPI通信协议讲解SPI通信概念SPI通信SPI
    发表于 12-22 19:19 25次下载
    <b class='flag-5'>SPI</b><b class='flag-5'>通信协议</b>讲解

    i2cspi通信协议的概念与区别 I2C/SPI总线通信协议你搞懂没有

    计划第四期:硬声UP主@硬件研究狮 从工程实践的角度,给大家拆解I2CSPI。     四分钟搞定通信协议的分类 简介: 同步通信与异步通信
    的头像 发表于 06-23 17:19 3085次阅读