Forum: Mikrocontroller und Digitale Elektronik Bei lcd-lib nur PD2-PD7 verwenden


von Bastler (Gast)


Lesenswert?

Hallo,
ich würde gerne die lcd-lib hier aus dem wiki verwenden, benötige jedoch 
PD0 und PD1 noch für das Kommunizieren über den UART. Wie kann man die 
lib so umschreiben, dass nur PD2-PD7 verwendet werden?

Wenn man in lcd-routines.h schaut, kann man da nur den Port an sich 
ändern, und die Pinbelegung von LCD_RS und LCD_EN, jedoch nicht so, dass 
die beiden UART- Pins freibleiben.

Gruß, Bastler

von Michael H* (Gast)


Lesenswert?

4 bit modus und einen shift-operator beim LCD-PORT define.

von Bastler (Gast)


Lesenswert?

Danke für deine schnelle Antwort!!!
Das LCD verwende ich im 4-BIT-Modus, aber was ist ein shift operator, 
und wie verwendet man den?

Gruß, Bastler

von Michael H* (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/Bitmanipulation#Bitoperatoren
0b00010010 << 2 = 0b01001000
jeder shift nach links entspricht dabei einer verdoppelung. jeder shift 
nach rechts...usw.

den rest an denksport überlass ich dir ^^

von Bastler (Gast)


Lesenswert?

Ok, danke für die Tips, aber wie wende ich das jetzt konkret an?
In lcd-routines.h sind folgende Definitionen:
1
#define LCD_PORT      PORT
2
#define LCD_DDR       DDRD
3
#define LCD_RS        PD4
4
#define LCD_EN        PD5
Wo soll ich da jetzt shiften? Ich weiß ja noch nicht, welche Bits später 
gesetzt sind, also kann ich dich nicht wie in deinem Beispiel vorgehen, 
oder?

Gruß, Steffen

von Peter D. (peda)


Lesenswert?


von F1-Circus-Fan (Gast)


Lesenswert?

hmmm...
1
#define LCD_PORT      PORT
2
#define LCD_DDR       DDRD
3
#define LCD_RS        PD6
4
#define LCD_EN        PD7

Ohne den Code genauer zu kennen (finde den gerade nicht), nehme ich mal 
an, daß dort irgendwo sowas in der Art steht.
1
LCD_PORT|=(data>>4)&0x0F;
2
...
3
LCD_PORT|=data&0x0F;
Die Ausgabe um 2 Bytes nach links verschoben würde ich so lösen.
1
LCD_PORT|=(data>>2)&0x3C;
2
...
3
LCD_PORT|=(data<<2)&0x3C;

von F1-Circus-Fan (Gast)


Lesenswert?

sorry für's gespamme, mußte aber raus.
Besser krieg' ich es nimmer hin...
1
#define LCD_PORT      PORT
2
#define LCD_DDR       DDRD
3
#define LCD_RS        PD6
4
#define LCD_EN        PD7
5
#define D0_PORT       PD2
6
#define MASK          (0x0F<<D0_PORT)
7
8
LCD_PORT|=(data>>D0_PORT)&MASK;
9
...
10
LCD_PORT|=(data<<D0_PORT)&MASK;
Auf die Tour darf man wild auf dem Port umher"shiften".

von Bastler (Gast)


Lesenswert?

Hmmmm, so was (LCD_PORT|=(data>>D0_PORT)&MASK;) hab ich jetzt im Code 
nicht gefunden. Vieileicht findest du im Code etwas entsprechendes...
Den Code findest du überigends hier: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung

@ Peter Danneger: Dein Beispiel ist mir ehrlich gesagt zu schwierig.

Gruß, Steffen

von F1-Circus-Fan (Gast)


Lesenswert?

ich schon...
1
...
2
LCD_PORT |= temp1;               // setzen
3
...
4
LCD_PORT |= temp2;               // setzen
mfg ;)

von Bastler (Gast)


Lesenswert?

Entschuldigung, wenn ich jetzt so blöd frag, aber was muss ich da 
ändern, dass es dem entspricht, was du oben gepostet hast?

Vielen Dank schonmal für deine Hilfe!!

Gruß, Steffen

von F1-Circus-Fan (Gast)


Lesenswert?

Nachtrag:
Die Variablen "temp1" und "temp2" werden vor der Portzuweisung 
entsprechend bearbeitet, eben Schritt für Schritt statt 'nem flotten 
Einzeiler. Ist wohl dem Wiki-Charakter geschuldet.
Habe mal den Code entsprechend umgeeselt...
1
#define LCD_PORT      PORT
2
#define LCD_DDR       DDRD
3
#define LCD_RS        PD6
4
#define LCD_EN        PD7
5
#define D0_PORT       PD2
6
#define MASK          (0x0F<<D0_PORT)
7
...
8
// sendet ein Datenbyte an das LCD
9
 
10
void lcd_data(unsigned char temp1)
11
{
12
   unsigned char temp2 = temp1;
13
 
14
   LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
15
 
16
   temp1 = temp1 >> D0_PORT;
17
   temp1 = temp1 & MASK;
18
   LCD_PORT &= ~MASK;
19
   LCD_PORT |= temp1;               // setzen
20
   lcd_enable();
21
 
22
   temp2 = temp2 << D0_PORT;
23
   temp2 = temp2 & MASK;
24
   LCD_PORT &= ~MASK;
25
   LCD_PORT |= temp2;               // setzen
26
   lcd_enable();
27
   
28
   _delay_us(42);
29
}
30
 
31
// sendet einen Befehl an das LCD
32
 
33
void lcd_command(unsigned char temp1)
34
{
35
   unsigned char temp2 = temp1;
36
 
37
   LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
38
 
39
   temp1 = temp1 >> D0_PORT;              // oberes Nibble holen
40
   temp1 = temp1 & MASK;            // maskieren
41
   LCD_PORT &= ~MASK;
42
   LCD_PORT |= temp1;               // setzen
43
   lcd_enable();
44
 
45
   temp2 = temp2 << D0_PORT;
46
   temp2 = temp2 & MASK;            // unteres Nibble holen und maskieren
47
   LCD_PORT &= ~MASK;
48
   LCD_PORT |= temp2;               // setzen
49
   lcd_enable();
50
   
51
   _delay_us(42);
52
}

von F1-Circus-Fan (Gast)


Lesenswert?

Ach, Sch...ande, die ganze Init-Routine muß ja auch noch umgeeselt 
werden, mag nimmer...

von F1-Circus-Fan (Gast)


Lesenswert?

...nagut...
1
// Initialisierung: 
2
// Muss ganz am Anfang des Programms aufgerufen werden.
3
 
4
void lcd_init(void)
5
{
6
   LCD_DDR = LCD_DDR | MASK | (1<<LCD_RS) | (1<<LCD_EN);   // Port auf Ausgang schalten
7
 
8
   // muss 3mal hintereinander gesendet werden zur Initialisierung
9
 
10
   _delay_ms(15);
11
   LCD_PORT &= ~MASK;
12
   LCD_PORT |= (0x03<<D0_PORT);            
13
   LCD_PORT &= ~(1<<LCD_RS);      // RS auf 0
14
   lcd_enable();
15
 
16
   _delay_ms(5);
17
   lcd_enable();
18
 
19
   _delay_ms(1);
20
   lcd_enable();
21
   _delay_ms(1);
22
 
23
   // 4 Bit Modus aktivieren 
24
   LCD_PORT &= ~MASK;
25
   LCD_PORT |= (0x02<<D0_PORT);
26
   lcd_enable();
27
   _delay_ms(1);
28
...

Habe ich noch was übersehen?

von F1-Circus-Fan (Gast)


Lesenswert?

...nicht wirklich.
1
// sendet ein Datenbyte an das LCD
2
 
3
void lcd_data(unsigned char temp1)
4
{
5
   LCD_PORT |= (1<<LCD_RS);        // RS auf 1 setzen
6
 
7
   LCD_PORT &= ~MASK;
8
   LCD_PORT |= (temp1 >> D0_PORT) & MASK;               // setzen
9
   lcd_enable();
10
 
11
   LCD_PORT &= ~MASK;
12
   LCD_PORT |= (temp1 << D0_PORT) & MASK;               // setzen
13
   lcd_enable();
14
   
15
   _delay_us(42);
16
}
17
 
18
// sendet einen Befehl an das LCD
19
 
20
void lcd_command(unsigned char temp1)
21
{
22
   LCD_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen
23
 
24
   LCD_PORT &= ~MASK;
25
   LCD_PORT |= (temp1 >> D0_PORT) & MASK;               // setzen
26
   lcd_enable();
27
 
28
   LCD_PORT &= ~MASK;
29
   LCD_PORT |= (temp1 << D0_PORT) & MASK;               // setzen
30
   lcd_enable();
31
   
32
   _delay_us(42);
33
}

SCNR

von Michael H* (Gast)


Lesenswert?

oder vielleicht einfach eine zusätzliche variable definiern, die dann 
geshiftet wird, anstatt wild im funktionierenden code zumrukramen.

von Bastler (Gast)


Lesenswert?

Ok, vielen Dank für deine Mühe F1-Circus-Fan!!!!!
Muss ich also die von dir genannten Veränderungen nur in den Funktionen 
lcd_data, lcd_command, und lcd_init vornehmen?

Gruß, Steffen

von Peter D. (peda)


Lesenswert?

Bastler wrote:

> @ Peter Danneger: Dein Beispiel ist mir ehrlich gesagt zu schwierig.


Komisch, die meisten finden es gerade besonders einfach und 
übersichtlich, z.B. roboter (Gast), 2 Beiträge darunter.

Es ist streng modular, d.h. gleiche Sachen werden nicht mit copy&paste, 
sondern mit Unterfunktionen gemacht.

Alle Pindefinitionen sind im main.h, d.h. nie wieder am Code 
rumeditieren, wenn sich was ändert.
Ich bin ja auch so einer, der die Pins erstmal fürs beste Layout 
definiert und dann die Software daran anpaßt.


Falls Dein Problem die besonders schicken Bitvariablen sind, hier wird 
das ausführlich erklärt:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=67368

Man muß es ja mit der Schifterei nicht übertreiben, wenns anders viel 
leserlicher geht.


Peter

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ja, aber dein Code ist ja eine ganz neue UART lib, wenn ich das richtig 
verstanden habe, oder?
Ich würde eigentlich nur gerne die alte anpassen, weil ich die auch 
schon in einigen anderen Projekten verwendet habe, und eigentlich immer 
notgedrungen auf die UART-Pins verzichtet habe. Wenn ich nun also nur in 
der lib etwas ändern müsste, müsste ich in den Projekten an sich nichts 
ändern.
Wenn ich jedoch eine ganz neue lib verwende, muss ich ja alles mit dem 
LCD  überarbeiten, weil in deinem Code die Funktionen anders heißen.

Also am liebsten wäre mir einfach die lib anzuändern.

Gruß, Steffen

von Peter D. (peda)


Lesenswert?

Steffen O. wrote:
> Ja, aber dein Code ist ja eine ganz neue UART lib, wenn ich das richtig
> verstanden habe, oder?

Was hat denn das LCD mit der UART zu tun?
In dem Code ist doch keine UART drin.

Ich sehe auch keinerlei Grund, warum Du meine LCD-Lib nicht mit 
irgeneiner UART-Lib kombinieren können solltest.


> Wenn ich jedoch eine ganz neue lib verwende, muss ich ja alles mit dem
> LCD  überarbeiten, weil in deinem Code die Funktionen anders heißen.

Was hindert Dich daran, Deine Namen zu verwenden?
Man muß es aber nicht überall im Quelltext tun.
Es reicht, im lcd.h-File ein paar #defines zu machen, die die 
Textersetzung für Dich durchführen.

Die lcd.c ist auch kein monolithischer Block und kein Hexenwerk.
Du kannst also beliebig drin rumeditieren oder fehlende Funktionen aus 
Deiner Lib mit einfügen.

Wichtig sind ja nur die 3 Grundfunktionen: Nibble senden, Datenbyte 
senden und Kommandobyte senden.
Sämtliche anderen Funktionen bauen dann ja darauf auf (sollten sie 
jedenfalls).


Peter

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Peter Dannegger wrote:
> Steffen O. wrote:
>> Ja, aber dein Code ist ja eine ganz neue UART lib, wenn ich das richtig
>> verstanden habe, oder?
>
> Was hat denn das LCD mit der UART zu tun?
> In dem Code ist doch keine UART drin.
>
> Ich sehe auch keinerlei Grund, warum Du meine LCD-Lib nicht mit
> irgeneiner UART-Lib kombinieren können solltest.
>
Sorry, da meinte ich natürlich LCD-lib. Ich hab schon irgendwie über 
meine UART-Verbindung nachgedacht, und war dann nicht richtig bei der 
Sache.


>> Wenn ich jedoch eine ganz neue lib verwende, muss ich ja alles mit dem
>> LCD  überarbeiten, weil in deinem Code die Funktionen anders heißen.
>
> Was hindert Dich daran, Deine Namen zu verwenden?
> Man muß es aber nicht überall im Quelltext tun.
> Es reicht, im lcd.h-File ein paar #defines zu machen, die die
> Textersetzung für Dich durchführen.

Ja, ich werds mir nochmal anschauen, vielleicht nehm ich ja auch deine 
lib.

> Die lcd.c ist auch kein monolithischer Block und kein Hexenwerk.
> Du kannst also beliebig drin rumeditieren oder fehlende Funktionen aus
> Deiner Lib mit einfügen.
>
> Wichtig sind ja nur die 3 Grundfunktionen: Nibble senden, Datenbyte
> senden und Kommandobyte senden.
> Sämtliche anderen Funktionen bauen dann ja darauf auf (sollten sie
> jedenfalls).

Ok.


Gut, ich werd dann erstmal die Veränderungen von F1-Circus-Fan in meiner 
lib durchführen, und wenns klappt, ists gut, und wenn nicht, dann werd 
ich mir deine Lösung nochmals anschauen.

Gruß, Steffen

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ok, nochmal Vielen Dank an F1-Circus-Fan!!!!
Mit deinen Veränderungen klappt die Ansteuerung des LCDs!!!

Gruß, Steffen

von nixversteh (Gast)


Lesenswert?

Obacht, da stimmt was nicht. Besser so bei den High-Nibbles.
1
LCD_PORT |= (temp1 >> (4-D0_PORT)) & MASK;

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.