20x4 lcd zeigt immer das gleiche an

OP #3615067
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 ^^
Angehängte Dateien:
#3615075
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
#3615080
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?
Gast #3615082
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
#3615099
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);
OP #3615114
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? ^^
OP #3615120
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
}
OP #3615134
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
}
OP #3616527
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?
#3616578
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?
#3616598
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.
#3616609
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.
OP #3616628
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.
OP #3616660
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
#3616663
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.
#3616711
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)
#3616985
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.
OP #3617007
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?
Angehängte Dateien:
Gast #3617021
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.
#3617055
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.
Gast #3617112
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.
#3617130
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.
OP #3617131
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.
OP #3617151
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
Gast #3617190
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.
OP #3617344
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?
Gast #3617364
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.
Moderator (Firma: Titel) Persönliche Seite #3617392
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...
Gast #3617449
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

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