www.mikrocontroller.net

Forum: GCC TWI I2C DOGXL160-7 sehr langsam


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Micha (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,
Ich habe einen AT90USB1287 mit 8Mhz.
Dazu über I2C ein DOGXL160-7.

Die I2C ist so eingestellt:
TWBR = 0
TWPS = 1

Damit errechnet sich mit

 8000000
----------- = 500000 HZ
16+2*0*4*1

Das Display verträgt bis zu 4000000.
Selbst wen ich denn Quarz gegen 16000000 austausche komme ich mit dieser 
Rechnung nur auf 1Mhz.

Wenn ich jedes Pixel beschreibe, dauert dies ungefähr 7 sek. Bei 
500000Hz.

Ist das normal? oder mache ich was falsch?

Ist der 4Wire SPI Mode schneller ?

Wenn das alles so langsam ist, hat das Display eine Möglichkeit,
komplette seiten in diesem zu speichern? Und dann nurnoch aufzurufen. So 
das man nicht jedesmal alle bits einzeln übertragen muss?

P.S.: Code wie im Forum unter TWI beschrieben.

Vielen Dank

Autor: Marc S. (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
zeig doch mal bitte die konkrete Ansteuerung des Displays ( nicht die 
TWI-Standart-Implementation sondern wie du die Daten dahin schickst)!

VG Marc

Autor: Micha (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Danke für die schnelle Antwort.

Wie im Beispielprogramm von der EA Homepage.

void LCD(uint8* DATA, uint8 i)
{
  while(i)
  {
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);                        //TWSTA = TWI START Condition Bit  
while  (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_START)
  Led0_on();                                                                //Fehlerbehandlung

TWDR = 0x78;//SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
  Led0_on();
  
TWDR = *DATA;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
  Led0_on();
  
  
TWCR = (1<<TWINT)|(1<<TWEN)|
(1<<TWSTO);

    DATA++;                         /* Increment the pointer on the array  */
    i--;                            /* Decrement the Byte counter  */
  }

return;
}

 

Allso müsste es schneller möglich sein?

Autor: Micha (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Dieser Teil Alle Pixel aus dauert 7 sek!
Erhöhe ich TWBR, dauert das ganze noch länger!
Also ist die Bitrate mit den obrigen einstellung schon auf Maximun. 
richtig?

/**************************************************************************************************
 * @fn      HalLcd_Clean
 *
 * @brief   Sets All pixels Off
 *
 * @param   None
 *
 * @return  None
 **************************************************************************************************/
void HalLcd_Clean(void)
{
  uint8 LcdData[] = {0x00};
 
  for(uint8 p=0; p<26; p++){                  /* 25  Pages */
    for(uint8 c=0; c<160; c++){               /* 160 Columns */
      HalLCD_SetPageAddress(0x00 + p);
      HalLCD_SetColumnAdress(0x00 + c);       
      HalLcd_SendData(LcdData, 1);
    }
  }
}



/**************************************************************************************************
 * @fn      HalLcd_SendData
 *
 * @brief   Sends  Data to LCD via 3 wire SPI
 *
 * @param   uint8* SData - Pointer to the Data to be written to the LCD
 *          uint i       - Number of the  Datas  to be written to the LCD
 *
 * @return  None
 **************************************************************************************************/

void HalLcd_SendData(uint8* SData, uint8 i)

{
  LCD_Data(SData,i);
  //P3OUT |=  CD;                                 /* CD High */
  //SPI_A0_Send_Data(SData , i);
}

void LCD_Data(uint8* DATA, uint8 i)
{
  while(i)
  {
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);                        //TWSTA = TWI START Condition Bit  
while  (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_START) // Passcaller 00 == 1
  Led0_on();                                                                //Fehlerbehandlung

TWDR = 0x7A;//SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
  Led0_on();
  
TWDR = *DATA;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
  Led0_on();
  
  
TWCR = (1<<TWINT)|(1<<TWEN)|
(1<<TWSTO);

    DATA++;                         /* Increment the pointer on the array  */
    i--;                            /* Decrement the Byte counter  */
  }

return;
}


Autor: Peter Dannegger (peda)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Micha schrieb:
> Wenn ich jedes Pixel beschreibe, dauert dies ungefähr 7 sek.

I2C ist bis max 400kHz spezifiziert.
Bei 400kHz komme ich auf:
160 * 104 * 9/8 / 400kHz = 0,05s pro Bild.
Die 7s gehen also woanders drauf.


Peter

P.S.:
Ich hab mir den Controller nicht angesehen, aber ich gehe mal davon aus, 
daß immer 8 Pixel je Datenbyte gesetzt werden können und die Adresse 
automatisch erhöht wird.

Autor: Marc S. (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Das Problem ist recht simpel:

Anstelle einfach bei 0 Anzufangen und das komplette Display in einem 
Rutsch zu beschreiben adressierst du jedes Byte einzeln und schreibst es 
danach hinein. Richtig schnell wirds nach dem Prinzip, wobei hier SPI 
verwendet wird (lässt sich aber auch auf I²C übertragen):
void   LCD_Sende_Kommando(uint8_t Kommando)
{
  PORT_ClearOutputBit(&PORTB, 3);  // Kommando-Modus
  SPIC.DATA = Kommando;      // Kommando senden
  while(!SPIC.STATUS){}      // Auf Sendeschluss warten
}

void   LCD_Sende_Daten(uint8_t Daten)
{
  PORT_SetOutputBit(&PORTB, 3);  // Daten-Modus
  SPIC.DATA = Daten;        //Datum senden
  while(!SPIC.STATUS){}      //Auf Sendeschluss warten
}

void  LCD_Auffrischen(void)
{
  PORT_ClearOutputBit(&PORTB, 1);    // Chipselect aktivieren
  for(uint8_t Zeile = 0; Zeile < 8; Zeile++)
  {
    LCD_Sende_Kommando(0xB0 + Zeile);    // Zeile Senden
    LCD_Sende_Kommando(0x04);
    LCD_Sende_Kommando(0x10);
    for(uint8_t Spalte = 0; Spalte < 128; Spalte++)
    {
      LCD_Sende_Daten(LCD_Ramspiegel[Zeile][Spalte]);
    }
  }
  PORT_SetOutputBit(&PORTB, 1);    // Chipselect deaktivieren
}

Dafür brauchst du aber ein Abbild des Displays im RAM !

Ansonnsten ersetz einfach den Verweis auf das Array in der inneren 
For-schleife durch ne Zahl dann siehst du schonmal das prinzip.

Autor: Micha (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Viele Dank.

Man muss nicht nach jeder übertragung ein Stopp senden. Sondern kann 
sofort weitermachen mit dem nächsten Datensatz.

Jetzt werde ich das noch mit einem Abbild erweitern. Dann kann ich die 
ganze Seite mit einmal senden!

Wie ist das jetzt mit diesem Takt?
Wie ihr oben seht beschreibe ich das Taktregister nicht!
Initalisiert wird es mit 0.

Kann man das so lassen? Oder geht da noch mehr?

Habe mich aktuell auf 0,8 sek verbessert.
Die Adresse erhöht das display automatisch.



LCD_clean(4160);

void LCD_clean(uint16 i)
{

TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);                        //TWSTA = TWI START Condition Bit  
while  (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_START) // Passcaller 00 == 1
  Led0_on();                                                                //Fehlerbehandlung

TWDR = 0x7A;//SLA_W;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
  Led0_on();
   
  while(i)
  {
  
TWDR = 0x00;
TWCR = (1<<TWINT) | (1<<TWEN);

while (!(TWCR & (1<<TWINT)));

if ((TWSR & 0xF8) != TW_MT_DATA_ACK)
  Led0_on();
    i--;                            /* Decrement the Byte counter  */
  }
  
  
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);



return;
}


Autor: G. G. (g_g)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

schau dir mal den Code (I2C) an, das Display ist in wenigen 
Millisekunden beschrieben!

http://www.basteln-mit-avr.de/atxmega32a4.html#dogxl160

Gruß G.G.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net