RTV forum PL | NewsGroups PL

I2C komunikacja przez port LPT z Atmega8: Co może być nie tak?

i2c przez lpt - mały problem...

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - I2C komunikacja przez port LPT z Atmega8: Co może być nie tak?

nuclear2001
Guest

Fri Dec 28, 2007 11:42 pm   



witam, robię sobie układzik komunikujący się z kompem za pomocą i2c,
napisałem cos, co wg mnie powinno działac, i okazuje sie ze jednak nie
działa. piszę w Borland C++ Builderze, a układ docelowy to Atmega8. układ
"slave" działa poprawnie z innym układem, dane są przesyłane poprawnie i
ogolnie wszystko ok. funkcje uSDA, uSCL, cSDA. cSCL działają poprawnie
(testowane diodkami), wiec wysjcia są aktywne, problem w tym ze gdy proboje
wysłac ządane dane, to slave na nie nie reaguje, tzn nie reaguje za
polecenie:

TWI_start();
TWI_write(adres);
TWI_write(data0);
TWI_write(data1);
TWI_stop();

przy tak zdeklarowanych funkcjach: (podejrzewam błędy w sekwencjach, ale
naprawde nie potrafie ich znalezc...)


/*założenia
data0-SDA out
strobe-SCL out
select-SDA in
paperout-SCL in
*/

BYTE inportb(UINT portid)
{
unsigned char value;
__asm mov edx,portid
__asm in al,dx
__asm mov value,al
return value;
}

void outportb(UINT portid,BYTE value)
{
__asm mov edx,portid
__asm mov al,value
__asm out dx,al
}

void uSDA(char data)
{
if(data) outportb(0x378,0x01);
else outportb(0x378,0x00);
Sleep(1);
}

void uSCL(char data)
{
if(data) outportb(0x37A,0x00);
else outportb(0x37A,0x01);
Sleep(1);
}

bool cSDA()
{
bool out;
out=(inportb(portid+0x01) & 0x10);
return out;
}

bool cSCL()
{
bool out;
out=(inportb(portid+0x01) & 0x20);
return out;
}


void TWI_start() //jest ok
{
uSDA(1); //ustaw SDA
uSCL(1); //ustaw SCL
uSDA(0); //zeruj SDA
}

void TWI_stop()
{
uSDA(0); //zeruj SDA
uSCL(1); //ustaw SCL
uSDA(1); //ustaw SDA
}


char TWI_write(char data)
{
char ack=0;

for(int i=0;i<8;i++)
{
uSCL(0); //zeruj SCL
uSDA(data<<7-i&&0x80); //ustaw bit SDA
uSCL(1);//ustaw SCL
while(!cSCL());
}

uSCL(0); //zeruj SCL
uSDA(1); //ustaw bit SDA
uSCL(1); //ustaw SCL
if(cSDA()) ack=1; //jesli SDA=1, ack =1
uSCL(0); //zeruj SCL
uSDA(1); //ustaw bit SDA

return ack;
}


char TWI_read(UINT portid,char ack)
{
char data;
uSCL(1); //ustaw SCL
while(!cSCL()); //czekaj aż SCL=1
for(int i=0;i<8;i++)
{
uSCL(1); //ustaw SCL
if(cSDA()) data |= (1 << i);
uSCL(0); //zeruj SCL
}
uSDA(ack); //ustaw bit SDA
uSDA(0); //zeruj bit SDA
uSCL(1); //ustaw SCL
uSCL(0); //zeruj SCL
return data;
}

Pawel Kraszewski
Guest

Sat Dec 29, 2007 9:34 am   



nuclear2001 wrote:

Quote:
witam, robię sobie układzik komunikujący się z kompem za pomocą i2c,
napisałem cos, co wg mnie powinno działac, i okazuje sie ze jednak nie
działa. piszę w Borland C++ Builderze, a układ docelowy to Atmega8. układ
"slave" działa poprawnie z innym układem, dane są przesyłane poprawnie i
ogolnie wszystko ok. funkcje uSDA, uSCL, cSDA. cSCL działają poprawnie
(testowane diodkami), wiec wysjcia są aktywne, problem w tym ze gdy
proboje wysłac ządane dane, to slave na nie nie reaguje, tzn nie reaguje
za polecenie:

[ ciach ]

1. "__asm mov edx,portid" sugeruje, że robisz pod Windows. I zakładasz, że
możesz tak sobie pisać i czytać po portach IO? I że absolutnie nie
potrzebujesz sterownika do tego? Hint -> np. http://tinyurl.com/3d4woh

2. Czy program jest _dokładnie_ taki, jak na listingu? Jak tak, to brakuje
opóźnień - pamiętaj, że max dla zwykłego I2C to ~400kHz a przy dłuższych
kablach i obsłudze programowej bezpieczniej będzie ~100kHz. Tak ciasne
pętle na współczesnych procach pewnie generują sygnały po kilka MHz...


Widzę, że bazujesz na "przytrzymywaniu" bitu SCL przez wolniejsze
urządzenie ale ono może po prostu nie zdążyć przyblokować SCLa...

--
Pawel Kraszewski
http://www.Kraszewscy.NET

nuclear2001
Guest

Sat Dec 29, 2007 9:49 am   



1. "__asm mov edx,portid" sugeruje, że robisz pod Windows. I zakładasz, że
możesz tak sobie pisać i czytać po portach IO? I że absolutnie nie
potrzebujesz sterownika do tego? Hint -> np. http://tinyurl.com/3d4woh

fakt, zapomniałem dodas ze uzywam sterownika "userport.sys", i sterownaie
poszczegolnymi pinami portu działa (testowane ledami)

2. Czy program jest _dokładnie_ taki, jak na listingu? Jak tak, to brakuje
opóźnień - pamiętaj, że max dla zwykłego I2C to ~400kHz a przy dłuższych
kablach i obsłudze programowej bezpieczniej będzie ~100kHz. Tak ciasne
pętle na współczesnych procach pewnie generują sygnały po kilka MHz...


Widzę, że bazujesz na "przytrzymywaniu" bitu SCL przez wolniejsze
urządzenie ale ono może po prostu nie zdążyć przyblokować SCLa...

ok, wprowadze ządane opoznienia i zobacze co to da..

nuclear2001
Guest

Sat Dec 29, 2007 10:02 am   



Quote:

ok, wprowadze ządane opoznienia i zobacze co to da..

heh, na szybkiego zmieniłem funkcje tak:


void uSDA(char data)
{
Sleep(1);
if(data) outportb(0x378,0x01);
else outportb(0x378,0x00);
Sleep(1);
}
void uSCL(char data)
{
Sleep(1);
if(data) outportb(0x37A,0x00);
else outportb(0x37A,0x01);
Sleep(1);
}

i patrzac na diodki to cos na liniach sie dzieje, nawet podobne, ale slave
nadal nie odpowiada...

nuclear2001
Guest

Sat Dec 29, 2007 10:50 am   



zmieniłem jeszcze tą funkcję

har TWI_write(char data)
{
char ack=0;

for(int i=0;i<8;i++)
{
uSCL(0); //zeruj SCL
uSDA(data & (1 << (7-i))); //ustaw bit SDA

uSCL(1);//ustaw SCL
while(!cSCL());
}

uSCL(0); //zeruj SCL
uSDA(1); //ustaw bit SDA
uSCL(1); //ustaw SCL
if(cSDA()) ack=1; //jesli SDA=1, ack =1
uSCL(0); //zeruj SCL
uSDA(1); //ustaw bit SDA

return ack;
}

i ogladajac ten przebieg, wszystko sie wydaje być ok, poza tym ze slave nie
wystawia ack, oraz nie reaguje... teraz juz nie rozumiem co moze byc nie
tak...

Michał Lankosz
Guest

Sat Dec 29, 2007 12:25 pm   



Użytkownik "nuclear2001" <nuclear2001@poczta.onet.pl> napisał w wiadomości
news:fl3u3b$jqh$1@news.onet.pl...
Quote:
witam, robię sobie układzik komunikujący się z kompem za pomocą i2c,
napisałem cos, co wg mnie powinno działac, i okazuje sie ze jednak nie
działa. piszę w Borland C++ Builderze, a układ docelowy to Atmega8. układ
"slave" działa poprawnie z innym układem, dane są przesyłane poprawnie i
ogolnie wszystko ok. funkcje uSDA, uSCL, cSDA. cSCL działają poprawnie
(testowane diodkami), wiec wysjcia są aktywne, problem w tym ze gdy
proboje wysłac ządane dane, to slave na nie nie reaguje, tzn nie reaguje
za polecenie:

TWI_start();
TWI_write(adres);
TWI_write(data0);
TWI_write(data1);
TWI_stop();


Dostajesz ACK po wysłaniu adresu? Może za szybko program leci?
Poza tym u mnie zawsze sekwencja startu jest:
sda(1)
scl(1) // te dwie linijki na wszelki wypadek, czasem nie dawałem bo to
załatwia stop
sda(0)
scl(0)

a wysyłanie bitów:
sda(bit)
scl(1)
scl(0)

Michał

nuclear2001
Guest

Tue Jan 01, 2008 7:30 pm   



hm, nagle zaczeło wszystko działac, chociaz nic nie zmieniałem, chyba slave
sie wieszał... no dobra, z tym sobie poradziłem, dane są odbierane, nie było
potrzeba zadnych opóżnien nawet ;] problem w tym ze gdy chce zrobić cos w
rodzaju

TWI_start();
TWI_write(adr);
TWI_write(0x28);
TWI_write(0xFF);
TWI_stop();
TWI_start();
TWI_write(adr);
TWI_write(0x29);
TWI_write(0xFF);
TWI_stop();

to układ odbiera tylko tą drugą transmisję... w czym moze być problem?
nieodpowiednio zakończona transmisja nr1 ? ale przeciez konczy sie warunkiem
stopu...

nuclear2001
Guest

Tue Jan 01, 2008 8:05 pm   



Quote:
to układ odbiera tylko tą drugą transmisję... w czym moze być problem?
nieodpowiednio zakończona transmisja nr1 ? ale przeciez konczy sie
warunkiem stopu...

dobra, sam sobie odpowiem, wszystko juz działa zupełnie bez zarzutu, jednak
małe opoznienie musi byc Wink dziekuje wszystkim za pomoc;]

elektroda NewsGroups Forum Index - Elektronika Polska - I2C komunikacja przez port LPT z Atmega8: Co może być nie tak?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map