Frage AVR-GCC-Tutorial => lcd-routines.c

Gast #1018995
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
Persönliche Seite #1019017
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren