Функции этого раздела предназначены для обмена данными с периферийными устройствами по высокоскоростному синхронному интерфейсу 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();