This shows you the differences between two versions of the page.
| — | en:examples:communication:i2c [2026/02/19 11:30] (current) – created - external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | < | ||
| + | ====== Two wire interface TWI/I2C ====== | ||
| + | //Required knowledge: | ||
| + | [HW] [[et: | ||
| + | [AVR] [[et: | ||
| + | [LIB] [[et: | ||
| + | |||
| + | ===== Theory ===== | ||
| + | |||
| + | Two Wire Interface (TWI) is most often known by the abbreviation I< | ||
| + | |||
| + | I< | ||
| + | |||
| + | [{{ : | ||
| + | ~~CL~~ | ||
| + | |||
| + | Each device on the I< | ||
| + | |||
| + | In the I< | ||
| + | |||
| + | * master sends | ||
| + | * master receives | ||
| + | * slave sends | ||
| + | * slave receives | ||
| + | |||
| + | The master initially is usually in transmit mode, first sending a start bit, followed by the 7-bit slave address and a read/write bit. If the slave with that address exists, it responds with an ACK bit (pulls the line low). After that the master either continues sending or switches to receiving. | ||
| + | |||
| + | The start bit is defined as pulling SDA low while SCL is high. The stop bit is defined as releasing SDA high while SCL is high. All other level changes must occur when SCL is low. | ||
| + | |||
| + | ~~CL~~ | ||
| + | |||
| + | Writing and reading are done byte by byte, and each successful byte exchange must be followed by an ACK signal from the receiving side. When the transfer is finished, the master sends either a stop bit or a new start bit with an address. | ||
| + | |||
| + | ===== Practice ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | In Atmel controllers, | ||
| + | |||
| + | The example shows use of the real-time clock module (RTC) DS3231 with a HomeLab III generation controller. The real-time clock has its own Li battery as autonomous power, and after initial time setup there is no need to reinitialize, | ||
| + | ~~CL~~ | ||
| + | ~~CL~~ | ||
| + | ~~CL~~ | ||
| + | <code c> | ||
| + | // HomeLab RTC module DS3231 example program | ||
| + | // The module is connected to PORTE TWI bus: SDA - PE0, SCL - PE1 | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | // DS1307 TWI address | ||
| + | #define DS3231 0b1101000 | ||
| + | |||
| + | // Define TWI master | ||
| + | TWI_Master_t twiMaster; | ||
| + | |||
| + | // TWI interrupt vector, | ||
| + | // handles background writes and reads on the TWI bus | ||
| + | ISR(TWIE_TWIM_vect) | ||
| + | { | ||
| + | TWI_MasterInterruptHandler(& | ||
| + | } | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | char buff[30]; | ||
| + | uint8_t time[8]; | ||
| + | uint8_t seconds = 0, minutes, hours; | ||
| + | uint8_t date, month, year; | ||
| + | |||
| + | // LCD initialization | ||
| + | lcd_gfx_init(); | ||
| + | lcd_gfx_write_string(" | ||
| + | |||
| + | // Start TWIE bus in master mode with low priority interrupt, | ||
| + | // TWI speed 100 kHz with 32 MHz system clock | ||
| + | TWI_MasterInit(& | ||
| + | TWI_BAUD(32000000, | ||
| + | // Enable low priority interrupts | ||
| + | PMIC.CTRL |= PMIC_LOLVLEN_bm; | ||
| + | sei(); | ||
| + | |||
| + | // Set initial time | ||
| + | time[0] = 0; // Address where time is written | ||
| + | time[1] = 0; // Seconds | ||
| + | time[2] = (4<< | ||
| + | time[3] = (1<< | ||
| + | time[4] = 3; // Day of week (3) | ||
| + | time[5] = (0<< | ||
| + | time[6] = (0<< | ||
| + | time[7] = (1<< | ||
| + | |||
| + | // Start DS3231 clock (if not already running) | ||
| + | TWI_MasterWrite(& | ||
| + | |||
| + | // Infinite loop | ||
| + | while (1) | ||
| + | { | ||
| + | // Read time again from DS3231 registers | ||
| + | TWI_MasterWriteRead(& | ||
| + | |||
| + | // Wait for response | ||
| + | while (twiMaster.status != TWIM_STATUS_READY); | ||
| + | | ||
| + | // Convert register values to time and date | ||
| + | seconds = ((twiMaster.readData[0]>> | ||
| + | minutes = ((twiMaster.readData[1]>> | ||
| + | hours = ((twiMaster.readData[2]>> | ||
| + | date = ((twiMaster.readData[4]>> | ||
| + | month = ((twiMaster.readData[5]>> | ||
| + | year = ((twiMaster.readData[6]>> | ||
| + | | ||
| + | // Display time on LCD | ||
| + | sprintf(buff," | ||
| + | hours, | ||
| + | lcd_gfx_goto_char_xy(2, | ||
| + | lcd_gfx_write_string(buff); | ||
| + | _delay_ms(100); | ||
| + | } | ||
| + | } | ||
| + | </ | ||