Forum: Compiler & IDEs Geht das ganze auch anders?


von Hal S. (hal9000de)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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.

von Hal S. (hal9000de)


Lesenswert?

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
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.