#define I2C_FREQ 100000UL void i2c_begin(uint8_t address) { TWBR = ((F_CPU / I2C_FREQ) - 16) / 2; // Расчет предделителя для заданной частоты TWAR = (address << 1); // Установка адреса устройства } void i2c_endTransaction() { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP } void i2c_beginTransmission(uint8_t address) { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Отправка условия START while (!(TWCR & (1 << TWINT))); // Ожидание завершения START TWDR = (address << 1); // Отправка адреса устройства TWCR = (1 << TWINT) | (1 << TWEN); // Отправка адреса while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи адреса } void i2c_endTransmission() { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO); // Отправка условия STOP } void i2c_write(uint8_t data) { TWDR = data; // Запись данных TWCR = (1 << TWINT) | (1 << TWEN); // Отправка данных while (!(TWCR & (1 << TWINT))); // Ожидание завершения передачи данных } void i2c_read(uint8_t *data, uint8_t ack) { if (ack) { TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); // Отправка ACK } else { TWCR = (1 << TWINT) | (1 << TWEN); // Отправка NACK } while (!(TWCR & (1 << TWINT))); // Ожидание завершения приема данных *data = TWDR; // Чтение данных }