Skocz do zawartości

[C] Komunikacja I2C (TWI) ATmega16 -> ATmega8


grip_rz

Pomocna odpowiedź

Witam,

Mam "mały" problem ze skomunikowaniem ze sobą dwóch atmeg za pomocą sprzętowego TWI. Atmega16 pracuje jako Master, a Atmega8 jako Slave. Komunikacja jest częścią sporego już programu.

Usiłuję korzystać z przykładowego kodu do obsługi sprzętowego TWI, który udało mi się znaleźć na anglojęzycznej stronie.

Z tego co zaobserwowałem, wysyłanie powinno działać, program nie wiesza się w miejscu wywoływania funkcji wysyłającej dane na slave'a (tak jak to miało miejsce kiedyś). Niestety slave nie reaguje w żaden sposób. Dla testów uprościłem kod - po otrzymaniu bajtu danych slave powinien wystawić stan niski na 2 piny, co powinno zaowocować zaświeceniem się diody. Tak się jednak nie dzieje. Bardzo proszę o jakieś rady, wskazówki, bo męcze się już z tym tydzień i nie mogę tego uruchomić...

Zależy mi, aby dane przechwytywało kilka slave'ów czyli trzeba zastosować wywołanie ogólne, tutaj jednak, dla uproszczenia testuję na jednym konkretnym adresie.

Poniżej prezentuję wybrane fragmenty kodu potrzebne do oceny sytuacji:

Kod dla mastera:

unsigned char address=0x20, read=1, write=1;
unsigned char write_data=0x01, recv_data;

void TWI_init_master(void) 							
{
TWBR=0x01; 										
TWSR=(0<<TWPS1)|(0<<TWPS0); 				
}

void TWI(void)
{
TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while(!(TWCR & (1<<TWSTO)));  				
}

void main(void)  
{
       TWI_init_master();
       while(1)
       {
       switch (stan)
	{

                case 4:
			for(i=0;i<40;i++)
			{
				adc();
				if(write_data==0x00)
				{
				TWI();
				}
			}
                               stan=5;break;
                 }
      }
}

I kod dla slave'a

unsigned char write_data, recv_data;
char bufor[6];

void function_01(void)
{
bufor[0]=recv_data;
if(bufor[0]=='a')
{
	PORTB &= ~_BV(PB2);
	PORTD &= ~_BV(PD3);
	_delay_ms(1000);
}
}

void TWI_init_slave(void)
{
TWAR=0x20; 
}

void TWI_read_slave(void)
{
TWCR= (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))); 
///////while((TWSR & 0xF8)!=0x80);
recv_data=TWDR;
}

void TWI_match_read_slave(void) 
{
while((TWSR & 0xF8)!= 0x60)  
{
	TWCR=(1<<TWEA)|(1<<TWEN)|(1<<TWINT);
	///////while (!(TWCR & (1<<TWINT)));  
}
}

void main(void)
{
DDRD = 0xFC;	               					
DDRB = 0x0F;									
PORTB = 0x00;
PORTD = 0x00;
TWI_init_slave();

while(1)
{
	TWI_match_read_slave();
	TWI_read_slave();
	function_01();
       }
}

Bardzo proszę o pomoc.

Pozdrawiam

Link do komentarza
Share on other sites

Nie podoba mi się to, co wysyłasz z Master'a w bajcie adresu. W argumencie funkcji TWI_write_address() sumujesz adres Slave'a (OK) i zmienną write (=1) a to oznacza, że bit R/W będzie jedynką 😐

Dodatkowo przy takim podawaniu argumentu (adresu) warto przesuwać go 1 bit w lewo właśnie po to, by jego LSB nie właził na bit R/W albo trzeba pamiętać, by adres zawsze był parzysty - to kwestia przyjętych założeń co do przechowywania w systemie i interpretacji adresów na szynie.

Po co ten _delay_ms(10) ?

EDIT: A może, jeśli już zrobiłeś dwie bliźniacze funkcje wysyłania bajtu adresu i danych, to zmodyfikuj tę pierwszą tak, by to ona właśnie odpowiednio przesuwała otrzymany adres zapewniając jednocześnie wartość bitu R/W=0. Może nie ma sensu przekazywanie do funkcji wysyłania adresu czegoś co nazywa się "write" skoro ona i tak ma właśnie to zrobić - wysłać.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.