Работа с шиной SPI

ПРЕДУПРЕЖДЕНИЕ

Для работы с функциями библиотеки подключите ее в Вашу программу с помощью инструкции #include <spi.h>

Подробнее о подключении библиотеки в пользовательскую программу →

Библиотека WiringRP позволяет обмениваться данными с периферийными устройствами по высокоскоростному синхронному интерфейсу SPI (Serial Peripheral Interface) со скоростью передачи данных до 100 МГц.

Список SPI-интерфейсов для Repka Pi 3 #

Идентификатор Интерфейс MOSI MISO CLK CS0 CS1 Вариант распиновки
SPI0_BUS SPI0 PC0 (пин19) PC1 (пин 21) PC2 (пин 23) PC3 (пин 24) PA3 (пин 26) 2 - 8
SPI1_BUS SPI1 PA15 (пин 38) PA16 (пин 35) PA14 (пин 40) PA13 (пин 36) отсутствует 2 - 6

Список SPI-интерфейсов для Repka Pi 4 #

Идентификатор Интерфейс MOSI MISO CLK CS0 CS1 Вариант распиновки
SPI0_BUS SPI0 PH5 (пин 19) PH6 (пин 21) PH4 (пин 23) PH3 (пин 24) PH2 (пин 26) 2 - 4 и 7 - 9

Список SPI-интерфейсов для Repka Pi 5 #

ВАЖНО

Если Вы используете Repka Pi 5, перед началом работы с SPI-интерфейсом SPI0 проверьте, что Вы выбрали правильный номер линии Chip Select.

Подробнее о выборе линии Chip Select для SPI0 на Repka Pi 5 →

Идентификатор Интерфейс MOSI MISO CLK CS0 CS1 Вариант распиновки
SPI0_BUS SPI0 GPIO3_D2 (пин 19) GPIO3_D1 (пин 21) GPIO3_D3 (пин 23) GPIO3_D4 (пин 24) GPIO3_D5 (пин 26) 2, 3, 4 и 7
SPI3_BUS SPI3 GPIO3_С7 (пин 38) GPIO3_C6 (пин 35) GPIO3_D0 (пин 40) GPIO3_C4 (пин 12) отсутствует 2, 3, 4 и 7

spiSetup() #

Инициализирует указанный SPI-интерфейс.

Синтаксис #

int spiSetup(const int spiBus, const int speed_hz)

Параметры #

spiBus - идентификатор SPI-интерфейса.

Доступные значения для каждой версии Repka Pi отображены в таблицах (столбец “идентификатор”).

speed_hz - скорость передачи данных, указанная в герцах.

Возвращаемое значение #

Файловый дескриптор SPI-интерфейса или отрицательное значение в случае ошибки.


spiRelease() #

Освобождает ресурсы задействованные при работе с SPI-интерфейсом.

Синтаксис #

void spiRelease(int fd)

Параметры #

fd - файловый дескриптор SPI-интерфейса.

Возвращаемое значение #

Ничего.


spiSetMode() #

Выбирает режим работы SPI-интерфейса.

Синтаксис #

int spiSetMode(int fd, const int mode)

Параметры #

fd - файловый дескриптор SPI-интерфейса.

mode - режим работы интерфейса.

Допустимые значения:

  • SPI_MODE_0: Режим 0.
  • SPI_MODE_1: Режим 1.
  • SPI_MODE_2: Режим 2.
  • SPI_MODE_3: Режим 3.

Возвращаемое значение #

0 при успешном выполнении или отрицательное значение в случае ошибки.


spiDataRW() #

Выполняет чтение и запись данных в full-duplex режиме обмена данными.

Синтаксис #

int spiDataRW(int fd, uint8_t *tx, uint8_t *rx, int len)

Параметры #

fd - файловый дескриптор порта SPI.

tx - указатель на массив передаваемых байт. Если указано NULL - передача данных не выполняется.

rx - указатель на массив принимаемых байт, Если указано NULL - получение данных не выполняется.

len - длина массивов tx и rx.

Возвращаемое значение #

Количество байтов, переданное по SPI-интерфейсу при успешном выполнении, или отрицательное значение в случае ошибки.


Пример использования: Подключение матрицы 8х8 красных светодиодов (MAX7219) #

ОСТОРОЖНО

Модуль матрицы 8х8 на базе чипа MAX7219 питается от линии 3.3V.

ПРЕДУПРЕЖДЕНИЕ

Для запуска данного примера на Repka Pi 5 убедитесь, что модуль матрицы подключен к интерфейсу SPI0 и в repka-config выбрана линия Chip Select 0.

Подробнее о выборе линии Chip Select для SPI0 на Repka Pi 5 →

Этот пример проверяет работоспособность интерфейса SPI0. Для работы примера необходимо соединить контакты SPI-интерфейса (MOSI, CLK, CS0) и контакты питания (+3.3V и GND) с соответствующими контактами матрицы 8х8. После запуска примера на светодиодной матрице появится бегущая точка.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "wiringRP.h"
#include "spi.h"

/*
 * Пример предназначен для иллюстрации возможности подключения устройств по интерфейсу SPI0 на Repka Pi 3, Repka Pi 4 или Repka Pi 5.
 * В данном примере подключается матрица 8х8 красных светодиодов (MAX7219) и отображается бегущая точка.
*/

// Глобальные переменные и константы
int spi0_fd; // Файловый дескриптор интерфейса SPI0
const int speed = 50000;
unsigned int step = 1;
uint8_t rx[2] = {0,0};
uint8_t point = 1;
uint8_t row = 1;

// Регистры MAX7219 (из datasheet)
#define REG_DECODE_MODE 0x09
#define REG_INTENSITY 0x0A
#define REG_SCAN_LIMIT 0x0B
#define REG_SHUTDOWN 0x0C
#define REG_DISPLAY_TEST 0x0F

static uint8_t tx_buf[2];

void setup() {
    // Инициализация библиотек wiringRP
    // Используется режим нумерации SUNXI
    if (setupWiringRP(WRP_MODE_SUNXI) < 0) {
        goto error;
    }

    // Инициализация пользовательских объектов
    spi0_fd = spiSetup(SPI0_BUS, speed);

    if (spi0_fd < 0) {
        goto error;
    }
    
	// Настройка режима работы MAX7219
	tx_buf[0] = REG_DECODE_MODE;
    tx_buf[1] = 0x00;
	spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
	
	tx_buf[0] = REG_SCAN_LIMIT;
    tx_buf[1] = 0x07;
    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
    
    tx_buf[0] = REG_INTENSITY;
    tx_buf[1] = 0x05;
    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
    
    tx_buf[0] = REG_SHUTDOWN;
    tx_buf[1] = 0x01;
    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
    
    tx_buf[0] = REG_DISPLAY_TEST;
    tx_buf[1] = 0x00;
    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
    
	// Очистка матрицы MAX7219
    uint8_t bufClear[16] = {1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0};
    for (int ind = 0; ind < 16; ind = ind + 2) {
		spiDataRW(spi0_fd, &bufClear[ind], &rx[0], 2);
	}

    return;
error:
    onClose(2);
}

void loop() {
    // Основной цикл программы
    // Сдвигам бит в переменной и записываем в регистр, который отвечает 
    tx_buf[0] = row;
    tx_buf[1] = point;
    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
    delay(100);

    point = point << 1;
    if (!point) {
        tx_buf[0] = row;
	    tx_buf[1] = 0;
	    spiDataRW(spi0_fd, &tx_buf[0], &rx[0], 2);
	    if (++row == 9) {
            row = 1;
        }
	    point = 1;
    }
}


ONDESTROY() {
    spiRelease(spi0_fd);

    // Завершение работы библиотек
    releaseWiringRP();
    // Выход из программы
    exit(0);
}

MAIN_WIRINGRP();

4053 просмотров0 комментариев
0

Комментарии (0)

Для участия в обсуждении Вы должны быть авторизованным пользователем
Разделы

Навигация

ВойтиРегистрация