From ca1230d7137745022799cc9e3a51b4d542cdab95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A8=D1=83=D0=BC?= =?UTF-8?q?=D0=B8=D0=BB=D0=BE=D0=B2?= Date: Thu, 25 May 2023 13:24:51 +0000 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D1=82=D1=8C=20'O?= =?UTF-8?q?LED-I2C/I2C.h'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OLED-I2C/I2C.h | 189 ------------------------------------------------- 1 file changed, 189 deletions(-) delete mode 100644 OLED-I2C/I2C.h diff --git a/OLED-I2C/I2C.h b/OLED-I2C/I2C.h deleted file mode 100644 index 8d66a16..0000000 --- a/OLED-I2C/I2C.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef I2C_h -#define I2C_h - -// этот символ необходим для совместимости с Wire.h. его значение является максимумом для параметра uint8_t используемого в оригинальной библиотеке. -#define BUFFER_LENGTH 255 - -class I2CLIB { -public: - void begin(void); // инициализация шины - void setClock(uint32_t clock); // ручная установка частоты шины 31-900 kHz (в герцах) - void beginTransmission(uint8_t address); // открыть соединение (для записи данных) - uint8_t endTransmission(bool stop); // закрыть соединение , произвести stop или restart (по умолчанию - stop) - uint8_t endTransmission(void); // закрыть соединение , произвести stop - size_t write(uint8_t data); // отправить в шину байт данных , отправка производится сразу , формат - byte "unsigned char" - uint8_t requestFrom(uint8_t address , uint8_t length , bool stop); //открыть соединение и запросить данные от устройства, отпустить или удержать шину - uint8_t requestFrom(uint8_t address , uint8_t length); //открыть соединение и запросить данные от устройства, отпустить шину - uint8_t read(void); // прочитать байт , БУФЕРА НЕТ!!! , читайте сразу все запрошенные байты , stop или restart после чтения последнего байта, настраивается в requestFrom - uint8_t available(void); // вернет количество оставшихся для чтения байт - // функции добавлены для совместимости с Wire API - inline void beginTransmission(int address){beginTransmission((uint8_t)address);} - uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop); - uint8_t requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop); - uint8_t requestFrom(int address, int quantity); - uint8_t requestFrom(int address, int quantity, int sendStop); - size_t write(const uint8_t *buffer, size_t size); - inline size_t write(unsigned long n) { return write((uint8_t)n); } - inline size_t write(long n) { return write((uint8_t)n); } - inline size_t write(unsigned int n) { return write((uint8_t)n); } - inline size_t write(int n) { return write((uint8_t)n); } - -private: - uint8_t _requested_bytes = 0; // переменная хранит количество запрошенных и непрочитанных байт - bool _address_nack = false; // Флаг для отслеживания ошибки при передаче адреса - bool _data_nack = false; // Флаг для отслеживания ошибки при передаче данных - bool _stop_after_request = true; // stop или restart после чтения последнего байта - void start(void); // сервисная функция с нее начинается любая работа с шиной - void stop(void); // сервисная функция ей заканчивается работа с шиной -}; -extern I2CLIB Wire; - -void setPinMode(uint8_t pin, uint8_t mode) { - if (mode == INPUT) { - DDRD &= ~(1 << pin); // устанавливаем вход - } else { - DDRD |= (1 << pin); // устанавливаем выход - } -} - -void I2CLIB::begin() -{ // Инициализация шины в роли master - setPinMode(SDA, INPUT_PULLUP); // Подтяжка шины - setPinMode(SCL, INPUT_PULLUP); // Подтяжка шины - TWBR = 72; // Стандартная скорость - 100kHz - TWSR = 0; // Делитель - /1 , статус - 0; -} - -void I2CLIB::setClock(uint32_t clock) -{ // Функция установки частоты шины 31-900 kHz (в герцах) - TWBR = (((long)F_CPU / clock) - 16) / 2; // Расчет baudrate - регистра -} - -void I2CLIB::beginTransmission(uint8_t address) -{ // Начать передачу (для записи данных) - I2CLIB::start(); // Старт - I2CLIB::write(address << 1); // Отправка slave - устройству адреса с битом "write" -} - -uint8_t I2CLIB::endTransmission(void) -{ // Завершить передачу и отпустить шину - return I2CLIB::endTransmission(true); -} - -uint8_t I2CLIB::endTransmission(bool stop) -{ // Завершить передачу (после записи данных) - if (stop) I2CLIB::stop(); // Если задано stop или аргумент пуст - отпустить шину - else I2CLIB::start(); // Иначе - restart (другой master на шине не сможет влезть между сообщениями) - if (_address_nack) { // Если нет ответа при передаче адреса - _address_nack = false; // Обнуляем оба флага - _data_nack = false; // Обнуляем оба флага - return 2; // Возвращаем '2' - } if (_data_nack) { // Если нет ответа при передаче данных - _address_nack = false; // Обнуляем оба флага - _data_nack = false; // Обнуляем оба флага - return 3; // Возвращаем '2' - } return 0; // Если все ОК - возвращаем '0' -} - -size_t I2CLIB::write(uint8_t data) -{ // Прямая отправка байта на шину - TWDR = data; // Записать данные в data - регистр - TWCR = _BV(TWEN) | _BV(TWINT); // Запустить передачу - while (!(TWCR & _BV(TWINT))); // Дождаться окончания - uint8_t _bus_status = TWSR & 0xF8; // Чтение статуса шины - if(_bus_status == 0x20) _address_nack = true; // SLA + W + NACK ? - нет ответа при передаче адреса - if(_bus_status == 0x30) _data_nack = true; // BYTE + NACK ? - нет ответа при передаче данных - return 1; // для совместимости с Wire API -} - -uint8_t I2CLIB::available() -{ // Вернуть оставшееся количество запрошенных для чтения байт - return _requested_bytes; // Это содержимое этой переменной -} - -uint8_t I2CLIB::read() -{ // Прямое чтение байта из шины после запроса - if (--_requested_bytes) { // Если байт не последний - TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWEA); // Запустить чтение шины (с подтверждением "ACK") - while (!(TWCR & _BV(TWINT))); // Дождаться окончания приема данных - return TWDR; // Вернуть принятые данные , это содержимое data - регистра - } - _requested_bytes = 0; // Если читаем последний байт - TWCR = _BV(TWEN) | _BV(TWINT); // Запустить чтение шины (БЕЗ подтверждения "NACK") - while (!(TWCR & _BV(TWINT))); // Дождаться окончания приема данных - if (_stop_after_request) I2CLIB::stop(); // Если в requestFrom не задан аргумент stop , или stop задан как true - отпустить шину - else I2CLIB::start(); // Иначе - restart (другой master на шине не сможет влезть между сообщениями) - return TWDR; // Вернуть принятый ранее байт из data - регистра -} - -uint8_t I2CLIB::requestFrom(uint8_t address , uint8_t length) -{ // Запрос n-го кол-ва байт от ведомого устройства и отпускание шины - return I2CLIB::requestFrom(address , length , true); -} - -uint8_t I2CLIB::requestFrom(uint8_t address , uint8_t length , bool stop) -{ // Запрос n-го кол-ва байт от ведомого устройства (Читайте все байты сразу!!!) - _stop_after_request = stop; // stop или restart после чтения последнего байта - _requested_bytes = length; // Записать в переменную количество запрошенных байт - I2CLIB::start(); // Начать работу на шине - I2CLIB::write((address << 1) | 0x1); // Отправить устройству адрес + бит "read" - return length; // вернуть длину сообщения для совместимости с оригинальной Wire API -} - -uint8_t I2CLIB::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop){ - return requestFrom(address , quantity , sendStop!=0); -} - -uint8_t I2CLIB::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop){ - if (isize > 0) { - // send internal address; this mode allows sending a repeated start to access - // some devices' internal registers. This function is executed by the hardware - // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers) - - beginTransmission(address); - - // the maximum size of internal address is 4 bytes - // не понятно почему ограничение размерности регистра в оригинальной Wire API в 3 байта - if (isize > 4){ - isize = 4; - } - - // write internal register address - most significant byte first - while (isize-- > 0) - write((uint8_t)(iaddress >> (isize*8))); - endTransmission(false); - } - - return requestFrom(address, quantity, sendStop); -} - -uint8_t I2CLIB::requestFrom(int address, int quantity) -{ - return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); -} - -uint8_t I2CLIB::requestFrom(int address, int quantity, int sendStop) -{ - return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); -} - -size_t I2CLIB::write(const uint8_t *buffer, size_t size){ - for (size_t i = 0 ; i < size; ++i) - write(buffer[i]); - return size; -} - -void I2CLIB::start() -{ // сервисная функция с нее начинается любая работа с шиной - TWCR = _BV(TWSTA) | _BV(TWEN) | _BV(TWINT); // start + I2CLIB enable + установка флага "выполнить задачу" - while (!(TWCR & _BV(TWINT))); // Ожидание завершения -} - -void I2CLIB::stop() -{ // сервисная функция ей заканчивается работа с шиной - TWCR = _BV(TWSTO) | _BV(TWEN) | _BV(TWINT); // stop + I2CLIB enable + установка флага "выполнить задачу" -} - -I2CLIB Wire = I2CLIB(); - -#endif \ No newline at end of file