Схемы выводов Raspberry Pi 2 и 3

Штырьковый разъем Raspberry Pi 2 и 3

Аппаратные интерфейсы для Raspberry Pi 2 и Raspberry Pi 3 предоставляются через 40-штырьковый разъем J8 на плате. Он поддерживает следующие функции:

  • 24x — штырьки GPIO
  • 1x — последовательные УАПП (у RPi3 есть только мини-УАПП)
  • 2x — Шина SPI
  • 1x — Шина I2C
  • 2x — контакты питания на 5В
  • 2x — контакты питания на 3,3 В
  • 8x — контакты заземления

Штырьки GPIO

Давайте рассмотрим GPIO, доступный на этом устройстве.

Обзор штырьков GPIO

Следующие штырьки GPIO доступны через API:

№ GPIO Включение питания Альтернативные функции Штырьковый разъем
2 Повышающий I2C1 SDA 3
3 Повышающий I2C1 SCL 5
4 Повышающий 7
5 Повышающий 29
6 Повышающий 31
7 Повышающий SPI0 CS1 26
8 Повышающий SPI0 CS0 24
9 Понижающий SPI0 MISO 21
10 Понижающий SPI0 MOSI 19
11 Понижающий SPI0 SCLK 23
12 Понижающий 32
13 Понижающий 33
16 Понижающий SPI1 CS0 36
17 Понижающий 11
18 Понижающий 12
19 Понижающий SPI1 MISO 35
20 Понижающий SPI1 MOSI 38
21 Понижающий SPI1 SCLK 40
22 Понижающий 15
23 Понижающий 16
24 Понижающий 18
25 Понижающий 22
26 Понижающий 37
27 Понижающий 13
35* Повышающий Красный светодиодный индикатор питания
47* Повышающий Зеленый светодиодный индикатор активности

* = ТОЛЬКО Raspberry Pi 2 GPIO 35 и 47 недоступны на Raspberry Pi 3.

Пример GPIO

Например, следующий код открывает GPIO 5 на выход и записывает цифровое значение "1" на выходе штырька:

using Windows.Devices.Gpio;

public void GPIO()
{
    // Get the default GPIO controller on the system
    GpioController gpio = GpioController.GetDefault();
    if (gpio == null)
        return; // GPIO not available on this system

    // Open GPIO 5
    using (GpioPin pin = gpio.OpenPin(5))
    {
        // Latch HIGH value first. This ensures a default value when the pin is set as output
        pin.Write(GpioPinValue.High);

        // Set the IO direction as output
        pin.SetDriveMode(GpioPinDriveMode.Output);

    } // Close pin - will revert to its power-on state
}

При открытии штырек находится в состоянии включения, сюда может входить нагрузочный повышающий резистор. Чтобы отключить нагрузочные повышающие резисторы и получить вход с высоким импедансом, задайте для режима диска значение GpioPinDriveMode.Input:

    pin.SetDriveMode(GpioPinDriveMode.Input);

При закрытии штырька он возвращается к состоянию питания.

Мультиплексирование штырьков

Некоторые штырьки GPIO могут выполнять несколько функций. По умолчанию штырьки настраиваются как входы GPIO. При открытии альтернативной функции путем вызова I2cDevice.FromIdAsync() или SpiDevice.FromIdAsync() штырьки, необходимые функции, автоматически переключаются ("мультиплексируются") в правильную функцию. Когда устройство закрывается путем вызова I2cDevice.Dispose() или SpiDevice.Dispose(), штырьки возвращаются к своей функции по умолчанию. Если вы пытаетесь одновременно использовать штырек для двух разных функций, при попытке открыть конфликтующую функцию будет возникать исключение. Например,

var controller = GpioController.GetDefault();
var gpio2 = controller.OpenPin(2);      // open GPIO2, shared with I2C1 SDA

var dis = await DeviceInformation.FindAllAsync(I2cDevice.GetDeviceSelector());
var i2cDevice = await I2cDevice.FromIdAsync(dis[0].Id, new I2cConnectionSettings(0x55)); // exception thrown because GPIO2 is open

gpio2.Dispose(); // close GPIO2
var i2cDevice = await I2cDevice.FromIdAsync(dis[0].Id, new I2cConnectionSettings(0x55)); // succeeds because gpio2 is now available

var gpio2 = controller.OpenPin(2); // throws exception because GPIO2 is in use as SDA1

i2cDevice.Dispose(); // release I2C device
var gpio2 = controller.OpenPin(2); // succeeds now that GPIO2 is available

Последовательное УАПП

В RPi2/3 доступно одно последовательное УАПП: UART0

  • Штырек 8 — UART0 TX
  • Штырек 10 — UART0 TX

В следующем примере инициализируется UART0 и выполняется запись, за которой следует чтение:

using Windows.Storage.Streams;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;

public async void Serial()
{
    string aqs = SerialDevice.GetDeviceSelector("UART0");                   /* Find the selector string for the serial device   */
    var dis = await DeviceInformation.FindAllAsync(aqs);                    /* Find the serial device with our selector string  */
    SerialDevice SerialPort = await SerialDevice.FromIdAsync(dis[0].Id);    /* Create an serial device with our selected device */

    /* Configure serial settings */
    SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
    SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
    SerialPort.BaudRate = 9600;                                             /* mini UART: only standard baud rates */
    SerialPort.Parity = SerialParity.None;                                  /* mini UART: no parities */  
    SerialPort.StopBits = SerialStopBitCount.One;                           /* mini UART: 1 stop bit */
    SerialPort.DataBits = 8;

    /* Write a string out over serial */
    string txBuffer = "Hello Serial";
    DataWriter dataWriter = new DataWriter();
    dataWriter.WriteString(txBuffer);
    uint bytesWritten = await SerialPort.OutputStream.WriteAsync(dataWriter.DetachBuffer());

    /* Read data in from the serial port */
    const uint maxReadLength = 1024;
    DataReader dataReader = new DataReader(SerialPort.InputStream);
    uint bytesToRead = await dataReader.LoadAsync(maxReadLength);
    string rxBuffer = dataReader.ReadString(bytesToRead);
}

Обратите внимание, что для запуска кода последовательного УАПП необходимо добавить следующую возможность в файл Package.appxmanifest в проекте UWP:

У Visual Studio 2017 в конструкторе манифестов (визуальный редактор для файлов appxmanifest) есть известная ошибка, влияющая на возможность сериализации. Если приложение appxmanifest добавляет функцию сериализованной коммуникации, изменение appxmanifest с помощью конструктора повредит appxmanifest (дочерний xml-файл устройства будет потерян). Эту проблему можно обойти, вручную изменив appxmanifest: для этого щелкните правой кнопкой мыши appxmanifest и выберите в контекстном меню команду "Просмотр кода".

  <Capabilities>
    <DeviceCapability Name="serialcommunication">
      <Device Id="any">
        <Function Type="name:serialPort" />
      </Device>
    </DeviceCapability>
  </Capabilities>

Шина I2C

Давайте рассмотрим шину I2C, доступную на этом устройстве.

Обзор I2C

Существует один контроллер I2C I2C1, представленный в штырьковом разъеме двумя рядами: SDA и SCL. Нагрузочные повышающие резисторы на 1,8 KОм для этой шины уже установлены на плате.

Название сигнала Номер штырькового разъема Номер GPIO
SDA 3 2
SCL 5 3

В приведенном ниже примере инициализируется I2C1 и записывает данные на устройство I2C с адресом 0x40:

using Windows.Devices.Enumeration;
using Windows.Devices.I2c;

public async void I2C()
{
    // 0x40 is the I2C device address
    var settings = new I2cConnectionSettings(0x40);
    // FastMode = 400KHz
    settings.BusSpeed = I2cBusSpeed.FastMode;

    // Create an I2cDevice with the specified I2C settings
    var controller = await I2cController.GetDefaultAsync();

    using (I2cDevice device = controller.GetDevice(settings))
    {
        byte[] writeBuf = { 0x01, 0x02, 0x03, 0x04 };
        device.Write(writeBuf);
    }
}

Шина SPI

На RPi2/3 два контроллера шины SPI.

SPI0

Название сигнала Номер штырькового разъема Номер GPIO
MOSI 19 10
MISO 21 9
SCLK 23 11
CS0 24 8
CS1 26 7

SPI1

Название сигнала Номер штырькового разъема Номер GPIO
MOSI 38 20
MISO 35 19
SCLK 40 21
CS0 36 16

Пример SPI

Ниже приведен пример выполнения записи SPI на шине SPI0 с использованием сигнала выбора микросхемы 0:

using Windows.Devices.Enumeration;
using Windows.Devices.Spi;

public async void SPI()
{
    // Use chip select line CS0
    var settings = new SpiConnectionSettings(0);
    // Set clock to 10MHz
    settings.ClockFrequency = 10000000;

    // Get a selector string that will return our wanted SPI controller
    string aqs = SpiDevice.GetDeviceSelector("SPI0");

    // Find the SPI bus controller devices with our selector string
    var dis = await DeviceInformation.FindAllAsync(aqs);

    // Create an SpiDevice with our selected bus controller and Spi settings
    using (SpiDevice device = await SpiDevice.FromIdAsync(dis[0].Id, settings))
    {
        byte[] writeBuf = { 0x01, 0x02, 0x03, 0x04 };
        device.Write(writeBuf);
    }
}