Быстрые функции для работы с пинами AVR (полный список смотри в gio_avr.h), ESP8266, ESP32
- Ускорение в среднем в 20-30 раз, итоговое время для всех архитектур практически одинаковое
- Классы для быстрого управления пином
- Отдельная обработка случаев константных и неконстантных пинов для AVR
- Быстрая реализация функций shiftIn/shiftOut
- Лёгкие программные
SoftWireиSoftSPI - Универсальный класс hard SPI / soft SPI для использования в библиотеках
| Версия | Частота | |
|---|---|---|
| AVR | 1.8.19 | 16 |
| ESP8266 | 3.1.2 | 80 |
| ESP32 | 2.0.11 | 240 |
| ESP32C3 | 2.0.11 | 80 |
| write NC | write | read NC | read | mode NC | mode | |
|---|---|---|---|---|---|---|
| AVR Ardu | 5.3 | 5.3 | 4.8 | 4.8 | 3.3 | 3.3 |
| AVR gio | 1.6 | 0.125 | 1.75 | 0.075 | 1.8 | 0.125 |
| ESP8266 Ardu | 1.5 | 1.5 | 0.54 | 0.54 | 1.4 | 1.4 |
| ESP8266 gio | 0.29 | 0.08 | 0.5 | 0.17 | 1.29 | 0.58 |
| ESP32 Ardu | 0.33 | 0.33 | 0.124 | 0.124 | 16 | 16 |
| ESP32 gio | 0.04 | 0.04 | 0.085 | 0.085 | 0.126 | 0.08 |
| ESP32C3 Ardu | 0.91 | 0.91 | 0.25 | 0.25 | 21 | 21 |
| ESP32C3 gio | 0.05 | 0.05 | 0.4 | 0.08 | 0.49 | 0.08 |
NC - пины не константы
Жирным выделено худшее время (Arduino не константы), жирным курсивом - лучшее (gio константы)
| shiftOut | gio::shift | |
|---|---|---|
| AVR NC | 0.06 | 0.66 |
| AVR | 0.06 | 1.3 |
| ESP8266 | 0.2 | 1.1 |
| ESP32 | 0.96 | 6 |
| ESP32C3 | 0.35 | 2.6 |
NC - пины не константы
- SoftWire AVR: 80 kHz по умолч., 38 kHz с
GIO_NO_MASK, 28 kHz сGIO_USE_ARDUINO - SoftSPI AVR: 200 kHz transfer, 1 MHz read
Совместима со всеми Arduino платформами (используются Arduino-функции)
- Для esp8266 и esp32 быстрый
pinMode()(mode()) работает только на режимыINPUT/OUTPUT! В остальных режимах вызывается штатныйpinMode()
Быстые функции для работы с пинами
int gio::read(uint8_t P);
void gio::high(uint8_t P);
void gio::low(uint8_t P);
void gio::write(uint8_t P, uint8_t V);
//
void gio::toggle(uint8_t P);
// режим пина. Для esp8266/esp32 только INPUT/OUTPUT!
void gio::mode(uint8_t P, uint8_t V);
// нужно вызывать для esp8266/esp32 при инициализации пина
// иначе mode() не будет работать!
void gio::init(uint8_t P, uint8_t V = INPUT);Быстрые функции рассчитаны на валидные номера пинов. Проверки невалидных пинов намеренно не добавлены ради скорости и веса.
Класс для быстрого управления одним пином с номером, заданным во время выполнения. На AVR хранит регистры DDR/PORT/PIN и позволяет переключать режим через mode().
gio::PinIO pin(5, OUTPUT);
pin.high();
pin.low();
pin.write(1);
pin.toggle();
int value = pin.read();Более лёгкий класс для одного пина в одном режиме. На AVR хранит только один регистр: PORT для OUTPUT или PIN для INPUT/INPUT_PULLUP.
gio::PinSingle out(5, OUTPUT);
out.high();
out.low();
out.write(1);
gio::PinSingle inp(6, INPUT_PULLUP);
int value = inp.read();
PinSingleне предназначен для переключения режима послеinit(). Для пина в режимеOUTPUTиспользуйтеwrite/high/low/toggle/read, дляINPUTиINPUT_PULLUPиспользуйтеread().
Шаблонный класс для пина, известного на этапе компиляции.
gio::PinT<5> pin(OUTPUT);
pin.high();
pin.low();
pin.write(1);
pin.toggle();
int value = pin.read();Быстрый аналог shiftIn/shiftOut (отправка данных с клоком)
// прочитать пакет. Вернёт true, если хотя бы один бит отличается
bool gio::shift::read(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
// прочитать байт
uint8_t gio::shift::read_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t delay = 0);
// прочитать пакет + cs пин. Вернёт true, если хотя бы один бит отличается
bool gio::shift::read_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
// прочитать байт + cs пин
uint8_t gio::shift::read_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t delay = 0);
// отправить пакет
void gio::shift::send(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
// отправить байт
void gio::shift::send_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t data, uint8_t delay = 0);
// отправить пакет + cs пин
void gio::shift::send_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
// отправить байт + cs пин
void gio::shift::send_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t data, uint8_t delay = 0);Параметр order может быть:
LSBFIRST/LSB_NORMAL- LSB, прямой порядок байтовMSBFIRST/MSB_NORMAL- MSB, прямой порядок байтовLSB_REVERSE- LSB, обратный порядок байтовMSB_REVERSE- MSB, обратный порядок байтов
delayв микросекундах, позволяет уменьшить скорость передачи. Например1мкс ограничит скорость до ~1 МГц, 2 мкс до ~500 кГц- Пины нужно сконфигурировать как
OUTPUTсамостоятельно до отправки (при запуске программы например)
Универсальный класс программно-аппаратного SPI с оптимизацией количества переменных для пинов
SSPI<0, freq> spi; // аппаратный без пина CS
SSPI<0, freq, cs> spi; // аппаратный с пином CS в шаблоне
SSPI<0, freq> spi(cs); // аппаратный с пином CS в классе
SSPI<1, freq, cs, dt, clk> spi; // программный с пинами в шаблоне
SSPI<1, freq> spi(cs, dt, clk); // программный с пинами в классеДля использования SSPI подключите отдельный заголовок:
#include <GyverIO_SPI.h>Минимальный программный SPI master, mode 0, MSB first. Работает через gio::PinSingle.
SoftSPI spi;
spi.begin(miso, mosi, clk);
SoftSPI_TX spi;
spi.begin(mosi, clk);
SoftSPI_RX spi;
spi.begin(miso, clk);Минимальный программный I2C master с API, близким к Wire. Работает через gio::PinIO, поддерживает clock stretching с таймаутом и попытку восстановления шины при begin().
SoftWire wire;
wire.begin(sda, scl);
wire.beginTransmission(0x40);
wire.write(0x01);
wire.write(data, len);
uint8_t status = wire.endTransmission();
uint8_t count = wire.requestFrom(0x40, len);
int value = wire.read();
wire.read(data, len);
wire.end();Коды endTransmission() совместимы по смыслу с Wire: 0 - успех, 2 - NACK адреса, 3 - NACK данных, 4 - ошибка шины/таймаут.
#define GIO_USE_ARDUINO // отключить быстрые функции (заменить на стандартные)
#define GIO_NO_MASK // отключить быстрый IO на основе маски для AVR (PinIO/PinSingle/shift)#include <GyverIO.h>
gio::write(3, 1); // включить пин 3
// отправить данные по пинам 3 и 4
uint8_t data[] = {34, 63, 231, 9};
gio::shift::send(3, 4, MSBFIRST, data, 4);#include <GyverIO_SPI.h>
SSPI<0, f, cs> spi;
spi.send(0x12);- v1.0
- v1.1 - в 3 раза ускорен AVR non-const, обновлены таблицы
- v1.2 - исправлена ошибка!
- v1.2.1 - небольшая оптимизация
- v1.2.2 - добавлена инверсия в shift
- v1.2.4 - исправлен баг в gio::shift::read для AVR NC
- v1.2.5 - добавлен возврат true в gio::shift::read при изменении буфера
- v1.3.0 - исправлена критическая ошибка AVR/mode/NC
- v1.3.1 - добавлен дополнительный delay в shift для симметричности клока
- v1.3.2 - SSPI вынесен в отдельный файл, чтобы не мешать компиляции на некоторых платформах
- v1.3.4 - поддержка ESP32C6
- Библиотеку можно найти по названию GyverIO и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- Скачать библиотеку .zip архивом для ручной установки:
- Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
- Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
- Распаковать и положить в Документы/Arduino/libraries/
- (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек здесь
- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
- Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
При нахождении багов создавайте Issue, а лучше сразу пишите на почту alex@alexgyver.ru
Библиотека открыта для доработки и ваших Pull Request'ов!
При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
- Версия библиотеки
- Какой используется МК
- Версия SDK (для ESP)
- Версия Arduino IDE
- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
- Какой код загружался, какая работа от него ожидалась и как он работает в реальности
- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код