Geht das ganze auch anders?

OP #2219106
Hallo,
ich mache gerade meine erste Erfahrungen im Programmieren von Atmel µCs. 
Zum üben hab ich jetzt ein Schieberegister aufgebaut um ein HD44780-LCD 
anzusteuern. Vom Controller brauche ich daher nur 3 Ports: DATA, CLK und 
ENABLE. Das ganze funktioniert bereits auch tadellos :-).

LCD <-> Register
----------------
D7  <-> DATA
RW  <-> QA
RS  <-> QB
D6  <-> QC
D5  <-> QD
D4  <-> QE


Mit dieser Routine schiebe ich die entsprechenden Bits ins Register:

void lcd_send(uint8_t data)
{
  uint8_t i, dout = 0x0;

  //data: D7, D6, D5, D4, --, --, RW, RS
  //dout: --, --, D7, RW, RS, D6, D5, D4

  dout |=  ((data & 0b11110000)>>4)
          |((data & 0b00000011)<<3)
          |((data & 0b10000000)>>2);

  // Bits ins Register schreiben
  for(i=0;i<=4;i++)
  {
    LCD_PORT &= ~(1<<LCD_CLK);      // CLK auf 0 setzen

    if(dout & (1<<i))
      LCD_PORT |= (1<<LCD_DATA);    // DATA auf 1 setzen
    else
      LCD_PORT &= ~(1<<LCD_DATA);    // DATA auf 0 setzen

    LCD_PORT |= (1<<LCD_CLK);      // CLK auf 1 setzen
  }

  // D7 ist gleich DATA
  if(dout & (1<<5))
    LCD_PORT |= (1<<LCD_DATA);      // DATA auf 1 setzen
  else
    LCD_PORT &= ~(1<<LCD_DATA);      // DATA auf 0 setzen

  lcd_enable();

}

Da ich keine Erfahrung hab würde mich interessieren was ich an meinen 
Code verbessern könnte? Komme ich auch eventuell ohne if-Abfrage aus?

danke!
#2219134
Hal Smith schrieb:

> Da ich keine Erfahrung hab würde mich interessieren was ich an meinen
> Code verbessern könnte? Komme ich auch eventuell ohne if-Abfrage aus?

Nein.
Denn abhängig vom auszugebenden Bit musst du den SDA Pin entweder auf 0 
oder auf 1 ziehen. Beides sind aber verschiedene Operationen.

Aber was du machen willst: Das hier

    (1<<i)

ist eine extrem teure Operation. Die willst du auf jeden Fall los 
werden.

antelle dass du dir eine Maske bastelst, die um jeweils 1 Bit 
weiterwandert, kannst du im Gegenzug auch dout in jedem 
Schleifendurchlauf um 1 Stelle nach rechts schieben und immer einfach 
nur auf das Bit 0 testen.
OP #2219247
OK ... verstehe ich es so richtig?

for(i=0;i<=4;i++)
{
  LCD_PORT &= ~(1<<LCD_CLK);      // CLK auf 0 setzen

  if(dout & 0x01)
    LCD_PORT |= (1<<LCD_DATA);    // DATA auf 1 setzen
  else
    LCD_PORT &= ~(1<<LCD_DATA);    // DATA auf 0 setzen

  dout = (dout>>1);

  LCD_PORT |= (1<<LCD_CLK);      // CLK auf 1 setzen
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.