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

Функции этого раздела предназначены для обмена данными с периферийными устройствами по высокоскоростному синхронному интерфейсу SPI (Serial Peripheral Interface).

К СВЕДЕНИЮ

Библиотека wiringRP автоматически определяет модель вашей платы для корректной работы с SPI. Скорость передачи данных может достигать 100 МГц.

Доступность SPI-шин на Repka Pi 3 (SoC Allwinner H5):

Константа Интерфейс 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 (SoC Allwinner H6):

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

Доступность SPI-шин на Repka Pi 5

Константа Интерфейс MOSI MISO CLK CS0 CS1 Доступен в вариантах распиновки
SPI0_BUS SPI0 GPIO3_D2_d 19 GPIO3_D1_d (п.21) GPIO3_D3_d (п.23) GPIO3_D4_d (п.24) GPIO3_D5_d (п.26) 2,3,4,7
SPI3_BUS SPI3 38 GPIO3_C6_u (п.35) GPIO3_D0_u (п.40) GPIO3_C4_u (п.12) - 2,3,4,7

spiSetup()

Инициализирует функцию передачи данных с использованием SPI интерфейса.

Синтаксис

int spiSetup(const int spiBus, const int speed_hz)

Параметры

  • spiBus - дескриптор порта SPI, доступные значения:
    • SPI0_BUS - порт SPI0.
    • SPI1_BUS - порт SPI1.
  • speed_hz - Максимальная скорость передачи данных в Гц.

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


spiRelease()

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

Синтаксис

void spiRelease(int fd)

Параметры

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

Возврат Ничего.


spiDataRW()

Чтение и запись данных из буферов SPI контроллера в full-duplex режиме обмена данными.

Синтаксис

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

Параметры

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

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


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

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

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#include "wiringRP.h"
#include "spi.h"

/*
Пример предназначен для иллюстрации возможности подключения устройств 
по протоколу SPI.
В данном примере подключается Матрица 8х8 красных светодиодов (MAX7219)
с примером индикации
*/

// Глобальные переменные и константы
int spi0_fd;
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
    if(setupWiringRP(WRP_MODE_SUNXI) < 0)
        exit(EXIT_FAILURE);

    // Инициализация пользовательских объектов
    spiPreSetup(2, 0, 500000);
    spi0_fd = spiSetup(SPI0_BUS, speed);
    if(spi0_fd < 0 )
        exit(EXIT_FAILURE);
	//Настройка режима работы 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);
	}
}

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();
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#include "wiringRP.h"
#include "spi.h"

/*
Пример предназначен для иллюстрации возможности подключения устройств 
по протоколу SPI.
В данном примере подключается Матрица 8х8 красных светодиодов (MAX7219)
с примером индикации
*/

// Глобальные переменные и константы
int spi0_fd;
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
    if(setupWiringRP(WRP_MODE_SUNXI) < 0)
        exit(EXIT_FAILURE);

    // Инициализация пользовательских объектов
    spiPreSetup(2, 0, 500000);
    spi0_fd = spiSetup(SPI0_BUS, speed);
    if(spi0_fd < 0 )
        exit(EXIT_FAILURE);
	//Настройка режима работы 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);
	}
}

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();
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#include "wiringRP.h"
#include "spi.h"

/*
Пример предназначен для иллюстрации возможности подключения устройств 
по протоколу SPI.
В данном примере подключается Матрица 8х8 красных светодиодов (MAX7219)
с примером индикации
*/

// Глобальные переменные и константы
int spi0_fd, spi1_fd;
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
    if(setupWiringRP(WRP_MODE_SUNXI) < 0)
        exit(EXIT_FAILURE);

    // Инициализация пользовательских объектов
    spiPreSetup(2, 0, 500000);
    spi0_fd = spiSetup(SPI0_BUS, speed);
    if(spi0_fd < 0 )
        exit(EXIT_FAILURE);
	//Настройка режима работы 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);
	}
}

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();

3267 views0 comments
0

Comments (0)

Sections

Navigation