PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : TWI nur bei hohen Frequenzen



Furtion
30.08.2010, 16:05
Hi,

ich habe einen Aufbau aus 2 Chips die per TWI verbunden sind, der Slave
hat die Aufgabe wenn man ihm per Schreibbefehl einen Befehl übergibt, im
anschließenden Lesemodus, je nach Befehl zu antworten. Der Master
sendet also zunächst den Befehl schließt die Schreibeübertragung per
Stop ab und ließt in einem Lesevorgang dann die Bytes ein. Dabei sollte
es möglich sein kein Delay zwischen einem Schreib/Lesevorgang zu
benötigen. Der Slave ist in C, der Master in Basic programmiert.

Das Problem was sich nun auftut ist, dass das ganze per Software TWI gut
funktioniert, sobald ich aber den Master auf Hardware TWI einstelle brauche
ich ein Delay zwischen den Vorgängen. Das ganze funktioniert selbst bei
500Hz Takt nicht, dies drückt sich dadurch aus, dass der Slave SDA/SCL
low zieht (war. ACK). Das kurioste an der ganzen Sache ist, wenn ich nun
die Busgeschwindigkeit erhöhe (auf 400kHz) dann läuft das ganze per
HW-TWI wieder stabil (ohne Delay).

Hat vill. jemand schon einmal ein solches Problem gehabt oder vill
eine Idee was man noch ausprobieren könnte?

PicNick
30.08.2010, 16:32
d.h, je nachdem, ob der MASTER Soft-oder Hardware TWI betreibt, reagiert der SLAVE unterschiedlich ?

btw: statt STOP u. START zwischen schreiben und lesen solltest du "repeated Start" verwenden.

Furtion
30.08.2010, 17:09
Hi,



d.h, je nachdem, ob der MASTER Soft-oder Hardware TWI betreibt, reagiert der SLAVE unterschiedlich ?

Das fasst es relativ gut zusammen, ich hatte zunächst befürchtet, dass das
Programm zu langsam ist, aber da das ganze bei 400kHz funktioniert
denke ich nicht, dass es dies ist.

Das mit dem repeated Start hatte ich mal versucht, hat aber nicht geklappt,
ich denke ich probiere es noch mal aus. Aber an sich kann es doch nicht
sein, dass es bei 500Hz nicht geht, bei 400kHz aber schon :-k ?

Kampi
30.08.2010, 17:19
Und einen Softwarefehler kannst du ganz sicher ausschließen?

Furtion
30.08.2010, 18:11
Hi,

gute Frage, im Prinzip funktioniert es ja also sowohl mit dem SoftTWI als
auch mit dem HW TWI bei höheren Frequenzen. Ich wüßte auch nicht wo
ich noch ansetzen könnte außer mit dem repeared Start.

PicNick
30.08.2010, 18:22
Geh', zeig doch mal deine beiden Programme her.
Ich glaube ohne weiteres an den Weihnachtsmann und an den Osterhasen, aber das kommt mir doch etwas seltsam vor.

Furtion
30.08.2010, 19:37
Hi,

ich hab mal den Code zusammengeschrumpft und getestet die Fehler bleiben.
Nun soll der Slave einfach nur die Daten einlesen / der Master nur senden.



#define NACK 0
#define ACK 1

void twi(void)
{
cli();

//Pullups
DDRC &= ~((1<<PC1) | (1<<PC0));
PORTC |= ((1<<PC1) | (1<<PC0));

//TWI Init
TWBR = 10;
TWAR = (15<<1);
TWCR = (1<<TWEN)|(1<<TWEA);

uint8_t i = 0;

while(1)
{
// If TWINT set
if (TWCR & (1<<TWINT))
{
switch (TWSR)
{
// Slave & Read Flag
case 0x60:
i = twi_read(ACK);
dectohex(i);
i = twi_read(NACK);
dectohex(i);
//TWI Stop
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA) | (1<<TWSTO));
break;

}
}

}
}

uint8_t twi_read(uint8_t ack_flag)
{
if (ack_flag)
{
TWCR = ((1<<TWINT) | (1<<TWEN) | (1<<TWEA));
} else {
TWCR = ((1<<TWINT) | (1<<TWEN));
}
while (!(TWCR & (1<<TWINT)));
return TWDR;
}





$regfile = "m168def.dat"
$crystal = 14745000
$baud = 19200

$lib "i2c_twi.lbx" ' Für Hardware TWI

' Externe Pullups vorhanden
Config Scl = Portc.5
Config Sda = Portc.4

'Funktioniert nur mit Waitms 1
Config Twi = 50000 ' Init TWBR und TWS

'Funktioniert
'Config Twi = 400000 ' Init TWBR und TWS

Twcr = &B00000100 ' nur TWEN setzen

Dim A As Byte

Do

I2cstart 'start condition
A = &B00011110
I2cwbyte A 'slave address
A = &H30
I2cwbyte A 'slave address
A = &H30
I2cwbyte A 'slave address
I2cstop

' Waitms 1

Loop

End