Mikrokontroléry rady AVR – i2C zbernica

Zbernica i2c je často používaná na pripojenie rôznych elektronických súčiastok k mikrokontroléru napr. lcd displeje, eeprom pamäte alebo napr. rtc obvod od firmy Dallas DS1307 a podobne. Špecifikácia i2c.

Zbernica i2c používa na prenos dát medzi dvoma zariadeniami iba dva vodiče (z tohto iný názov – two wire interface – TWI). Jeden z nich, označovaný SCL, prenáša medzi master a slave zariadením hodinové impulzy, podľa ktorých sa celá komunikácia riadi. Druhý vodič sa využíva na prenos dát, teda dátový SDA.

Na zbernicu je možné pripojiť viacero zariadení. Väčšinou je na zbernici jedno MASTER zariadenie – ktoré riadi prenos dát (generuje hodiny, štart a stop podmienky a pod.), a jeden alebo viacero zariadení SLAVE (zariadenia adresované MASTER-om). Adresovanie je uskutočnené 7bit-ovou adresou, ktorá sa posiela po vykonaní štart podmienky.

obr1

Obr.1 i2c interconnection

Obidva vodiče zbernice sú pripojené cez pull-up (4k7) odpor na napájacie napätie – na vodičoch je log1. Prenos po tejto zbernici je 8bit-ový a po každom bajte nasleduje ACK bit (acknowledge) – potrvdenie dát.

Obidve linky sú nastavené na log1 pri nepracujúcom režime. Inicializácia komunikácie sa vykonáva tzv. štartovacou podmienkou – START CONDITION. Tá sa realizuje tak, že keď sú hodiny (SCL vodič) v stave log1 sa na dátovom vodiči (SDA) zmení úroveň z log1 na log0.

obr2

Obr.2 štart, stop, opakovaný štart na zbernici i2c

Po štart podmienke sa vysiela na zbernicu 7bitove číslo – adresa SLAVE zariadenia s ktorým chceme komunikovať – doplnené o najnižší bit, ktorý značí či chceme do zariadenia dáta zapisovať alebo z neho dáta prijímať (čítať). Pre zápis dát sa posledný bit nastaví na log0 a pre čítanie sa nastaví na log1.

obr3

Obr.3 odoslanie paketu

Za jeden časový okamih (1 hodinový impulz) sa môže vyslať iba 1 bit. Zmena vysielaného bitu (z log1 na log0 alebo naopak) sa nesmie uskutočniť vtedy ak je hodinový signál v stave log1 inak by to znamenalo nestabilitu a tá môže byť vyhodnotená ako kontrolný signál (napr. štart alebo stop podmienka).

obr4

Obr.4 zmena dát na SDA linke

Po každom prijatom byte-e MASTER zariadenie vysiela na zbernicu potvrdzovací bit – ACK bit a pri každom odoslanom byte-e do SLAVE zariadenia, toto zariadenie generuje ACK bit.

Pre ukončenie komunikácie po i2c zbernici sa vyšle STOP CONDITION – stop podmienka, ktorá sa realizuje zmenou hodnoty SDA z log0 na log1 počas hodinového signálu v stave log1.

AVR a i2c – TWI – TwoWire Interface

Na komunikáciu so zariadením po i2c zbernici môžeme využiť u MCU AVR jednotku TWI, ktorá má podľa datasheetu (ATMega32) takéto vlastnosti:

-> režim MASTER alebo SLAVE
-> môže pracovať ako vysielač alebo ako prijímač dát
-> 7bit adresovanie zariadení t.j. 128 rôznych adries
-> režim multimaster
-> prenosová frekvencia do 400 kHz
-> programovateľná adresa ak nastavíme MCU ako SLAVE
-> zobudenie zo Sleep Mode po rozpoznaní adresy

obr5

Obr.5 bloková schéma TWI

Inicializácia jednotky TWI sa vykonáva nastavením prenosovej frekvencie v registri TWBR (pričom sa môže využiť delička – register TWSR). Nastaví sa raz na začiatku programu a nemusí sa prepisovať kým nepotrebujeme nastaviť inú frekvenciu.

Vzorec pre výpočet hodnoty do registra TWBR (ak nie je nastavená delička):

TWBR = ((F_CPU/SCL_CLOCK)-16)/2

kde F_CPU je frekvencia CPU, SCL_CLOCK – požadovaná frekvencia na zbernici. A pri použití deličky:

obr10

Delička sa väčšinou nenastavuje keďže minimálna hodnota registra TWBR musí byť minimálne 10 t.j. frekvencia CPU minimálne 3,6 MHz.

Ďalej nasleduje horepopísaná komunikácia po i2c so zariadením.
Priebeh nastavovania riadiacich registrov pre komunikáciu po i2c je pekne popísaný v datasheete so zdrojovými kódmi v ASM a v jazyku C na str. 182. Preto to tu nebudem zbytočne vypisovať.

obr6

Obr.6 typické pripojenie zariadenia k MCU cez i2c – na obr. eeprom pamäť at24c

Registre TWI

AVR TWI obsahuje nasledujúce registre:

a) dátové:

TWAR – TWI (Slave) Address Register – obsahuje adresu (7bit), ktorá sa používa ako adresa zariadenia ak je náš MCU nastavený ako SLAVE;
TWBR – TWI BitRate Register – nastavuje hodnotu pre bit rate generátor, ktorý generuje frekvenciu i2c zbernice (SCL);
TWDR – TWI Data Register – v režime prijímača obsahuje posledný prijatý bajt a v režime vysielania obsahuje vysielanú hodnotu (zapisujeme ju my);

b) riadiace:

TWCR – TWI Control Register

obr7

Obr.7 Register TWCR

popis bitov:

TWINT – je nastavovaný hardware-om a je v log1 ak TWI dokončila práve vykonávanú činnosť; ak je povolené prerušenie (SEI) a je povolené aj prerušenie od TWI (bit TWIE) skáče sa na vektor prerušenia a prerušenie sa obsluhuje – viac v datasheete;
TWEA – TWI enable acknowledge bit – vyšle na zbernicu ACK bit po prijatí bajtu (alebo inej činnosti pri nastavení ako SLAVE – pozri datasheet);
TWSTA – TWI Start condition bit – po nastavení sa generuje štart podmienka (v master režime);
TWSTO – po nastavení sa generuje stop podmienka (v MASTER režime);
TWWC – TWI write collision flag
TWEN – TWI enable bit – po nastavení tohto bitu sa zapína TWI jednotka, preberá sa riadenie vodičov SDA a SCL a pod., po zápise do nuly sa vypína;
TWIE – TWI interrupt enable – po nastavení tohto bitu sa generuje prerušenie od TWI;

TWSR – TWI Status Register

obr8

Obr.8 Register TWSR

popis bitov:

TWS7:3 – predstavujú stav jednotky TWI a zbernice;
TWPS1:0 – delička F_CPU pre TWI jednotku;

obr9

Obr.9 Nastavenie deličky

Knižnica pre i2c s využitím TWI AVR

Tak ako na skoro všetko aj na i2c som si sám (s pomocou datasheetu) spravil mini-knižnicu s jednoduchými funkciami pre prácu s ňou v režime MASTER. Pred jej použitím nastavíme v hlavičkovom súbore i2c_master.h frekvenciu prenosu – konštanta SCL_CLOCK.

Obsahuje funkcie pre inicializáciu TWI: void i2c_init(void);

Štart podmienka s odoslaním adresy zariadenia a smeru prenosu dát sa vykoná funkciou:

unsigned char i2c_start(unsigned char address, unsigned char dir);

kde prvý parameter je adresa zariadenia (už posunutá o bit doľava t.j. posledný bit je voľný) a druhý parameter je riadenie smeru prenosu, kde môžeme využiť definované konštanty I2C_READ alebo I2C_WRITE.
Po bezchybnom priebehu zápis vráti táto funkcia nulu. Po neúspešnom štarte vráti 1 a ak SLAVE nepotvrdí dáta vráti 2.

Stop podmienka sa vykonáva funkciou unsigned char i2c_stop(void); po úspešnom priebehu vráti 0 po neúspešnom vráti 1.

Dáta na zbernicu vyšleme funkciou (po štart podmienke s adresou a I2C_WRITE): unsigned char i2c_write(unsigned char data); kde parametrom funkcie je vysielaný bajt. Po úspešnom vyslaní bajtu vráti funkcia 0 ak nie vráti 1.

Bajt zo zbernice prečítame funkciou unsigned char i2c_read_nAck(void); a ak očakávame ďalší bajt (hneď nasledujúci) tak použijeme funkciu unsigned char i2c_read_Ack(void); to znamená, že za prijatým bajtom MASTER generuje ACK bit a čaká na ďalší bajt.

Príklad som nespravil žiaden pretože ma nič dobré nenapadlo a aj tak plánujem písať články o súčiastkach pripojiteľných k MCU, z ktorých väčšina využíva zbernicu i2c. Najbližšie by to mal byť článok o práci s EEPROM od ATMEL -> AT24C.

Na ukážku aspoň screeny z analyzera zbernice i2c pri komunikácii s EEPROM. Pre zväčšenie klikni na obrázok.

i2c_write

Obr.10 Zápis dát na zbernicu

A0 – adresa zariadenia spolu s adresou bloku kde sa bude zapisovat + WRITE bit
00 – adresa bunky od ktorej sa budu postupne zapisovat bajty
AC, 72 – zapisovane bajty

S – start bit; A – ACK bit; N – NACK bit; P – stop bit;

i2c_read

Obr.11 Čítanie zo zbernice (pred čítaním je zápis adresy bloku pamäte z ktorej sa má čítať)

A0 – adresa zariadenia spolu s adresou bloku kde sa bude zapisovat: 00 – adresa bunky od ktorej sa budu postupne citat bajty
A1 – adresa zariadenia spolu s adresou bloku kde sa bude čítať + READ bit
AC, 72 – čítané bajty

Záver

Toto bol taký základ ako na MCU AVR s i2c zbernicou v režime MASTER. Pre režim SLAVE a ďalšie funkcie pozri datasheet.

Príklady

I2C

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *

Môžete použiť tieto HTML značky a atribúty: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>