Forum: Mikrocontroller und Digitale Elektronik Frage AVR-GCC-Tutorial => lcd-routines.c


von Lutz (Gast)


Lesenswert?

Hallo,
ich (Anfänger) gehe gerade das o.g. Tutorial durch und habe eine 
Verständnisfrage. Funktionieren wird der Code wohl, sonst stünde er hier 
ja nicht, also verzweifle ich gerade mit meinem C-Büchlein. Also:
1
// Pinbelegung für das LCD, an verwendete Pins anpassen
2
#define LCD_PORT      PORTD
3
#define LCD_DDR       DDRD
4
#define LCD_RS        PD4
5
#define LCD_EN        PD5
6
// DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden 
7
// sendet ein Datenbyte an das LCD
8
 
9
void lcd_data(unsigned char temp1)
10
{
11
   unsigned char temp2 = temp1;
12
 
13
   LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
14
 
15
   temp1 = temp1 >> 4;
16
   temp1 = temp1 & 0x0F;
17
   LCD_PORT &= 0xF0;
18
   LCD_PORT |= temp1;               // setzen
19
   lcd_enable();
20
 
21
   temp2 = temp2 & 0x0F;
22
   LCD_PORT &= 0xF0;
23
   LCD_PORT |= temp2;               // setzen
24
   lcd_enable();
25
   
26
   _delay_us(42);
27
}

temp1 = temp1 >> 4;
Soweit klar: Soll ein unsigned char um 4 Stellen nach rechts shiften; 
dadurch kommen von links Nullen nach und das höherwertige Nibble 
befindet sich nun im niederwertigen Nibble, da PD0 bis PD3 im 
höherwertigen Nibble DB4 bis PD7 des LCD entsprechen und zuerst 
übertragen werden.

temp1 = temp1 & 0x0F;
Verstehe ich inhaltlich schon nicht mehr, denn nach meinem bisherigen 
Verständnis kann sich der Inhalt von temp1 dadurch überhaupt nicht 
verändern (höherwertiges Nibble ist ja schon Null und niederwertiges 
Nibble wird mit 1111 verUNDet; ergibt das, was vorher schon im 
niederwertigen Nibble da war).

LCD_PORT &= 0xF0;
Hier wird DB0 bis DB3 auf Null gesetzt. Warum? Mit dem nächsten Befehl

LCD_PORT |= temp1;
wird doch sowieso das ins Register geschrieben, was in temp1 steht?

Und hier hör ich lieber auf, denn wenn ich 2 Schritte hintereinander 
schon nicht verstehe, frage ich lieber nach.

Danke und Gruß
Lutz

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Stelle 1:

> temp1 = temp1 >> 4;
> ...
> temp1 = temp1 & 0x0F;
> ...

Schritt 2 könnte man an der Stelle weglassen. Mag sein, dass das ein 
Rest von der Ururversion ist. Die Zeile "schadet" aber auch nicht.

Stelle 2:

> LCD_PORT &= 0xF0;
> Hier wird DB0 bis DB3 auf Null gesetzt. Warum? Mit dem nächsten Befehl
>
> LCD_PORT |= temp1;
> wird doch sowieso das ins Register geschrieben, was in temp1 steht?

"Durch das ODER (|) werden nur die 1-en aus temp1 nach LCD_PORT 
gschrieben".

Nimm Papier und Bleistift und rechne ab Stelle 2 mit den Anfangswerten

LCD_PORT = 0x81;
temp1 = 0x82;

durch und lasse dann die Anweisung

LCD_PORT &= 0xF0;

mal weg...

Weitere Lektüre: Bitmanipulation

von Lutz (Gast)


Lesenswert?

Autsch! Die 1 von 0x81 bleibt beim verODERn stehen und wird 
"durchgereicht". Mit LCD_PORT &= 0xF0; wird das niederwertige Nibble 
vorher "gereinigt".
=> Kapiert.

Vielen Dank.

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.