PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C delay



Koertis
28.08.2010, 14:05
Hallo,

ich habe folgendes Problem:

Ich steuere per I2C-Bus 4xTLC59116 an. Nun habe ich festgestellt wenn der Atmega schreibt, gibt es beim Wechsel der TLCs einen delay von 200us [Siehe Oszibild].

Diese Zeit ist mir unerklärlich und ich muss sie umbeding auf mindestens ca. 50us veringern.

Ich arbeite mitn einem Atmega644, 20MHz.
Busgeschwindigkeit 850kHz.

An den Schreibbefehlen i2csendstart, i2csendbyte liegt es nicht.
Kann es sein dass meine Globale Variable LINE zu viel Zeit in Anspruch nimmt?




// Mein Schreibbefehl: Sendet jedem TLC 16byte + 2bit
// LINE ist ein Array von [4][16] <- für jeden TLC ein String
// LINE ist eine globale variable

void WRITE_LINE (void) {
uint8_t TLC;
uint8_t Counter;
uint8_t Coloumn = 3;

for(TLC = 0xC6;TLC >= 0xC0; TLC-=2) {
if (i2csendstart() != 0x08) {
i2csendstop();
_delay_us(5);
return;
}
if (i2csendbyte(TLC) != 0x18) {
i2csendstop();
_delay_us(5);
return;
}
if (i2csendbyte(0xA2) != 0x28) {
i2csendstop();
_delay_us(5);
return;
}

for(Counter = 0; Counter <16; Counter ++) {
if (i2csendbyte((LINE[Coloumn][Counter])) != 0x28) {
i2csendstop();
_delay_us(5);
return;
}
}
i2csendstop();
Coloumn--;
}
return;
}



Danke,
lg Koertis

PicNick
28.08.2010, 14:35
Tscha, in einem hast du recht:
eine zweifache indizierung in der innersten Schleife tut weh. da kommen schon ein paar Cycles zusammen.
Ich würde als erste Hilfe schon mal versuchen, vor der Schleife wenigsten LINE[column][0]
zu einem char* zu machen und dann nurmehr diesen pointer inkrementieren.

Koertis
29.08.2010, 17:21
Ich habe jetzt die globale Variable gelöscht und diese in der Write_Line funktion übergeben, jedoch besteht immer noch der selbe delay von 210us...




void WRITE_LINE (uint8_t LINE[][16]) {
uint8_t TLC = 0xC4;
uint8_t Coloumn = 3;
uint8_t Counter = 0;
for(TLC = 0xC6;TLC >= 0xC0; TLC-=2) {
//_delay_us(2);
if (i2csendstart() != 0x08) {
i2csendstop();
_delay_us(5);
return;
}
if (i2csendbyte(TLC) != 0x18) {
i2csendstop();
_delay_us(5);
return;
}
if (i2csendbyte(0xA2) != 0x28) {
i2csendstop();
_delay_us(5);
return;
}

for(Counter = 0; Counter <16; Counter ++) {
if (i2csendbyte((LINE[Coloumn][Counter])) != 0x28) {
i2csendstop();
_delay_us(5);
return;
}
}
i2csendstop();
Coloumn--;
}



return;
}


oder geht es mit pointer inkrementieren schneller??

lg Koertis

PicNick
29.08.2010, 19:16
Das da tut weh

i2csendbyte(LINE[Coloumn][Counter])) ....

Deswegen sag ich ja
pointer = &LINE[Coloumn][0]

und in der 16-erschleife dann nurmehr
pointer++

Koertis
29.08.2010, 21:13
Danke, ich werde es morgen probieren.
Gibt es sonst noch eine schnellere Möglichkeit die Farbwerte irgendwie zu übergeben?

lg Koertis

PicNick
30.08.2010, 06:49
naja, das mögliche Limit ist zu ermitteln, wenn du ausrechnest, wieviel Bits bei 850 kHz in welcher Zeit über die Leitung gehen ( 1 Byte = 8+1 Bit).
Schneller als das kann's nicht werden.

Koertis
30.08.2010, 07:16
Die Übertragung kann ich noch bis zu 1MHz erhöhen,
aber wichitiger ist, den delay von 200us zwischen den Baustein zu reduzieren... denn so habe ich einen delay con 4x200us...