Forum: Compiler & IDEs LCD an Atmel - ENable-Pin auf anderen Port


von M.B. (Gast)


Lesenswert?

Hallo ich habe ein Problem!

Ich habe ein LCD-Display 4x20 an meinem ATmega88 angeschlossen und 
möchte für das Enable-Signal einen anderen Pin an einem anderen Port 
benutzen. Leider versagt diese Methode:

Bisher hatte ich das Display komplett an PortD (D0-D5). Das funktioniert 
einwandfrei. Nun brauche ich den PWM-Ausgang D5 an Port D. Kurzerhand 
habe ich die Leitung an C5 Port C gelötet und im Quellcode die Stellen 
entsprechend bearbeitet. - Und gehofft das es läuft. Es tuts aber nicht. 
Irgendetwas übersehe ich. Vielleicht kann jemand von Euch sich meiner 
Sache annehmen - ich verzweifle schon!
1
in lcd-routines.h:
2
3
// Pinbelegung für das LCD, an verwendete Pins anpassen
4
 
5
#define LCD_PORT      PORTD
6
#define LCD_DDR       DDRD
7
8
#define LCD_PORT_RS   PORTD // geändert, vorher: LCD_PORT - wie oben
9
#define LCD_DDR_RS    DDRD  // geändert, vorher: LCD_DDR  - wie oben
10
#define LCD_RS        PD4  
11
12
#define LCD_PORT_EN   PORTC // geändert, vorher: LCD_PORT - wie oben 
13
#define LCD_DDR_EN    DDRC  // geändert, vorher: LCD_DDR  - wie oben
14
#define LCD_EN        PC5   // vorher PD5
15
//#define LCD_EN        PD5 - wird verwendet für PWM ausgang
16
17
18
und in lcd-routines.c:
19
20
// erzeugt den Enable-Puls
21
void lcd_enable(void)
22
{
23
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
24
   // http://www.mikrocontroller.net/topic/81974#685882
25
   LCD_PORT_EN |= (1<<LCD_EN);      // geändert
26
    _delay_us(1);                   // kurze Pause
27
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
28
   // http://www.mikrocontroller.net/topic/80900
29
   LCD_PORT_EN &= ~(1<<LCD_EN);     // geändert
30
}
31
32
und weiter:
33
34
void lcd_init(void)
35
{
36
   LCD_DDR    |= 0x0F;         // Port auf Ausgang schalten
37
   LCD_DDR_RS |= (1<<LCD_RS);  // RS-Port auf Ausgang
38
   LCD_DDR_EN |= (1<<LCD_EN);  // ENable-Port auf Ausgang
39
 [...]
40
41
// ehemalig:    LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN);  
42
}
43
44
sowie alle 
45
LCD_PORT &= ~(1<<LCD_RS);
46
in
47
LCD_PORT_RS &= ~(1<<LCD_RS);
48
geändert

von gast (Gast)


Lesenswert?

Hi,
so wie ich das sehe musst Du im init LCD_DDR = 0x1F schreiben, sonst ist 
PD4 nicht auf Ausgang geschaltet.

Gruß
Frank

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Machen die nicht sichtbaren Codeteile (insbesondere die PWM 
Initialisierung) noch was mit DDRC oder PORTC? Vielleicht machen die die 
lcd_int() für die EN Leitung unwirksam.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Frank wrote:

> so wie ich das sehe musst Du im init LCD_DDR = 0x1F schreiben, sonst ist
> PD4 nicht auf Ausgang geschaltet.

Es ist etwas ungeschickt in der Source, aber Output für PD4 einstellen 
macht die Zeile
   LCD_DDR_RS |= (1<<LCD_RS);  // RS-Port auf Ausgang

von Frank L. (franklink)


Lesenswert?

Hi,
dann schick mal Deinen gesamten Code, dann ist es mit Sicherheit 
einfacher Dir zu helfen.

Gruß
Frank

von M.B. (Gast)


Lesenswert?

Zunächst erst einmal vielen Dank für Eure Antworten und Tipps!

Frank wrote:
>so wie ich das sehe musst Du im init LCD_DDR = 0x1F schreiben, sonst ist
>PD4 nicht auf Ausgang geschaltet.

Stefan wrote:
>Es ist etwas ungeschickt in der Source, aber Output für PD4 einstellen
>macht die Zeile
>   LCD_DDR_RS |= (1<<LCD_RS);  // RS-Port auf Ausgang

Das ist nicht ungeschickt, sondern so gewollt um die Ports flexibel zu 
gestalten, so, wie von mir geplant.
Es ist möglich die Leitungen Daten, RS und Enable an getrennten Ports zu 
betreiben.

Stefan wrote:
>Machen die nicht sichtbaren Codeteile (insbesondere die PWM
>Initialisierung) noch was mit DDRC oder PORTC? Vielleicht machen die die
>lcd_int() für die EN Leitung unwirksam.

Ich habe im Moment, wegen des Problems, den Code minimiert. Die PWM wird 
nicht genutzt und auch nicht initialisiert. Außerdem ist PWM an PortD 
und daher wollte ich mit Enable an PortC ausweichen.

Meine main sieht so aus, das nur etwas am Display angezeigt werden soll:
1
main.c:
2
3
uint16_t Spg=0;
4
char Buffer[10];       // Buffer für LCD Umwandlung ascii to integer
5
6
lcd_init();  // initialisieren von Display
7
set_cursor(1,0);  // Cursor setzen: Zeile 1, Stelle 0
8
lcd_string("Hallo Welt");  // schreiben
9
10
for(;;)  // Programmschleife
11
{
12
13
  Spg = Messung(Spannung);  // Unterprogramm Standart ADC-Funktion, ohne DDR und PORT Anweisung
14
  itoa(Spg,Buffer,10); // umwandeln in lesbare Zahl am Display
15
  set_cursor(2,0);  // Cursor setzen: Zeile 2, Stelle 0
16
  lcd_string(Buffer);  // Ausgabe der Zahl
17
18
}

btw, wenn ich >Build starten< auswähle, kommt folgende Warnung:
warning: implicit declaration of function 'itoa'

beim nächsten Build-Vorgang ist die Warnung wieder weg. Wie soll ich 
damit umgehen? Ignorieren?

Und noch was PortC Pin C5 habe ich vorher als Digit Out benutzt und das 
funktionierte auch. Jetzt brauche ich die PWM-Ansteuerung und habe daher 
D5 und C5 tauschen wollen. Heißt: C5 ist nicht defekt.

von Stefan E. (sternst)


Lesenswert?

> beim nächsten Build-Vorgang ist die Warnung wieder weg.

Weil es von der C-Datei bereits eine aktuelle Objekt-Datei gibt, wird 
sie nicht nochmal übersetzt.

> Wie soll ich damit umgehen? Ignorieren?

Nein, die richtige Header-Datei einbinden (stdlib.h).

von M.B. (Gast)


Lesenswert?

Stefan Ernst wrote:
>> Wie soll ich damit umgehen? Ignorieren?
>
>Nein, die richtige Header-Datei einbinden (stdlib.h).

Vielen Dank für die Info! Das hat funktioniert - die Warnung ist weg.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

M.B. wrote:

> Das ist nicht ungeschickt, sondern so gewollt um die Ports flexibel zu
> gestalten, so, wie von mir geplant.

Das ist klar. Ungeschickt ist, dass LCD_DDR_RS zu etwas verodert wird 
ohne dass dessen Grundeinstellung definiert wird.

Bei dem LCD_DDR_EN ist das anders gelöst, da steht als Grundeinstellung 
ein LCD_DDR = ... davor. Durch deine Änderung ist aber LCD_DDR == 
LCD_DDR_EN != LCD_DDR_RS und die LCD_DDR = ... Zuweisung gilt für den 
LCD_DDR_RS Port nicht.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

[aufreg an]
Wann lernen es die Leute, dass Codefetzen nix bringen ausser Nachfrage 
nach Nachfrage oder Schweigen.
[aufreg aus]

Wie sieht Messung() aus? Beim Atmega88 ist der ADC an PORTC und du 
hast dein LCD RS an PORTC. Beeinflusst die Initialisierung des ADC den 
Pin PC5? Der/die Pin(s) an PORTC werden ja von IO-Pins auf ADC-Pins 
umgeschaltet. Wird PC5 davon auch ausgenommen?

Atmega88 Datenblatt
http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf

von M.B. (Gast)


Lesenswert?

Habe die AD-Wandlung auch rausgeschmissen und gebe nur einen festen Wert 
aus. Es funktioniert einfach nicht. Habe den Port gerade nach D6 gelegt 
- das funktioniert auch. War zwar fummelei weil ich einen µC in TQFP 
habe und dort eine Leitung an das Beinchen anlöten musste, aber dann 
mujss ich mich nicht mehr mit dem Display rumärgern. Obwohl es mir alles 
sehr merkwürdig vorkommt.

Wenn ich Zeit habe werde ich der Sache noc mal nachegehn und einen 
Dip-µC holen und ein bischen rumspielen.

Vielen Dank trotzdem für eure tipps

von Peter D. (peda)


Lesenswert?

Einfach so machen:

http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip

und schon geht jede x-beliebige Pinkombination fürs LCD.
Nie mehr Nachdenken oder Code ändern müssen.


Peter

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.