Forum: Mikrocontroller und Digitale Elektronik 20x4 lcd zeigt immer das gleiche an


von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Hallo erstmal an alle :)
Ich hoffe Ihr könnt mir bei einem Problem helfen.

Ich steuere einen KS0066-LCD mit 4 Zeilen zu je 20 Zeichen via 
4-bit-modus mit einem ATMega16 Mikrocontroller an. Nur will das 
irgendwie nicht funktionieren und ich weiß nicht mehr weiter. Das 
einzige was ich zu sehen bekomme sind 2 Balken, jeweils in 1. & 3. 
Zeile.

Fehlerquellen die ich bis jetzt schon ausschließen konnte:
-kalte Lötstellen
-schaltungstechnische fehler
-bauteile

es muss also an der software, sprich an meinem Programm liegen.
Dieses sieht wie folgt aus:
------------------------------------------------------------------------
1
#define PORT_LCD      PORTB
2
#define LCD_RS        PB0
3
#define LCD_EN        PB1
4
5
void lcd_data(unsigned char temp1)
6
{
7
  unsigned char temp2 = temp1;
8
  PORT_LCD = (temp1 & 0xF0) | LCD_RS;
9
  _delay_us(41);
10
  lcd_enable();
11
  temp2 = temp2 << 4;
12
  PORT_LCD = (temp2 & 0xF0) | LCD_RS;
13
  _delay_us(41);
14
  lcd_enable();
15
  _delay_us(44);
16
}
17
18
void lcd_command(unsigned char temp1)
19
{
20
  unsigned char temp2 = temp1;
21
  PORT_LCD = (temp1 & 0xF0);
22
  _delay_us(41);
23
  lcd_enable();
24
  temp2 = temp2 << 4;
25
  PORT_LCD = (temp2 & 0xF0);
26
  _delay_us(41);
27
  lcd_enable();
28
  _delay_us(44);
29
}
30
31
void lcd_enable(void)
32
{
33
  PORT_LCD |= LCD_EN;
34
  _delay_us(21);
35
  PORT_LCD &= ~LCD_EN;
36
}
37
38
39
void lcd_init(void)
40
{
41
  _delay_ms(31);
42
  lcd_command(0x30);
43
  _delay_us(5);
44
  lcd_enable();
45
  lcd_command(0x30);
46
  _delay_us(101);
47
  lcd_enable();
48
  lcd_command(0x30);
49
  lcd_enable();
50
  
51
  lcd_command(0x20);
52
  
53
  lcd_command(0x07); // I/D=1, S=1
54
  lcd_command(0x0E); // D=1, C=1, B=0
55
  lcd_command(0x10); // S/C=0, R/L=0
56
  lcd_command(0x2C); // 4bit, 5x10
57
}
58
59
void lcd_clear(void)
60
{
61
  PORT_LCD = 0x01;
62
  _delay_ms(2);
63
  lcd_enable();
64
}
65
66
void lcd_home(void)
67
{
68
  PORT_LCD = 0x20;
69
  _delay_ms(2);
70
  lcd_enable();
71
}
72
73
void lcd_setcursor(uint8_t x, uint8_t y)
74
{
75
  uint8_t temp = 0;
76
  if(y==0)    {temp = x;}
77
  else if(y==1) {temp = 40 + x;}
78
  else if(y==2) {temp = 14 + x;}
79
  else if(y==3) {temp = 54 + x;}
80
  lcd_command(temp);
81
}
------------------------------------------------------------------------

Im Anhang findet Ihr noch das Datenblatt des LCDs.

Ich bitte um schnelle Antwort beziehungsweise Hilfe.
Die Ansteuerung des LCD ist Teil meiner Diplomarbeit für den Abschluss 
der HTL. Somit bekommt das Problem eine gewisse Wichtigkeit ^^

: Bearbeitet durch User
von Uwe (de0508)


Lesenswert?

Hallo Ryan,

schaue dir bitte die beiden funktionierenden Libs von PeDa [1], [2] und 
Peter Fleury [3] an.

Es liegt bei Dir bestimmt am Timing, aber die korrekte 4 Bit Ansteuerung 
wird Du selbst überprüfen müssen.

_Links:_
[1] 
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=102296
[2] Beitrag "Re: C/C++ LCD Lib für Arduino 2560 Board mit LCD Shield 1602"
[3] http://homepage.hispeed.ch/peterfleury/avr-software.html

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Das Fehlerbild ist typisch für eine misslungene Initialisierung. Der 
Controller geht in die default Einstellung (bei 4 zeiligen Displays sind 
meist Zeile 1 und 3 logisch zwei Hälften einer einzigen Zeile).

Zeig uns doch bitte deinen Schaltplan. Wie ist RW beschaltet?

von spess53 (Gast)


Lesenswert?

Hi

>Nur will das
>irgendwie nicht funktionieren und ich weiß nicht mehr weiter.

Das heißt ganz einfach, das die Initialisierung nicht passt.

>  PORT_LCD = ....
>  _delay_us(41);
>  lcd_enable();

Tausche mal bei allen Ausgaben dieser Art delay und enable. Der Befehl 
wird nämlich erst mit dem enable ausgeführt und das delay muss zwischen 
zwei Ausgaben liegen.

MfG spess

von Georg G. (df2au)


Lesenswert?

Er pulst enable schon in der Befehls-schreib-Routine. Das zusätzliche 
lcd-enable ist imho überflüssig.

von spess53 (Gast)


Lesenswert?

Hi

>Das zusätzliche lcd-enable ist imho überflüssig.

Aber nicht bei den ersten drei Befehlen der Initialisierung.

MfG Spess

von holger (Gast)


Lesenswert?

>Er pulst enable schon in der Befehls-schreib-Routine. Das zusätzliche
>lcd-enable ist imho überflüssig.

Nö, das lcd_command() darf er bei den drei 0x30 einfach nicht machen.

von Georg G. (df2au)


Lesenswert?

spess53 schrieb:
> Aber nicht bei den ersten drei Befehlen der Initialisierung.

Wie kommst du da drauf? Zweimal enable ist nicht notwendig.

So mach ich es seit Jahr und Tag und hatte noch nie Probleme:
  lcd_write(0x28,0); // Vorspann laut Displaytech Datenblatt
  _delay_ms(10);
  lcd_write(0x28,0); // Busyflag funktioniert sonst nicht richtig
  _delay_ms(1);
  lcd_write(0x28,0);

von Ryan P. (ryanpolster)


Lesenswert?

@Georg G.
Das habe ich auch schon gelesen. Anschließend habe ich viel Zeit in die 
Initialisierung gesteckt - erfolglos.
RW ist auf GND, weil ich ohnehin nie etwas von LCD auslesen werde. Das 
sollte letztendlich ein Tacho sein.

@all

also wie ist jetzt die richtige Reihenfolge bzw. Syntax? ^^

von Ryan P. (ryanpolster)


Lesenswert?

1
#define PORT_LCD      PORTB
2
#define LCD_RS        PB0
3
#define LCD_EN        PB1
4
5
void lcd_data(unsigned char temp1)
6
{
7
  unsigned char temp2 = temp1;
8
  PORT_LCD = (temp1 & 0xF0) | LCD_RS;
9
  lcd_enable();
10
  _delay_us(41);
11
  temp2 = temp2 << 4;
12
  PORT_LCD = (temp2 & 0xF0) | LCD_RS;
13
  lcd_enable();
14
  _delay_us(41);
15
  _delay_us(44);
16
}
17
18
void lcd_command(unsigned char temp1)
19
{
20
  unsigned char temp2 = temp1;
21
  PORT_LCD = (temp1 & 0xF0);
22
  lcd_enable();
23
  _delay_us(41);
24
  temp2 = temp2 << 4;
25
  PORT_LCD = (temp2 & 0xF0);
26
  lcd_enable();
27
  _delay_us(41);
28
  _delay_us(44);
29
}
30
31
void lcd_enable(void)
32
{
33
  PORT_LCD |= LCD_EN;
34
  _delay_us(21);
35
  PORT_LCD &= ~LCD_EN;
36
}
37
38
39
void lcd_init(void)
40
{
41
  _delay_ms(31);
42
  lcd_command(0x30);
43
  lcd_enable();
44
  _delay_us(5);
45
  lcd_command(0x30);
46
  lcd_enable();
47
  _delay_us(101);
48
  lcd_command(0x30);
49
  lcd_enable();
50
  
51
  lcd_command(0x20);
52
  
53
  lcd_command(0x07); // I/D=1, S=1
54
  lcd_command(0x0E); // D=1, C=1, B=0
55
  lcd_command(0x10); // S/C=0, R/L=0
56
  lcd_command(0x2C); //4bit, 5x10
57
}
58
59
void lcd_clear(void)
60
{
61
  PORT_LCD = 0x01;
62
  lcd_enable();
63
  _delay_ms(2);
64
}
65
66
void lcd_home(void)
67
{
68
  PORT_LCD = 0x20;
69
  lcd_enable();
70
  _delay_ms(2);
71
}
72
73
void lcd_setcursor(uint8_t x, uint8_t y)
74
{
75
  uint8_t temp = 0;
76
  if(y==0)    {temp = x;}
77
  else if(y==1) {temp = 40 + x;}
78
  else if(y==2) {temp = 14 + x;}
79
  else if(y==3) {temp = 54 + x;}
80
  lcd_command(temp);
81
}

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

ok, hab jetzt den fehler bei lcd_home entfernt & alle unnötigen enables 
weggegeben.. immernoch das gleiche bild
1
#define PORT_LCD      PORTB
2
#define LCD_RS        PB0
3
#define LCD_EN        PB1
4
5
void lcd_data(unsigned char temp1)
6
{
7
  unsigned char temp2 = temp1;
8
  PORT_LCD = (temp1 & 0xF0) | LCD_RS;
9
  lcd_enable();
10
  _delay_us(41);
11
  temp2 = temp2 << 4;
12
  PORT_LCD = (temp2 & 0xF0) | LCD_RS;
13
  lcd_enable();
14
  _delay_us(41);
15
  _delay_us(44);
16
}
17
18
void lcd_command(unsigned char temp1)
19
{
20
  unsigned char temp2 = temp1;
21
  PORT_LCD = (temp1 & 0xF0);
22
  lcd_enable();
23
  _delay_us(41);
24
  temp2 = temp2 << 4;
25
  PORT_LCD = (temp2 & 0xF0);
26
  lcd_enable();
27
  _delay_us(41);
28
  _delay_us(44);
29
}
30
31
void lcd_enable(void)
32
{
33
  PORT_LCD |= LCD_EN;
34
  _delay_us(21);
35
  PORT_LCD &= ~LCD_EN;
36
}
37
38
39
void lcd_init(void)
40
{
41
  _delay_ms(31);
42
  lcd_command(0x30);
43
  _delay_us(5);
44
  lcd_command(0x30);
45
  _delay_us(101);
46
  lcd_command(0x30);
47
  
48
  lcd_command(0x20);
49
  
50
  lcd_command(0x07); // I/D=1, S=1
51
  lcd_command(0x0E); // D=1, C=1, B=0
52
  lcd_command(0x10); // S/C=0, R/L=0
53
  lcd_command(0x2C); //4bit, 5x10
54
}
55
56
void lcd_clear(void)
57
{
58
  PORT_LCD = 0x01;
59
  lcd_enable();
60
  _delay_ms(2);
61
}
62
63
void lcd_home(void)
64
{
65
  PORT_LCD = 0x02;
66
  lcd_enable();
67
  _delay_ms(2);
68
}
69
70
void lcd_setcursor(uint8_t x, uint8_t y)
71
{
72
  uint8_t temp = 0;
73
  if(y==0)    {temp = x;}
74
  else if(y==1) {temp = 40 + x;}
75
  else if(y==2) {temp = 14 + x;}
76
  else if(y==3) {temp = 54 + x;}
77
  lcd_command(temp);
78
}

: Bearbeitet durch User
von Uwe (de0508)


Lesenswert?

Hallo Ryan,

weine Lösung habe ich Dir aufgezeigt, wenn Du weiter nur rumstochern 
möchtest Bitte.

Wenn Du mit einer der beiden Libs deine HW testen solltest, siehst Du 
vielleicht den wald vor lauter bäumen.

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

ok ich werde jede dieser Libs am Abend testen, da ich jetzt leider weg 
muss.
ich werde mich schnellstmöglich wieder melden.

Und danke schonmal an alle helfenden :)

von Ryan P. (ryanpolster)


Lesenswert?

@Uwe S.
ich hab die Libs jetzt auf meine Hardware angepasst und sie getestet. 
Leider erfolglos.
Was mir aber auffällt ist dass alle Libs im Internet die Zeile

#include "irgendwas.h"

haben.

wenn ich die *.h datei einbinde erkennt er keine einzige Funktion.
daraufhin ändere ich es immer so wie es für mich sinn macht, sprich

#include "irgendwas.c"

ist das egal in welcher reihenfolge das aufgerufen wird oder auf was 
sollte man hier achten?

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:

> Was mir aber auffällt ist dass alle Libs im Internet die Zeile
>
> #include "irgendwas.h"
>
> haben.

Ja.
Genau so soll das ja auch sein.

> wenn ich die *.h datei einbinde erkennt er keine einzige Funktion.
... beim Linken

> daraufhin ändere ich es immer so wie es für mich sinn macht, sprich
>
> #include "irgendwas.c"

Und genau das macht man eben nicht.

C ist als Sprache so designed, dass ein komplettes Programm aus mehreren 
C-Dateien bestehen kann. Jede einzelne C-Datei wird getrennt von allen 
anderen compiliert und die einzelnen Übersetzungsergebnisse werden von 
einem Linker zum kompletten Programm zusammengesetzt.

OK, auf den kleinen µC ist das nicht so wichtig. Aber in der 
professionellen Entwicklung IST das wichtig. Dann da besteht ein 
komplettes Projekt schon auch mal aus ein paar hundert C-Files. Da ist 
es wichtig, dass jede einzelne für sich übersetzbar ist. Denn dann sind 
Programmänderungen in ein paar Sekunden realisierbar: das geänderte 
C-File wird neu kompiliert und mit den immer noch vorhandenen 
vorhergehenden Überstzungsergebnissen der anderen C-Files ein neues 
Programm zusammengelinkt. Das dauert ein paar Sekunden bis ein paar 
Minuten, während eine komplette neue Übersetzung des kompletten Source 
Codes schon auch mal ein paar Stunden dauern kann.

Nichts desto trotz kannst du dasselbe Vorgehen wie die Profis benutzen. 
Wenn du eine Entwicklungsumgebung hast, dann fügst du der ganz einfach 
das 2.te C-File noch mit dazu, und dann sorgt die IDE, dass der 
komplette Ablauf genau so durchläuft: beide C-Files werden getrennt 
voneinander kompiliert und dann die Überstzungsergebnisse 
zusammengelinkt.
Wenn du keine IDE hast, dann hast du zumindest ein makefile. IM makefile 
das 2.te C-File eintragen und dann erledigt das makefile (wenn es 
richtig geschrieben ist) all diese Schritte. Wenn du noch nicht mal ein 
makefile hast: Warum hast du keines?

> Die Ansteuerung des LCD ist Teil meiner Diplomarbeit für den
> Abschluss der HTL.
Gerade dann solltest du aber eigentlich den Enstehungsprozess eines 
Programmes aus mehreren Source Code Files kennen. Denn als dein 
potentieller Arbeitgeber würde ich mich schön gefrotzelt vorkommen, wenn 
ich dich in die Programmierung einstelle und dir dann die Grundlagen 
erst mal beibringen muss, wie eigentlich Programme gebaut werden - wie 
Compiler und Linker zusammenspielen.

Mittlerweile hab ich mich daran gewöhnt. Schöne Verarsche, die das 
Ministerium da mit euch treibt, indem sie das alles 'Diplomarbeit' 
nennt. Eine Diplomarbeit ist für mich eine Arbeit, die an einer Uni 
gemacht wird um den akademischen Grad 'Diplom-Ingenieur' zu erwerben 
(ja, ich weiss, den gibt es nicht mehr). Eine Abschlussarbeit an einer 
HTL ist für mich eine Abschlussarbeit. Aber sicher keine Diplomarbeit. 
Seit wann gibt es da ein Diplom dafür?

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

dann liegt mein problem wohl im makefile.

wie kann ich denn den bearbeiten?

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:
> ok, hab jetzt den fehler bei lcd_home entfernt & alle unnötigen enables
> weggegeben.. immernoch das gleiche bild

Du bellst den falschen Baum an.

Wenn ein HD_hamstibamsti LCD das bekannte Bild mit den Balken zeigt, 
dann liegt das Problem am Anfang der INitialisierung. Also hier

> void lcd_init(void)
> {
>   _delay_ms(31);
>   lcd_command(0x30);
>   _delay_us(5);
>   lcd_command(0x30);
>   _delay_us(101);
>   lcd_command(0x30);
>
>   lcd_command(0x20);
>



Da ist weder ein lcd_clear beteiligt, noch ist sonst irgendeine deiner 
Funktionen beteiligt. Da geht es einzig und alleine darum, dass an den 4 
verbundenen Dtaenleitungen das richtige Muster anliegt und dass Zeiten 
eingehalten werden. Punkt.

Denn:
du kannst an dieser Stelle deine lcd_command Funktion noch nicht 
benutzen.
Die lcd_command Funktion kannst du erst dann benutzen, wenn das LCD 
schon im 4-Bit Modus IST. Dazu muss es aber erst mal in diesem Momdus 
SEIN. Schlussfolgerung: an dieser Stelle kann die Funktion nicht benutzt 
werden, sondern mann muss händisch die Bitmuster auf die Portpins geben 
und den Enable-Toggler aufrufen.
Das ist wie der Baron von Münchhausen, der sich nicht selbst am 
Haarschopf
aus dem Sumpf ziehen kann.

Und natürlich sich an die zeitlichen Vorgaben halten.

Und natürlich muss die Verkabelung stimmen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Georg G. schrieb:
> spess53 schrieb:
>> Aber nicht bei den ersten drei Befehlen der Initialisierung.
>
> Wie kommst du da drauf? Zweimal enable ist nicht notwendig.

Doch ist es.
Eine robuste Initialisierung eines HD44780 (bzw. KS0066) kann ein LCD 
aus jedem beliebigen Zustand wieder in einen geordneten 4-Bit Modus 
holen.
Selbst dann, wenn der ansteuernde Prozessor mitten in der Befehlsausgabe 
nach dem ersten Nibble resettet wird und das HD44780 bis zum St. 
Nimmerleinstag auf die 2.te Hälfte des Befehlsbytes warten würde.

Genau darauf ist die ganze Initialisierung ausgelegt. Das LCD mit 
absoluter Sicherheit aus jedem beliebigen Ansteuerzustand wieder 
geordnet in den 4.Bit Modus zu holen und zu initialisieren. Und zwar 
ohne Power down / Power up.

Daher stammen zum Teil nämlich auch die diversen einzuhaltenden 
Wartezeiten :-) Das LCD könnte zufällig gerade das erste Nibble eines 
Clear Befehls erhalten haben, wenn der Reset kommt. Mit der ersten 
Übertragung der versuchten Neuinitialisierung wird dieser Clear 
abgeschlossen und das LCD führt den erst mal aus ... was abgewartet 
werden muss, ehe der 2.te Versuch gestartet wird, das LCD in den 8 Bit 
Modus zurück zu schalten, von wo man es dann in den 4 Bit Modus 
schaltet.

die 3-fache Ausgabe einer 0x3 auf den 4 Datenleitungen hat nur diesen 
einen Zweck: das LCD erst mal sicher in den 8 Bit Modus zu holen. Das 
kann je nach Betriebszustand nach 3 Nibble der Fall sein. Aber 
spätestens nach 3 Nibbles (und entsprechenden Wartezeiten) ist es im 8 
Bit Modus, von wo es dann mit einem einzigen 0x2 in den 4 Bit Modus 
geschaltet wird.

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

Ich habe jetzt die lcd_command() bei der Init durch Bitmuster wie folgt 
ersetzt:
1
_delay_ms(31);
2
PORT_LCD = 0b00110000;
3
_delay_us(5);
4
PORT_LCD = 0b00110000;
5
_delay_us(101);
6
PORT_LCD = 0b00110000;
7
8
PORT_LCD = 0b00100000;
9
10
lcd_command(0x07); // I/D=1, S=1
11
lcd_command(0x0E); // D=1, C=1, B=0
12
lcd_command(0x10); // S/C=0, R/L=0
13
lcd_command(0x2C); //4bit, 5x10
Jedoch weiß ich noch nicht wie ich den makefile bearbeiten kann und 
inwiefern ich die einträge darin ändern muss.
Bitte um Hilfe.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Wie sieht dein makefile jetzt aus?
bzw. wie baust du jetzt deine AVR Projekte zusammen?

von dummy (Gast)


Lesenswert?

>Ich habe jetzt die lcd_command() bei der Init durch Bitmuster wie folgt
>ersetzt:

..und dabei die notwendigen lcd_enable() gelöscht..

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Also ich kann die Dateiendung auf *.txt ändern um Einsicht zu bekommen.
Ich werde sie im Anhang hinzufügen.

Ich benutze Atmel Studio 6.1.
Damit kompiliere und programmiere ich.

von Ryan P. (ryanpolster)


Lesenswert?

touché..
1
_delay_ms(31);
2
  PORT_LCD = 0b00110000;
3
  lcd_enable();
4
  _delay_us(5);
5
  PORT_LCD = 0b00110000;
6
  lcd_enable();
7
  _delay_us(101);
8
  PORT_LCD = 0b00110000;
9
  lcd_enable();
10
  
11
  PORT_LCD = 0b00100000;
12
  lcd_enable();
13
  
14
  lcd_command(0x07); // I/D=1, S=1
15
  lcd_command(0x0E); // D=1, C=1, B=0
16
  lcd_command(0x10); // S/C=0, R/L=0
17
  lcd_command(0x2C); //4bit, 5x10

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:
> Also ich kann die Dateiendung auf *.txt ändern um Einsicht zu bekommen.

Brauchst du nicht.
So ist das gut.


> Ich benutze Atmel Studio 6.1.

OK, dann ist das makefile im Grunde uninteressant, denn Atmel Studio 
erzeugt sich selber eines.

Nur der Vollständigkeit halber
Im Makefile
1
....
2
# Add inputs and outputs from these tool invocations to the build variables 
3
C_SRCS +=  \
4
../Diplomarbeit.c
5
6
...


Im Atmel Studio machst du über dem Projekt-Baum einen Rechtsklick, aus 
dem Kontextmenü "Add existing Source File" und fügst das andere C-File 
zum Projekt mit dazu. Ab sofort kümmert sich Atmel Studio darum, dass es 
mitcompiliert und mitgelinkt wird.

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

jetzt habe ich dei *.c Datei erfolgreich eingebunden.
Aber es geht immer noch nicht.

Habe es jetzt auch wieder mit der Lib von Peter Fleury ausprobiert, da 
mir seine die liebste von den oben genannten drei ist.

von Karl H. (kbuchegg)


Lesenswert?

Ryan Polster schrieb:

> Habe es jetzt auch wieder mit der Lib von Peter Fleury ausprobiert, da
> mir seine die liebste von den oben genannten drei ist.

Im Header File von den Fleury Funktionen gibt es einen Schalter für 
KS0066 LCD. Hast du den richtig gesetzt?

Und für die Fleury Lib musst du die R/W Leitung verbinden (oder 
alternativ die Funktion busywait durch eine Wartezeit ersetzen)

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

KS0066 Bit ist richtig gesetzt.

Die R/W-Leitung habe ich auf GND. Sollte ja eig. keinen Einfluss auf das 
Programm haben. Ich werde es trotzdem ändern.

von Ryan P. (ryanpolster)


Lesenswert?

Habe jetzt R/W auf PB2 gelegt und das stimmt auch mit dem Code überein.
Geht aber trotzdem nicht.
Ich weiß langsam echt nicht mehr weiter.

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Gibt es sonst noch etwas auf das man bei der Ansteuerung eines LCD 
achten muss bzw. sollte?

oder etwas erwähnenswertes zu Peter Fleurys library?

Im Anhang hab ich alle relevanten Dateien hinzugefügt.
Ich brauche unbedingt eure Hilfe.

von Hubert G. (hubertg)


Lesenswert?

Stimmt die angegebene Taktfrequenz, F-CPU, mit der tatsächlichen 
Taktfrequenz überein?

von Robo (Gast)


Lesenswert?

Hatte mal einen ähnlichen Effekt, da war der Kontrast-Trimmer defekt.

von holger (Gast)


Lesenswert?

while(1)
  {
    lcd_clrscr();
    lcd_home();
    lcd_puts("Hallo");
  }

Dein LCD wird schneller wieder gelöscht als du hinsehen kannst;)

von holger (Gast)


Lesenswert?

In Diplomarbeit.c

#define F_CPU 8000000

In lcd.h

#define XTAL 4000000              /**< clock frequency in Hz, used to 
calculate delay timer */

Ja was denn nun?

von holger (Gast)


Lesenswert?

In lcd.h

#define LCD_CONTROLLER_KS0073 1  /**< Use 0 for HD44780 controller, 1 
for KS0073 controller */

Das muss 0 sein für KS0066

von Ryan P. (ryanpolster)


Lesenswert?

so, ks0066 bit ist auf 0

jetzt ist nur noch xtal auf 4mhz in lcd.h

@holger: den bildschirm löschen habe ich jetzt aus der schleife genommen

@hubert: tatsächliche taktfrequenz?

von Ryan P. (ryanpolster)


Lesenswert?

was ist eigentlich der unterschied zwischen XTAL und F_CPU?
oder wann verwendet man das eine und wann das andere?

ich habe jetzt nämlich eine Warnung dass F_CPU von delay.h genommen wird 
und das wären 1Mhz.

und was bedeutet "UL" bei F_CPU 1000000UL ?

: Bearbeitet durch User
von Ryan P. (ryanpolster)


Lesenswert?

@hubert: Die Frequenz des LCD ist 270kHz
meinst du das mit tatsächlicher Taktfrequenz? Müssen die identisch sein?

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> was ist eigentlich der unterschied zwischen XTAL und F_CPU?
> oder wann verwendet man das eine und wann das andere?

An sich ist es egal wenn es mit dem Namen im laufenden Programm 
übereinstimmt. F_CPU kann man im AVR-Studio4 unter configuration options 
einstellen. Wird in den anderen Versionen ähnlich sein. Damit muss ich 
das nur einmal machen.
F_CPU sollte aber auch mit der Taktfrequenz übereinstimmen mit der der 
Controller tatsächlich läuft.

von Ryan P. (ryanpolster)


Lesenswert?

und mit welcher läuft der ATMega16?

von Ryan P. (ryanpolster)


Angehängte Dateien:

Lesenswert?

Das Problem liegt an der Initialisierung.
Eine Initialisierung besteht ja nur aus 2 Teilen:
-Die Kommandos
-Das Timing dazwischen

Das alles ist aus dem Datenblatt zu entnehmen.
Dieses habe ich als Anhang hinzugefügt.

Den Code(von Peter Fleury) zur Initialisierung habe ich hier, angepasst 
an meine Hardware:
1
/*************************************************************************
2
Initialize display and select type of cursor 
3
Input:    dispAttr LCD_DISP_OFF            display off
4
                   LCD_DISP_ON             display on, cursor off
5
                   LCD_DISP_ON_CURSOR      display on, cursor on
6
                   LCD_DISP_CURSOR_BLINK   display on, cursor on flashing
7
Returns:  none
8
*************************************************************************/
9
void lcd_init(uint8_t dispAttr)
10
{
11
#if LCD_IO_MODE
12
    /*
13
     *  Initialize LCD to 4 bit I/O mode
14
     */
15
     
16
    if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
17
      && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT)
18
      && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) 
19
      && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) )
20
    {
21
        /* configure all port bits as output (all LCD lines on same port) */
22
        DDR(LCD_DATA0_PORT) |= 0x7F;
23
    }
24
    else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
25
           && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
26
    {
27
        /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
28
        DDR(LCD_DATA0_PORT) |= 0x0F;
29
        DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
30
        DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
31
        DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
32
    }
33
    else
34
    {
35
        /* configure all port bits as output (LCD data and control lines on different ports */
36
        DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
37
        DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
38
        DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
39
        DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
40
        DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
41
        DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
42
        DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
43
    }
44
    delay(31000);        /* wait 16ms or more after power-on       */
45
    
46
    /* initial write to lcd is 8bit */
47
    LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);  // _BV(LCD_FUNCTION)>>4;
48
    LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
49
    lcd_e_toggle();
50
    delay(5);         /* delay, busy flag can't be checked here */
51
   
52
    /* repeat last command */ 
53
    lcd_e_toggle();      
54
    delay(105);           /* delay, busy flag can't be checked here */
55
    
56
    /* repeat last command a third time */
57
    lcd_e_toggle();      
58
    delay(105);           /* delay, busy flag can't be checked here */
59
60
    /* now configure for 4bit mode */
61
    LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);   // LCD_FUNCTION_4BIT_1LINE>>4
62
    lcd_e_toggle();
63
    delay(64);           /* some displays need this additional delay */
64
    
65
    /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */    
66
#else
67
    /*
68
     * Initialize LCD to 8 bit memory mapped mode
69
     */
70
    
71
    /* enable external SRAM (memory mapped lcd) and one wait state */        
72
    MCUCR = _BV(SRE) | _BV(SRW);
73
74
    /* reset LCD */
75
    delay(31000);                           /* wait 16ms after power-on     */
76
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                   
77
    delay(5);                            /* wait 5ms                     */
78
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                 
79
    delay(105);                              /* wait 64us                    */
80
    lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                
81
    delay(105);                              /* wait 64us                    */
82
#endif
83
84
#if KS0073_4LINES_MODE
85
    /* Display with KS0073 controller requires special commands for enabling 4 line mode */
86
  lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
87
  lcd_command(KS0073_4LINES_MODE);
88
  lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
89
#else
90
    lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines  */
91
#endif
92
    lcd_command(LCD_DISP_OFF);              /* display off                  */
93
    lcd_clrscr();                           /* display clear                */ 
94
    lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
95
    lcd_command(dispAttr);                  /* display/cursor control       */
96
97
}/* lcd_init */

Weiß jemand von euch weiter?

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

> Den Code(von Peter Fleury) zur Initialisierung habe ich hier, angepasst
> an meine Hardware:

Oh mein Gott.

>Weiß jemand von euch weiter?

Ja, hör auf in der lcd.c etwas zu ändern.
Nur die lcd.h musst du an deine LCD Beschaltung anpassen.

von Ryan P. (ryanpolster)


Lesenswert?

In der *.c Datei habe ich nur die Zeiten für die Initialisierung 
geändert, weil diese nicht mit meinem übereinstimmten.

von Hubert G. (hubertg)


Lesenswert?

In dieser Lib von Fleury musst du nur in der lcd.h Datei deine 
Einstellungen machen. Du verschleierst nur deine Probleme mit den 
Änderungen in der lcd.c.
Die Frequenz mit der dein Controller läuft musst du in die lcd.h 
eintragen.

Ich verwende die Fleury Lib schon seit Jahren. Wenn es mal nicht 
funktionierte dann war die Frequenz falsch oder es war ein 
Hardwarefehler.

von Ryan P. (ryanpolster)


Lesenswert?

Habe es jetzt mit der originalen lcd.c Datei von Peter Fleury versucht.
Funktioniert auch nicht.

von Hubert G. (hubertg)


Lesenswert?

Wie sieht es mit den Takteinstellungen aus?

von holger (Gast)


Lesenswert?

Welche Leitungen vom Display hast du angeschlossen?
Laut deinem Code müsste das

PORTB4 - DB4
PORTB5 - DB5
PORTB6 - DB6
PORTB7 - DB7

für den 4 Bit Mode sein.

von Ryan P. (ryanpolster)


Lesenswert?

Ich liste dir mal sämtliche auffindbaren Frequenzen auf:

ISP Clock: 115.2 kHz
Clock generator: 3,686 Mhz

XTAL: 4 Mhz (in lcd.h von Peter Fleury)
F_CPU: 4 Mhz (zusätzlich in Hauptprogramm, schadet ja nicht)

von Ryan P. (ryanpolster)


Lesenswert?

@holger: jop

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> Ich liste dir mal sämtliche auffindbaren Frequenzen auf:

Und mit welcher Frequenz läuft dein Mega16?

von holger (Gast)


Angehängte Dateien:

Lesenswert?

Funktioniert die Hex-Datei aus dem Anhang?

von Ryan P. (ryanpolster)


Lesenswert?

Ich dachte das sag ich ihm mit F_CPU bzw. XTAL?

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> Ich dachte das sag ich ihm mit F_CPU bzw. XTAL?

Nein, damit sagst du deinem Programm wie schnell dein Controller ist.

von Ryan P. (ryanpolster)


Lesenswert?

Die *.hex Datei funktioniert leider auch nicht.

von Hubert G. (hubertg)


Lesenswert?

Wie schnell dein Controller ist kannst du im AVR-Studio über die Fuses 
abfragen.

von holger (Gast)


Lesenswert?

>Die *.hex Datei funktioniert leider auch nicht.

Schlechte Karten für deine Schaltung;)
Zeig mal ein Foto.

von Ryan P. (ryanpolster)


Lesenswert?

Interessant, danke :)

Nachdem ich nicht extern dazu geschalten habe muss es irgendeine interne 
Frequenz sein. Näheres weiß ich leider nicht.

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> Näheres weiß ich leider nicht.

Wie wäre es mit Abfragen?

von W.S. (Gast)


Lesenswert?

Ryan Polster schrieb:
> Habe es jetzt mit der originalen lcd.c Datei von Peter Fleury versucht.
> Funktioniert auch nicht.

Hast du es mal mit der Doku zum Chip versucht? ("_Lesen_" meine ich)

Ich frage mich so langsam, ob das Posten von funktionierenden Quellen 
hier in diesem Forum etwas Gutes oder etwas völlig Kontraproduktives 
ist. Eigentlich meint unsereiner, daß es was Gutes ist, aber was zieht 
man damit groß? Leute, die solche Quellen nicht verstehen wollen, 
sondern bloß blind benutzen wollen - und sich selbst für Fachleute 
halten: "Hab die Lib von P.D. genommen, funzt nich, nu die von P.F. oh 
die funzt auch nich, watt für ein Mist in diesem Forum.."

Irgendwann sehe ich die Zeit kommen, daß die Moderatoren gemeinsam 
dieses Forum mitsamt dessen Trolls in die Luft sprengen und dann unter 
Absingen unanständiger Stoßgebete des Weges ziehen...

W.S.

von Ryan P. (ryanpolster)


Lesenswert?

Ich habe gehört bzw. gelesen dass man mit den Fuses sehr vorsichtig 
umgehen sollte (bei meinem Wissenstand).
Daher ändere ich erstmal nichts.
Da steht bei SUT_CKSEL "INTROSC_1MHZ_6CK_64MS"

also ich schätze mal 1Mhz?
und was bedeutet der Rest?

von Hubert G. (hubertg)


Lesenswert?

Ein wenig sollte man sich schon mit der Materie beschäftigen, besonders 
wenn es um einen Abschlußarbeit geht.
Es ist interner Takt, 1MHz, 6Takte und 64msek Verzögerung bis der 
Controller läuft.
Also jetzt mal die 1MHz als F_CPU eintragen.
Und schön langsam tippe ich auch einen Hardwarefehler in deiner 
Schaltung.

von Ryan P. (ryanpolster)


Lesenswert?

Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es 
zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so 
trivial ist.

1 µC
1 LCD
fertig ^^

Schaltungstechnische Fehler schließe ich aus, da ich ja nicht komplett 
inkompetent bin.
Lötstellen berühren sich nirgends.

von Hubert G. (hubertg)


Lesenswert?

Wenn es so einfach ist, bist du sicher das der Controller überhaupt 
läuft?
Nicht glauben sondern testen. Lass mal eine LED blinken.

Wie hast du deinen Timer eingestellt, wenn du nicht mal die Taktfrequenz 
weiss.

von Uwe (Gast)


Lesenswert?

Wieviele Abblockkondensatoren hat dein µC erhalten?
Wie ist avcc beschaltet?

von Ryan P. (ryanpolster)


Lesenswert?

Ich liste mal alle Verbindungen auf:

µC:
PB0: RS (LCD)
PB1: E  (LCD)
PB2: R/W(LCD)
PB4: D4(LCD)
PB5: D5(LCD)
PB6: D6(LCD)
PB7: D7(LCD)
Spannungsversorgung +5,18V

LCD:
Spannungsversorgung +5,18V
Kontrast: 5k Poti im Spannungsteilerbetrieb
RS: PB0
R/W: PB2
E: PB1
D0: GND
D1: GND
D2: GND
D3: GND
D4: PB4
D5: PB5
D6: PB6
D7: PB7
Kathode: GND
Anode: +5,18V mit Vorwiderstand: 120 Ohm

von Hubert G. (hubertg)


Lesenswert?

Steckst du deinen Programmer ab zum testen? Du bist mit den 
ISP-Leitungen auf den Datenleitungen des LCD.

von Ronny S. (phoenix-0815)


Lesenswert?

Ryan Polster schrieb:
> Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es
> zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so
> trivial ist.

Na dann sollten Deine Probleme ja alle zu deiner Zufriedenheit gelöst 
sein.

Viel Spaß noch mit dem Display habe auch solche sind echt nicht 
verkehrt.

Gruß Ronny

von Ryan P. (ryanpolster)


Lesenswert?

In meinem Programm verwende ich keine Timer.

Ich habe keine Kondensatoren verschalten.

Die Spannungsversorgung habe ich von einem normalen Netzteil. Einfach 
abgeschnitten & Krokodilklemmen drauf ^^

von Ryan P. (ryanpolster)


Lesenswert?

Ich programmiere auf dem STK500 unabhängig von der Schaltung.

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> In meinem Programm verwende ich keine Timer.

Dann lass mal eine LED blinken. Dann siehst du ob der Controller 
wirklich läuft.

von Ryan P. (ryanpolster)


Lesenswert?

Habe jetzt einen komplett neuen, noch nie benutzten ATMega16 genommen 
und ihm das Programm verpasst. Auch der geht nicht.

Ich versuche das mit der LED mal.

von Ryan P. (ryanpolster)


Lesenswert?

Ja der Controller läuft. Der gesamte PORTB funktioniert einwandfrei.
Habe es mit den LEDs vom STK500 probiert. Erwähnenswert ist nur das die 
invertiert sind.

von holger (Gast)


Lesenswert?

>Ein Foto der Schaltung habe ich grad nicht auf dem Rechner und finde es
>zu viel Arbeit eines zu machen und hochzuladen weil die Schaltung so
>trivial ist.

Ich bin dann mal raus. Bringt nichts mehr.

von Ronny S. (phoenix-0815)


Lesenswert?

Hallo,
hast es mal mit der Forum Suche versucht.

Beitrag "LCD - komme nicht weiter"

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> Habe es mit den LEDs vom STK500 probiert.

Das heißt aber nicht das es in deiner Schaltung auch funktioniert, bzw. 
der Controller läuft.

von Ryan P. (ryanpolster)


Lesenswert?

@holger: Ich habe versucht die Fotos direkt via Iphone hochzuladen. Das 
ging leider nicht. Da habe ich einfach die Verbindungen gepostet. Ob 
sich zwei Lötstellen berühren oder ob kalte Lötstellen vorhanden sind 
kann ich selbst nachsehen, hoffentlich ^^

von Ryan P. (ryanpolster)


Lesenswert?

@Hubert G.
Das verstehe ich nichts ganz. Wie werden denn dann die LEDs auf dem 
Board angesteuert wenn nicht vom µC?

von Hubert G. (hubertg)


Lesenswert?

Ryan Polster schrieb:
> Das verstehe ich nichts ganz. Wie werden denn dann die LEDs auf dem
> Board angesteuert wenn nicht vom µC?

Auf dem STK ist der Controller optimal versorgt.
Ob das in deiner Schaltung mit dem LCD auch so ist, bezweifle ich laut 
deinen Ausführungen ohne Kondensatoren, doch etwas.

von Ryan P. (ryanpolster)


Lesenswert?

Also so war das gemeint.

Die Initiative mit den Kondensatoren ergreife ich später.
Habe gerade beim Ausmessen bemerkt dass sich 3 Datenleitungen berührten.
Bin grad am Ausbessern.

Dieser große Fehler blieb unerkannt weil ich so eine Busleitung für die 
Daten genommen habe zwecks Übersichtlichkeit.

Falls das auch nicht funktioniert werde ich wohl ein paar Kondensatoren 
verschalten müssen.

Weißt du zufällig auch wo die überall hingehören?

von Uwe (Gast)


Lesenswert?

TaTa!

Ryan Polster schrieb:
> Weißt du zufällig auch wo die überall hingehören?

Steht in der AP zum Datenblatt des AVR und ja Stichwort - 
Stromversorgung, AVcc, Quarz Bürde usw.

von Mike (Gast)


Lesenswert?

Ryan Polster schrieb:
> Erwähnenswert ist nur das die invertiert sind.

Invertiert gegenüber was?
Hast du irgendeine Vorstellung wie die LEDs zum Leuchten angesteuert 
werden müssen und warum?

Ryan Polster schrieb:
> Weißt du zufällig auch wo die überall hingehören?

Guck dir einfach 100 Schaltungen mit 'nem ATmega16 an. Geh' davon aus, 
dass 30% ok sind und beim Rest kommt schnell das Gemecker über die 
Kondensatoren.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ryan Polster schrieb:
> Ich liste mal alle Verbindungen auf:
Mach das in einem Schaltplan. Damit unterhalten sich Elektroniker.

Hast du eigentlich schon mal eine LED zum Blinken gebracht? Und einen 
Taster eingelesen?

Ich frage mich immer: wie kommen die Leute auf die Idee, ohne jede 
Ahnung von der Materie gleich in der Oberliga spielen zu wollen?

Es ist nicht schwer, ein LCD anzusteuern. Nur muss man an irgendeiner 
Stelle dann selber anfangen zu Denken...

von Ryan P. (ryanpolster)


Lesenswert?

Problem gelöst.. In der Daten-Busleitung berührten sich 3 Leitungen.

von spess53 (Gast)


Lesenswert?

Hi

Deine Aussagen:

>Schaltungstechnische Fehler schließe ich aus, da ich ja nicht komplett
>inkompetent bin.
>Lötstellen berühren sich nirgends.

>Problem gelöst.. In der Daten-Busleitung berührten sich 3 Leitungen.

Mit deiner Inkompetenz hast du hier Völkerstämme beschäftigt.

MfG Spess

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.