I2C slave na Atmega?

Apr 02, 2007 6 Replies

Witam, ³aczê sobie 2 procesorki (atmega 16 jako master i atmega8 slave) na I2C. master ma dobrze zdefiniowane funkcje (dogaduje siê z DS1307) . próbujê uruchomiæ tego slave, wpisa³em taki fragment kodu TWAR = 0b00011000; (0x18) TWBR = 0b00000000; TWCR = 0b01000101;



i gdy w masterze wykonam tak± kombinacjê:



twi_start(); twi_wr(0x18); twi_stop(); to uk³ad odpowiada ack, ale w tym momencie transmisja siê psuje, i master przestaje sie dogadywaæ z ds1307. rozumiem ¿e slave trzyma³ bedize to ack w nieskonczonosæ.. czyli muszê w tym momencie ustawic odpowiedni rejestr (TWEA w TWCR?) i wtedy master bedzie mog³ wysy³aæ nastepne dane? tylko jak to zrobiæ - przerwaniem? w³asnie ,jak w winavr nazywa siê to przerwanie? (wiem tylko ze int0 to jest SIGNAL(SIG_INTERRUPT0) { kod... } ) a jak± sk³adnie na TWI ? i co, wtedy mam wziasc przychodz±ce dane z TWDR, po czym ustawiæ TWEA? dobrze to rozumiem?



dobra, problem sie znmieni³ ;) znalaz³em w sieci taki kod:

SIGNAL (SIG_2WIRE_SERIAL) { Status_I2C = TWSR&0xFC; switch(Status_I2C) { //TRANSMITTER case 0xA8: //odebrano bit startu i bajt adresu do odczytu n=0; TWDR=Buf[n]; break; case 0xB0: //odebrano bit startu i bajt adresu do odczytu n=0; TWDR=Buf[n]; break; case 0xB8: //odebrano wyslanie znaku z ACK n++; TWDR=Buf[n]; break; case 0xC0: //odebrano wyslanie znaku bez ACK break; case 0xC8: //odebrano wyslanie znaku bez ACK break; // RECEIVER: case 0x60: //odebrano bit startu i bajt adresu do zapisu m=0; break; case 0x80: // odebrano bajt Buf2[m]=TWDR; m++; break; case 0xA0: // odebrano bit STOP lub kolejny START TWCR = TWCR & ~0x44; TWDR=0; TWCR = TWCR | 0x44; m=0; break; default: break; } TWCR = TWCR | 0x80; }

oprócz tego przy w³aczaniu procka wykonywany jest kod:

TWBR=0x00; TWAR=0x18; TWCR=0x45; TWSR=0x00;

i teraz wysy³aj±c z mastera co¶ takiego

twi_start(); twi_wr(0x18); twi_wr(0x55); twi_wr(0x33); twi_stop();

spodziewa³em siê wyniku Buf2[0]=0x55; Buf2[1]=0x33;

a tu lipa, oba maja warto¶æ 0x00, jakkolwiek wydaje siê ze transmisja przebieg³a poprawnie, master dostaje w odpowiedzi 3xACK, i dzia³a sobie dalej... gdzie tu co¶ przeoczy³em?

dobra, problem siê skurczy³ i to znacznie - gdzie robiê b³±d? spraw wygl±da tak - dane s± odbierane poprawnie, jeszcze w obrêbie funkcji przerwania warto¶æ jest zachowana, natomiast w funkcji g³ównej wartosc zmiennej Buff1[n] jest równa 0. dlaczego? zmienna jest zdeklarowana na pocz±tku, poza jakakolwiek funkcj±... niby powinno dzia³aæ...

nuclear napisał(a):

Jak zadeklarowales Buff1[n] ?

pozdrawiam Pawel K

nuclear napisał(a):

Zdefiniuj ja jako volatile static char buff1[]

dziêki ;) pomog³o

teraz jeszcze rozgryze czemu sie wiesza w trybie slave transmiter i bedzie ok;D

Jest taka sprawa, ze obs³ugê slave-receiver juz mam w pe³ni sprawn± natomiast problem jest w slave-transmiter

czy dobrze rozumiem, patrz±c na ponizszy kod, ze zeby przes³aæ dane ze salve do master (slave ma adres 0x1A) wystarczy wys³aæ co¶ takiego z mastera:

twi_start(); twi_wr(0x1B); datatrans[0]=twi_rd(1); datatrans[1]=twi_rd(1); twi_stop();

i w odpowiedzi dostanê to co akurat slave ma odpowiednio w Buf[0] i Buf[1] ? mysla³em ze tak to ma wygladaæ, ale co¶ przeoczy³em... tylko co? master siê wiesza w oczekiwaniu na dane... czyli slave nic nie wysy³a chyba.. czemu?

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required