Professional Documents
Culture Documents
Charakterystyka oglna
Na szyn I2C skadaj si tylko dwie linie: linia danych (oznaczana jako SDA, ang. serial data)
i linia zegara taktujcego transmisj (oznaczana jako SCL, ang. serial clock). Tymi dwiema liniami
przesyane s wszystkie informacje: dane, adresy i sygnay sterujce. Obie linie szyny I2C - SDA i
SCL - s liniami dwukierunkowymi i przez rezystor podcigajcy podczone s do dodatniego
napicia zasilajcego. Gdy na szynie nie odbywa si adna transmisja to na obu liniach jest poziom
wysoki. Obwody wyjciowe podczonych ukadw musz by typu otwarty-dren lub otwarty-
kolektor, ze wzgldu na konieczno realizacji funkcji galwaniczne-AND. Dane na szynie I2C mog
by przesyane z prdkoci do 100kb/s w trybie standardowym (ang. Standard-mode) lub do 400kb/
s w trybie szybkim (ang. Fast-mode). Liczba ukadw podczonych do szyny jest zalena od
maksymalnej pojemnoci szyny wynoszcej 400pF.
Kady ukad podczony do szyny I2C rozpoznawany jest przez swj adres i moe pracowa
zarwno jako nadajnik, jak i odbiornik. Oczywicie sterownik wywietlacza LCD jest tylko
odbiornikiem, ale np. pami moe by jednym i drugim. Dodatkowo podczas transmisji podczone
ukady dziel si na master i slave. Master jest to ukad inicjujcy transmisj i generujcy sygna
zegarowy umoliwiajcy t transmisj. W tym momencie kady zaadresowany ukad jest ukadem
slave.
Transmisja na szynie I2C jest transmisj start-stopow, tzn. kady transfer rozpoczyna si od
bitu START, po ktrym przesyane s informacje (w przeciwiestwie jednak do interfejsu RS-232C
ich ilo nie jest ograniczona), i koczy si bitem STOP.
Szyna I2C jest szyn typu multi-master. To znaczy, e moe by podczonych wiele ukadw
mogcych kontrolowa transmisj. Zwykle ukadami master s mikrokontrolery. Rozpatrzmy tak
sytuacj, gdy podczone s dwa mikrokontrolery. Moe to wyglda np. tak:
Jeeli dwa lub wicej ukadw master rozpoczyna transmisj, to ukad, ktry pierwszy
wygeneruje bit o poziomie logicznym '1', gdy inne ukady generuj '0', traci arbitra. Sygna
zegarowy na linii SCL podczas procedury arbitracyjnej jest funkcj galwaniczne-AND sygnaw
zegarowych generowanych przez ukady master, chcce zainicjowa transmisj.
Generowanie sygnau zegarowego na szynie I2C jest zawsze zadaniem ukadu typu master.
Kady master generuje swj wasny sygna zegarowy podczas transmisji danych. Sygna zegarowy z
ukadu master moe by zmieniony tylko, wtedy gdy zbyt wolny ukad slave wymusi poziom niski
lub podczas procedury arbitracyjnej.
Dane na linii SDA musz by stabilne podczas wysokiego poziomu sygnau zegarowego. Stan
na linii danych moe si zmienia tylko podczas niskiego stanu sygnau zegarowego (na linii SCL).
START i STOP
Najwaniejszymi sytuacjami podczas transmisji na szynie I2C s bity START i STOP.
Gdy na linii SDA stan logiczny zmienia si z '1' na '0', podczas gdy na linii SCL jest stan '1', to
sytuacja taka nazywa si START. Natomiast gdy na linii SDA stan logiczny zmienia si z '0' na '1',
podczas wysokiego poziomu na linii SCL, to sytuacja taka nazywa si STOP.
START i STOP generowane s zawsze przez ukad master. Po wygenerowaniu START'u
szyna jest zajta, natomiast po wygenerowaniu STOP'u szyna jest wolna. Wykrywanie START'u i
STOP'u jest atwe, gdy podczone urzdzenia zawieraj odpowiedni interfejs sprztowy.
Mikrokontrolery bez tego interfejsu, w celu wykrycia transmisji, musz prbkowa lini SDA co
najmniej dwa razy w cigu cyklu zegarowego.
Transfer danych
Informacje wysyane na lini SDA musz by 8-bitowe. Liczba bajtw, ktre mog by
przesane nie jest limitowana. Kady bajt musi zosta potwierdzony bitem potwierdzenia. Podczas
transmisji danych pierwszy wysyany jest bit najstarszy. Jeeli odbiornik nie moe odebra
nastpnego kompletnego bajtu danych, ze wzgldu na konieczno wykonania jakich innych
funkcji, to moe wymusi poziom '0' na linii SCL, w tym momencie nadajnik przejdzie w stan
oczekiwania. Transmisja bdzie kontynuowana, gdy odbiornik zwolni lini SCL.
Potwierdzenie
Transmisja z potwierdzeniem jest jedyn moliw na szynie I2C. Impuls zegarowy dla bitu
potwierdzenia jest generowany, tak jak zawsze, przez ukad master. Na czas impulsu zegarowego
dla bitu potwierdzenia nadajnik zwalnia lini SDA (poziom wysoki). Odbiornik musi wymusi niski
poziom na linii SDA podczas tego impulsu zegarowego, tak aby poziom niski by stabilny podczas
wysokiego poziomu na linii SCL.
Gdy odbiornik-slave potwierdzi swoje zaadresowanie, ale potem podczas transmisji nie bdzie
mg odbiera kolejnych danych, to master znowu bdzie musia przerwa transmisj. Sytuacja tak
jest rozpoznawana, gdy slave nie wygeneruje bitu potwierdzenia po pierwszym kolejnym bajcie
(zostawi lini SDA w stanie wysokim). Master wygeneruje wtedy sygna STOP.
Gdy odbiornikiem jest ukad master, to sygnalizuje on koniec danych nadajnikowi-slave nie
generujc bitu potwierdzenia po ostatnim bajcie wysanym przez ukad slave. Nadajnik-slave musi
wtedy zwolni lini danych, aby umoliwi ukadowi master wygenerowanie sygnau STOP.
Arbitra i synchronizacja
-Synchronizacja
Kady master generuje wasny sygna zegarowy na linii SCL, gdy chce przesa dane szyn
2
I C. Dane wane s tylko podczas wysokiego poziomu na linii SCL. Synchronizacja zegarw
nastpuje przy pomocy poczenia galwaniczne-AND wszystkich ukadw do linii SCL.
Zsynchronizowany sygna zegarowy generowany jest z poziomem niskim okrelonym przez ukad,
ktry najduej utrzyma poziom '0' i z poziomem wysokim okrelonym przez ukad, ktry najkrcej
utrzyma poziom '1'.
-Arbitra
Ukad master moe zacz transmisj tylko wtedy gdy szyna jest wolna. Moe si jednak
zdarzy, e dwa lub wicej ukady master wygeneruj sygna START w tym samym czasie.
Rozpocznie si wtedy procedura arbitracyjna. Arbitra ma miejsce podczas wysokiego poziomu na
linii SCL. W takim przypadku master, ktry nadaje poziom wysoki na linii SDA, podczas gdy drugi
master nadaje poziom niski, przestanie nadawa, poniewa stan na linii SDA nie bdzie odpowiada
stanowi przez niego wygenerowanemu. Arbitra moe trwa przez wiele bitw. Jego pierwszym
etapem jest porwnywanie bitw adresowych. Jeeli ukady master staraj si zaadresowa te samo
urzdzenie, arbitra przeciga si na bity danych. Poniewa adres i dane uywane s do arbitracji,
adna informacja nie jest tracona podczas tego procesu. Master, ktry straci arbitra moe
generowa sygna zegarowy do koca bajtu, w ktrym straci arbitra.
Jeli master peni rwnie funkcj slave i straci arbitra podczas etapu adresowania to jest
moliwe, e wygrywajcy master prbuje go zaadresowa. Master, ktry przegra arbitra musi
czym prdzej przeczy si w tryb slave.
Oczywicie w arbitrau moe uczestniczy wicej ukadw master (zaley ile jest
podczonych).
Kontrola szyny I2C zaley od wysanego, przez konkurujce ukady master, adresu i danych,
tak wic zbdny jest jakikolwiek master centralny lub kolejno priorytetw.
Adresowanie 7-bitowe
Po bicie START wysyany jest 7-bitowy adres, uzupeniony smym bitem R/W okrelajcym
kierunek transmisji - '0' oznacza zapis, '1' oznacza odczyt. Transmisja danych zawsze koczy si
bitem STOP generowanym przez ukad master. Jeeli master nadal chce komunikowa si po
szynie, to moe wygenerowa powtrzony sygna START i zaadresowa nastpny ukad slave bez
generowania bitu STOP.
Uwagi.
1. Format mieszany moe by uywany np. do sterowania pamici szeregow. Pierwszy bajt
danych okrela wewntrzny adres w pamici. Po powtrzonym bicie START i adresie ukadu mog
by przesane dane.
2. To czy adres wewntrz pamici bdzie automatycznie zwikszany, czy zmniejszany zaley od
projektanta danego ukadu.
i2cmaster.h
#ifndef _I2CMASTER_H_
#define _I2CMASTER_H_
#endif
#include <avr/io.h>
#define DS1337ADDR 0xD0 //adres urzadzenia dla A0=gnd, dla vcc bedzie 0xA2;
#define I2C_READ 1
#define I2C_WRITE 0
void i2c_start_wait(unsigned char address); // j/w, ale czeka az urzadzenie bedzie gotowe
#include <compat/twi.h>
#include "i2cmaster.h"
#include <util/delay.h>
#include "master.c"
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#define SCL_CLOCK 20000L // szybkosc i2c
#define sbi(PORT,PIN) ((PORT)|=1<<(PIN))
#define cbi(PORT,PIN) ((PORT)&=~(1<<(PIN)))
// wysyla adres
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
return 0;
}
while (1)
{
// wysyla warunek startu
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wysylanie adresu
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// sprawdzenie statusu
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
{
//urzadzenie na i2c zajete, wysyla STOP aby zakonczyc transmisje
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}
}
void i2c_stop(void)
{ // warunek stopu
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// oczekiwanie na zakonczenie
while(TWCR & (1<<TWSTO));
}
// sprawdzenie statusu
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}
return TWDR;
}
master.c
#include <compat/twi.h>
#include "i2cmaster.h"
#include <util/delay.h>
#include "i2cmaster.c"
uint8_t value;
int main(void)
{
sbi(DDRB,PB1); //informacja o poprawnie odebranych danych
cbi(PORTB,PB1); //ustawienie w stan niski
sbi(PORTC,PC4); //Podcignicie linii SDA do 5V
sbi(PORTC,PC5); //Podcignicie linii SCL do 5V
while(1)
{
i2c_start(DS1337ADDR+I2C_WRITE); //wysanie sygnau start
//zawierajcego adres urzdzenia oraz
//inf. czy dane bd wysyane czy odbierane
i2c_write(0xf3+I2C_WRITE); //wysanie danych
i2c_stop(); //zakoczenie transmisji
i2c_start(DS1337ADDR+I2C_READ);
value = i2c_readNak(); //odbir danych
i2c_stop();
asm volatile (
"WDR"::); //reset watchdoga
if(value == 0b10101010)
sbi(PORTB,PB1); //podcignicie portu na stan wysoki
}
}
i2cslave.c
//Program wykorzystanie magistrali i2c w trybie podrzdnym
#include <avr/io.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
SIGNAL (SIG_2WIRE_SERIAL)
{
switch(TWSR)
{
case 0x00: //bd (nieoczekiwany sygna START lub STOP)
sbi(TWCR,TWSTO);
sbi(TWCR,TWINT);
break;
case 0x68: //Utracono kontrol nad magistral, odebrano wasny SLA+W zwrcono ACK
break;
// sprawdzenie statusu
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK)
break;
case 0xB8: //Nadano sowo danych, odebrano ACk konieczne dalsze przesyanie
TWDR=0b10101010;
// sprawdzenie statusu
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK)
break;
case 0xC0: //Nadano sowo danych, odebrano NACK konieczne przerwanie transmisji
TWDR=0b10101010;
// sprawdzenie statusu
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK)
break;
}
sbi(TWCR,TWEA); //wczenie generacji potwierdze ACK
sbi(TWCR,TWINT); //znacznik przerwania dla moduu TWI
sbi(TWCR,TWEN); //wczenie moduu TWI
sbi(TWCR,TWIE); //uaktywnienie przerwa dla moduu TWI
asm volatile ( //reset watchdoga
"WDR"::);
}
int main()
{
// twi
DDRB=0xff; //port z diodami na wyjcie
PORTB=0x00; //ustawienie portu na stan niski
cbi(PRR0,PRTWI); //The Power Reduction TWI bit, PRTWI bit in
// Power Reduction Register 0 - PRR0 on
//page 54 must be written to zero to enable
// the 2-wire Serial Interface. In ATmega2561
sbi(TWCR,TWEA); //wczenie generacji potwierdze ACK
sbi(TWCR,TWINT); //znacznik przerwania dla moduu TWI
sbi(TWCR,TWEN); //wczenie moduu TWI
sbi(TWCR,TWIE); //uaktywnienie przerwa dla moduu TWI
while(1){}
}