logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C] Transmisja TWI. Program nie obsługuje przerwania.

majster256 24 Lip 2008 23:30 3128 22
  • #1 5375704
    majster256
    Poziom 21  
    witam mam problem z TWI

    przeglądałem forum i udało mi się bez problemów nadawać dane na tej magistrali ale mam problem z ich odbiorem. Udaje mi się jedynie odebrać adres i odpowiedzieć bitem ACK. następnie master ma wysłać jeszcze jeden bajt z poleceniem ale juz nie wiem jak to zrobić :( wydaje mi się ze w przerwaniu będzie najlepiej ale meczę sie i pomimo włączonych globalnych przerwań i
    TWCR = (1<<TWINT)|(1<<TWEN);
    program nie obsługuje przerwania które wykonuję tak
    SIGNAL (SIG_2WIRE_SERIAL)
    {
    ...
    }


    dla moderatorów:
    przeglądałem uważnie forum i nie znalazłem odpowiedzi na mój problem dlatego zamieszczam ten post. nie jest on przejawem lenistwa, ze jakoby nie chciało mi się szukać.

    Poprawiłem tytuł, przyklejone wątki są trudne do znalezienia :/
    https://www.elektroda.pl/rtvforum/topic1015361.html
    [c_p]
  • #2 5375952
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Jak zwykle pod latarnią jest najciemniej... Nota aplikacyjna AVR311 - "Using the TWI module as I2C slave". Kod drivera w języku C jest w materiałach uzupełniających.

    Pozdrawiam,
    Dr.Vee
  • #3 5375963
    majster256
    Poziom 21  
    przeglądałem to, niewiele mi to pomogło, a skompilować się to nie chce:( dodałem pare bibliotek ale on tych co tam sa ioavr.h oraz inavr.h nie może naleźć :( więc dalej nic:(
  • #4 5375977
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Jak to Ci nie pomogło? Przecież w tej nocie są flowcharty dla całego programu - na tej podstawie możesz napisać swoją wersję, albo zweryfikować poprawność swojego kodu.

    Nie kompiluje Ci się dlatego, że większość not aplikacyjnych atmela zawiera kod w C pisany pod kompilator IAR. Dlatego nie możesz w avr-gcc znaleźć podanych plików nagłówkowych. Jak bardzo chcesz, to możesz je zdobyć ściągając ewaluacyjną wersję kompilatora IAR.

    Pozdrawiam,
    Dr.Vee
  • #5 5376002
    majster256
    Poziom 21  
    ja potrzebuje tylko wiedzieć jak odebrać to co wysłał master, tak żeby slave nadal bit ack bo nie wysyła go:(
  • #6 5376021
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    To wszystko jest opisane w sekcji o TWI w dokumentacji AVR. Np. dla ATmega8 na stronie 186 jest tabelka nr 68, w której jest łopatologicznie napisane, co aplikacja powinna zrobić w przerwaniu po odczytaniu statusu TWI.

    W Twoim przypadku pierwsze przerwanie powinno zostać zgłoszone przy statusie 0x60 (odebrano własny adres, wyslano ACK), wtedy ustawiasz TWINT = 1, TWEA = 1.
    Następne przerwanie powinno być ze statusem 0x80 (odebrano bajt danych, wysłano ACK), odczytujesz dane z TWDR i wpisujesz TWINT = 1, TWEA = 1 (czekasz na kolejny bajt, wyślesz ACK).
    Później albo jeszcze raz 0x80 (kolejne bajty), albo 0xA0 (STOP = koniec transmisji), wpisujesz TWINT = 1.

    Ogólnie zawsze w przerwaniu po wykonaniu operacji musisz wyzerować flagę TWINT wpisując w nią bit 1, bo inaczej TWI trzyma linię SCL w dole uniemożliwiając dalszą komunikację.

    No i jeszcze jedno - dlaczego to ja czytam to z datasheeta, a Ty nie umiesz??? Należy się duże piwo :]

    (edit) zmiana numeru strony w datasheecie

    Pozdrawiam,
    Dr.Vee
  • #7 5376027
    majster256
    Poziom 21  
    zamieszczam mój kod
    slave:
    
    
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    #include <stdlib.h> 
    #include <math.h> 
    #define F_CPU 16000000
    #include "delay.c"
    
    
    /////////////////////////////////////////////////////////////
    //recv data
    ////////////////////////////////////////////////////////////
    uint8_t value;
    
    SIGNAL (SIG_2WIRE_SERIAL)
    {
    
       value = TWDR;
    
       TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE);
    
    }
    
    ////////////////////////////////////////////////////////////
    //// main
    ////////////////////////////////////////////////////////////
    
    
    int main()
    {
    //globalne zezwolenie na przerwania		
    	SREG |= 0x80; // globalne zezwolenie na przerwania
    
    // twi
    
    	TWAR = 0x98;
    	TWCR = (1<<TWEA)|(1<<TWEN)|(1<<TWINT)|(1<<TWIE);
    	
    //******************************************************************
    //pętla główna
    //*******************************************************************
    
    	while(1)
    	{
    
    	}
    
    
    }
    
    



    master

    	
    TWSR = 0;                         /* no prescaler */
    	TWBR = ((16000000/100000)-16)/2;  /* must be > 10 for stable operation */ 
    

    
    					// wysyła start
    					TWCR =  (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    					
    					// czeka aż wyśle
    					while (!(TWCR & (1<<TWINT)));
    					
    					// wysyła adres
    					TWDR = 0X98;
    					TWCR = (1<<TWINT) | (1<<TWEN);
    					
    					// czeka aż wyśle
    					while(!(TWCR & (1<<TWINT)));
    					
    					// sprawdznie ACK
    					if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
    					{
    					UDR = 0X1F;// nie ma ACK
    					}else
    					{
    					UDR = 0x11;// wszystko OK jest ACK
    					}
    				// ACK JUZ ODEBRANO
    			
    				TWCR = ((1<<TWINT)|(1<<TWEN));
    					// wysyła polecenie
    					TWDR = 0XA1;
    					TWCR = (1<<TWINT) | (1<<TWEN);
    
    					// czeka aż wyśle
    					while(!(TWCR & (1<<TWINT)));
    
    					// sprawdznie ACK
    					if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
    					{
    					UDR = 0X2F;// nie ma ACK
    					}else
    					{
    					UDR = 0x21;// wszystko OK jest ACK
    					}
    


    nie mam wyświetlacza w układzie stąd to UDR = coś tam- wysyłam na RS'a


    i takie pytanie jaki status przerwania :?:

    PS z piwem nie ma problemu jak ruszy:)

    Dodano po 1 [minuty]:

    a noty katalogowe mamy zupełnie inne bo w mojej na stronie 106 mam opisany ALU a na tabeli 64 mam parzystość UART'a

    Dodano po 1 [minuty]:

    to chyba numer katalogu
    2503F–AVR–12/03
    podaj numer twojej, to jest na dole w rogu, odszukam te sama note

    Dodano po 5 [minuty]:

    status to wartość w (TWSR)??? no widzisz;d a ja myślałem wcześniej ze sam mam to tam wpisać :P a później zauważyłem ze jak tego nie ma to nic sie nie zmienia w działaniu
  • #8 5376034
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Sorry, pomieszałem strony. Chodziło o stronę 186, a nie 106.

    Status możesz odczytać przez makro TW_STATUS z <util/twi.h>. Tam zresztą masz zdefiniowane wszystkie możliwe statusy.

    W tej tabelce z noty katalogowej ATmega8 są podane kody heksadecymalnie i jest napisane co należy gdzie wpisać, jeśli chce się uzyskać taki a taki rezultat.

    Pozdrawiam,
    Dr.Vee
  • #9 5376041
    majster256
    Poziom 21  
    
    uint8_t value;
    
    SIGNAL (SIG_2WIRE_SERIAL)
    {
    	switch(TW_STATUS)
    	{
    	case 0x60: //odebrano włąsny adres wysłano ACK|(1<<TWEN)|(1<<TWIE)
    		TWCR = (1<<TWEA)|(1<<TWINT);
    		
    		
    		break;
    	
    	case 0x80: //odebrano bajt danych wysłano ACK|(1<<TWEN)|(1<<TWIE)|(1<<TWIE)
    		value = TWDR;		
    		TWCR = (1<<TWEA)|(1<<TWINT);
    		
    		
    		break;
    	} 
    
    }
    


    i jak bym zrobił to, to jest to samo??

    no to ładnie ale master nadal nie otrzymuje tego ACK

    Dodano po 2 [minuty]:

    a tabelkę znam:) tylko źle wykorzystywałem ten status ;/ no ale dalej coś jest nie tak;/
  • #10 5376043
    Dr.Vee
    VIP Zasłużony dla elektroda
    Hej,

    TW_STATUS jest zdefiniowane jako TWSR & TW_STATUS_MASK, więc od razu maskujesz bity preskalera TWI.

    Nie zapisuj TWCR = ..., tylko TWCR |= (...) i TWCR &= ~(...), wtedy zmienisz tylko pojedyncze bity, a tak wszystkie pozostale ustawiasz na zero (np. wyłączasz TWI itd ;) )

    Jesteś już o krok od celu :)

    Edit: Zdajesz sobie sprawę, że w transakcji TWI po ostatnim bajcie slave powinien wysłac NACK, a nie ACK? Czyli idealnie powinno być tak:

    Odbierasz TW_SL_SLA_ACK, TWEA = 0, odbierasz TW_SL_DATA_NACK, TWEA = 1, odbierasz TW_SL_STOP.

    Edit 2:

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/twi.h>
    
    volatile uint8_t g_recvd_char;
    
    ISR(SIG_2WIRE_SERIAL) {
        switch (TW_STATUS) {
            case TW_SR_SLA_ACK: // address + write received
                TWCR &= ~_BV(TWEA); // send nack = receive one byte
                break;
            case TW_SR_DATA_ACK:
            case TW_SR_DATA_NACK: // data received
                g_recvd_char = TWDR;
                break;
            case TW_SR_STOP:   // stop received
                TWCR |= _BV(TWEA); // enable address recognition again
                break;
            default:
                // error handling here.
        }
        TWCR |= _BV(TWINT);
    }
    


    Pozdrawiam,
    Dr.Vee
  • #11 5376050
    majster256
    Poziom 21  
    probowałem już i z tą sumą:) teraz mam:
    
    TWCR &= ~(1<<TWSTA);
    TWCR |= (1<<TWEA)|(1<<TWINT)|(1<<TWEN);
    


    i dalej nic;/

    czo by tu jeszcze zmienić <myśli>

    a nadajnik jest na 100% dobry??
    zresztą sprawdzałem go z nota katalogową z tabela na 177 stronie...
  • #12 5376054
    Dr.Vee
    VIP Zasłużony dla elektroda
    Hej,

    Oczywiście jeśli chcesz otrzymać ACK (bo to w sumie sprawdzasz w nadajniku), to usuń linię

               TWCR &= ~_BV(TWEA); // send nack = receive one byte
    


    Wtedy domyślnie wysłany zostanie ACK.

    Nadajnik wygląda na dobry, skoro odbierasz pierwszy ACK po adresie to powinno hulać...

    Pozdrawiam,
    Dr.Vee
  • #13 5376563
    majster256
    Poziom 21  
    witam
    czyli transmisja działa tak:
    master do slave wysyła adres
    slave do master wysyła ACK (logiczne 0)
    master do slave wysyła dane
    slave do master wysyła NACK (może być albo 0 albo 1?? dlaczego tak bo ja zawsze odbieram 1 wiec może u mnie to działa a ja sie mecze;d)

    jestem po lekturze http://serwistvvideo.republika.pl/i2c.html
  • #14 5376798
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    O protokole TWI wszystko jest napisane np. we wspomnianej wyżej nocie katalogowej ATmega8, albo w specyfikacji I²C Philipsa.

    Transakcja, którą Ty przeprowadzasz powinna wyglądać tak:

    Master wysyła STOP,
    Master wysyła adres + bit r/!w (w Twoim przypadku r)
    Slave wysyła ACK (czyli jest podpięty do linii i może się komunikować)
    Master wysyła bajt do slave
    Slave wysyła ACK, jeśli może przyjąc więcej danych
    Slave wysyła NACK, jeśli to był ostatni bajt, albo nie może przyjąć więcej danych
    Master wysyła STOP

    Oczywiście możesz to zrobić jak sobie chcesz, bo Ty kontrolujesz oba układy, więc czy wyślesz ACK czy NACK to nie ma znaczenia.

    Edit: odpowiadając na pytanie - ACK to odpowiedź, czyli odbiornik "ściąga" linię SDA do masy. NACK to brak odpowiedzi, więc odbiornik nie robi nic (stąd SDA zostaje w stanie wysokim).

    Pozdrawiam,
    Dr.Vee
  • #15 5377073
    majster256
    Poziom 21  
    jesli mam miec bit R za adresem (logiczna 1) to w odbiorniku musze odbierac ze statusem 0xa8 a nie ze statusem 0x60 jak robiłem to dotychczas, ale co ciekawe jak odbieram to z 0xa8 to tez nie wysyła ACK <wnerw>

    Dodano po 1 [godziny] 28 [minuty]:

    jak zrobić zeby slave po odebraniu 2 bajtów wysłał swoje 2 bajty? ja już nie mam sił do tego;/

    Dodano po 13 [minuty]:

    bo jak slave wysyła to zegarem steruje master, jak to zrobić??
  • #16 5377668
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    majster256 napisał:
    jesli mam miec bit R za adresem (logiczna 1) to w odbiorniku musze odbierac ze statusem 0xa8 a nie ze statusem 0x60 jak robiłem to dotychczas, ale co ciekawe jak odbieram to z 0xa8 to tez nie wysyła ACK <wnerw>


    Nota aplikacyjna ATmega8, strona 177. TWI działa w jednym z 4 trybów. Master zawsze podaje adres slave i kontroluje zegar.
    * MT - master transmitter (master podaje dane),
    * MR - master receiver (master odbiera dane),
    * ST - slave transmitter (slave wysyła dane),
    * SR - slave receiveer (slave odbiera dane).

    Jak widać, żeby układy się dogadały, to MT musi gadać z SR, a MR z ST. MT i SR występuje, gdy do adresu slave jest dodany bit W. MR i ST wtedy, gdy jest bit R.

    majster256 napisał:

    jak zrobić zeby slave po odebraniu 2 bajtów wysłał swoje 2 bajty? ja już nie mam sił do tego;/


    Jak widać z powyższego, musisz zacząć nową transakcję, w tym przypadku podając adres slave z bitem R, wtedy slave będzie wysyłał dane (kontrolował linię SDA).

    majster256 napisał:

    bo jak slave wysyła to zegarem steruje master, jak to zrobić??


    Master steruje zegarem, ale slave może "przeciągnąć" stan niski na linii SCL - w TWI atmela SCL jest w stanie niskim tak długo, jak flaga TWINT jest ustawiona - dlatego każdorazowo trzeba ją zerować po obsłużeniu przerwania.

    Teraz wszystko już jasne?

    Pozdrawiam,
    Dr.Vee
  • #17 5378082
    majster256
    Poziom 21  
    no dobra ale zacznijmy od tego ze strona 189 tabela 69 status TWSR = 0xa8 "Own SLA+R has been received; ACK has been returned" to mojemu to nic innego jak ACK został zwrócony, to dlaczego master go nie odbiera?? a jak wysyłam dane SLA+W to master widzi ze ACK został zwrócony. to tu nie działa, a ja chyba kombinuje nie w tym miejscu gdzie cza;/
  • #18 5378219
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Jeśli masz układ w trybie slave, to musisz mieć ustawiony bit TWEA. Inaczej urządzenie nie odpowie na wezwanie ze swoim adresem. Jeśli w poprzedniej transakcji wyzerowałeś TWEA (w ten sposób wysyłasz NACK), to musisz ten bit później jakoś ustawić - na przykład przy końcu transmisji (wykryciu START lub STOP), tak jak napisałem w swoim kodzie X postów powyżej:

    
            case TW_SR_STOP:   // stop received
                TWCR |= _BV(TWEA); // enable address recognition again
                break; 
    


    Pozdrawiam,
    Dr.Vee
  • #19 5390889
    majster256
    Poziom 21  
    nie działało bo w MT powinienem tak sprawdzać ACK
    	
    	// sprawdznie ACK
    		if (TWSR == 0x40)
    		{
    		//	UDR = 0x11;// wszystko OK jest ACK
    		}else
    		{
    		//	UDR = 0X1F;// nie ma ACK
    		} 
    


    teoretycznie wszystko działa:D ale jak czytam rejestr TWDR żeby odebrać wysłane do mnie dane to odbieram to co wysyłałem na początku - SLA+R

    jak sie uporam to sie pochwale jak to zrobiłem:) chyba, że ktoś wesprze moje działania :D
  • #20 5390920
    mirekk36
    Poziom 42  
    Witam,
    od dłuższego czasu też walczyłem aby zrobić ładny sprzętowy TWI-SLAVE. W C jeszcze jestem troszkę za słaby więc na początek zrobiłem to na podstawie różnych postów tu na elektrodzie w Bascomie. Działa prze-ślicznie :) jak narazie i rozwiązane mam w tej procedurze obsługi przerwania chyba wszystko z czym walczysz w tym temacie.

    nie wiem czy na to spojrzysz bo właśnie to przykład w Bascomie z małą wstawką w assemblerze ale w zasadzie to same IF'y i reakcje na odpowiednie statusy w przerwaniu TWI więc nie powinno być problemu aby to sobie przełożyć na dowolny język.

    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''''''''''                                       '''''''''''''''''''''''''
    ''''''''''''   Obsługa przerwania TWI (I2C SLAVE)  '''''''''''''''''''''''''
    ''''''''''''                                       '''''''''''''''''''''''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Twi_przerwanie:
    
       $asm
          'Twi_status = Twsr And &B11111000
          lds   r16, {Twi_status}
          andi  r16, &b11111000
          sts   {Twi_status}, r16
       $end Asm
    
    
    
       If Twi_status = &H60 Then                                'SLA+W, ACK sended
                                                                ' (nastąpiło żądanie zapisu mastera do tego slave i slave wysłał potwierdzenie)
    
          Twi_rx_cnt = 1                                        ' przy zaadresowaniu Slave zawsze ustawiamy wskaźnik bufora na 1
                                                                ' aby odebrać komendę, która zawsze jest pierwszym odebranym bajtem
    
       Elseif Twi_status = &H80 Then                            'SLA+W data received, ACK sended
                                                                 ' (odebrano bajt danych po uprzednim zaadresowaniu slave w trybie
                                                                 ' do zapisu SLA+W i slave odesłał potwierdzenie, że odebrał ten bajt poprawnie)
    
    
    
          ' TU OBSŁUGUJEMY ODEBRANE przez Slave DANE (BAJTY) - można je ładować do jakiegoś bufora
          '---------------------------------------------------------------------------
          If Twi_rx_cnt = 1 Then                                ' sprawdzamy jaka jest komenda do wykonania dla SLAVE
             Twi_cmd = Twdr
             ' reakcja na poszczególne komendy adresowane do SLAVE
             If Twi_cmd = 0 Then
             Elseif Twi_cmd = 1 Then
             Elseif Twi_cmd = 2 Then
             Elseif Twi_cmd = 3 Then
             Elseif Twi_cmd = 4 Then
             Elseif Twi_cmd = 5 Then
             Elseif Twi_cmd = 6 Then
             Elseif Twi_cmd = 7 Then
             Elseif Twi_cmd = 8 Then
             Elseif Twi_cmd = 9 Then
             Elseif Twi_cmd = 10 Then
             Elseif Twi_cmd = 11 Then
             Elseif Twi_cmd = 12 Then
             Elseif Twi_cmd = 13 Then
             Elseif Twi_cmd = 14 Then
             Elseif Twi_cmd = 15 Then
             Elseif Twi_cmd = 16 Then
             End If
          Else
             Twi_rx_buf(twi_rx_cnt) = Twdr                      ' ładujemy dane jeśli są przesyłane po komendzie
             If Twi_rx_cnt <= Twi_rx_buf_max Then Incr Twi_rx_cnt
          End If
          '---------------------------------------------------------------------------
    
       Elseif Twi_status = &HA0 Then                            'STOP or repeated START
          Set Twcr.twea
    
       Elseif Twi_status = &HA8 Then                            'SLA+R, ACK sended
    
          ' TU ładujemy pierwszy element bufora danych, które Slave ma przesłać do MASTER'a
          '---------------------------------------------------------------------------------
          'Twdr = Twi_tx_bufor(1)
          'Twi_licznik = 2
          'Twdr = Lastcmd
          '----------------------------------------------------------------------------------
    
       Elseif Twi_status = &HB8 Then                            'SLA+R, ACK received
    
          ' TU ładujemy kolejne elementy bufora danych, które Slave ma przesłać do MASTER'a
          '---------------------------------------------------------------------------------
          'Twdr = Twi_tx_bufor(twi_licznik)
          'If Twi_licznik < Twi_licznik_ograniczenie Then Incr Twi_licznik
          'Twdr = Lastadr
          '---------------------------------------------------------------------------------
    
       Elseif Twi_status = &HC0 Then                            'SLA+R,NACK received
    
       Elseif Twi_status = &H00 Then                            'bus ERROR
          Set Twcr.twsto
    
       End If
    
       Twcr.twint = 1
    
    Return
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  • #21 5390934
    majster256
    Poziom 21  
    Dzięki wielkie ale ja pewnie mam coś z rejestrami, ktorych z pod bascom sie nie używa :D

    Dodano po 24 [minuty]:

    wg. noty katalogowej sprzętowe TWI powinno wyzerować TWINT gdy coś odbierze, a nie zeruje, wiecie może dlaczego:?:

    Dodano po 29 [minuty]:

    ale dziwnie:(
    wysyłam adres, czkam na ACK, dostaje ACK
    a teraz
    
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
    		
    
    		UDR = TWCR;// wykazuje 0x44 a wiec TWINT = 0 ( a przecież wpisałem 1:(
    		UDR = TWDR;// odbiera adres slavea;/
    
    		while(!(TWSR == 0x50)); // czeka aż odbierze znak
    
    		UDR = TWCR;// wykazuje 0xC4 a wiec TWINT = 1 
    		UDR = TWDR;// i dalej adres slavea odbieram:(
    				
    		TWCR = (1<<TWINT) | (1<<TWEN);
    
    
    
  • Pomocny post
    #22 5391332
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Coś nie możesz dojść z tym TWI do ładu.

    Flagę TWINT można tylko wyzerować. A zeruje się ją przez wpisanie 1 do rejestru - tak żeby było śmieszniej ;)

    Sprzętowe TWI ustawia TWINT gdy "coś się wydarzy". Po wykonaniu procedury przerwania (albo "ręcznym odpytaniu" TWI co i jak) należy wyzerować TWINT przez wpisanie TWINT = 1. W przeciwnym przypadku linia SCL będzie utrzymywana w stanie niskim (chyba zależy od trybu master/slave itd.), co uniemożliwia dalszą komunikację.

    Pozdrawiam,
    Dr.Vee
  • #23 5391357
    majster256
    Poziom 21  
    rozwiązanie problemu okazało się wręcz śmieszne:) najpierw cza sie bawić TWDR a później rejestrami, w odwrotnej kolejności nie działało :cry:

    i problem leżał w slave a nie master, gdzie szukałem błędu

    dziękuje wszystkim za pomoc, zwłaszcza Dr.Vee
REKLAMA