Forum: Mikrocontroller und Digitale Elektronik LCD ansteuerung mit einem ATMega16 und I2C


von arget (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Ich habe hier auf mikrocontroller.net die Beschreibung zur ansteuerung 
für LCD Bildschirme gelesen und möchte nun einen solchen mithilfe eines 
MCP23017 (I2C GPIO erweiterung) ansteuern. Hierfür habe ich die Library 
die hich hier gefunden habe verwendet und sie erweitert. Jedoch scheine 
ich bereits beim initialiesieren einen Fehler zu haben da nur schwarze 
Balken angezeigt werden. Die Schaltung ist als Anhang zu finden, ich 
verwende das Panelolu2 von meinem 3D Drucker! Zum Display selber kann 
ich sagen das er funktioniert, da er mit dem Arduino und der 
dazugehörigen Software für den 3D Drucker ohne Probleme funktioniert.

Da es anscheinend nur möglich ist Bilder als Anhang zu posten ist hier 
der Code den ich zum ansprechen des Displays verwende.

lcd-routines.h
1
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
2
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
3
//
4
5
#ifndef LCD_ROUTINES_H
6
#define LCD_ROUTINES_H
7
8
////////////////////////////////////////////////////////////////////////////////
9
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!
10
11
#ifndef F_CPU
12
#define F_CPU 15000000UL
13
#endif
14
15
////////////////////////////////////////////////////////////////////////////////
16
// Pinbelegung für das LCD, an verwendete Pins anpassen
17
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
18
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen
19
20
//Adresse des Slave Devices MCP23017
21
//Die ersten 4 Bit sind laut Datenblatt definiert(0100)
22
//Die letzten 3 Bit werden über die Pins A0-A2 definiert
23
#define  SLAVE 0b0100000
24
25
//  LCD DB4-DB7 <-->  PORTB an MCP23017 Bit GPB1-GPB4
26
#define LCD_PORT      0x13 //GPIOB Register Addresse des MCP23017
27
#define LCD_DDR       0x01 // IODIRB Register addresse des MCP23017
28
#define LCD_DB        1 // GPB1 
29
30
//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
31
#define LCD_RS        7
32
33
//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
34
#define LCD_EN        5
35
36
////////////////////////////////////////////////////////////////////////////////
37
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)
38
39
#define LCD_BOOTUP_MS           15
40
#define LCD_ENABLE_US           20
41
#define LCD_WRITEDATA_US        46
42
#define LCD_COMMAND_US          42
43
44
#define LCD_SOFT_RESET_MS1      5
45
#define LCD_SOFT_RESET_MS2      1
46
#define LCD_SOFT_RESET_MS3      1
47
#define LCD_SET_4BITMODE_MS     5
48
49
#define LCD_CLEAR_DISPLAY_MS    2
50
#define LCD_CURSOR_HOME_MS      2
51
52
////////////////////////////////////////////////////////////////////////////////
53
// Zeilendefinitionen des verwendeten LCD
54
// Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 Zeichen passen
55
// Bei anderen Zeilenlängen müssen diese Einträge angepasst werden
56
57
#define LCD_DDADR_LINE1         0x00
58
#define LCD_DDADR_LINE2         0x40
59
#define LCD_DDADR_LINE3         0x14
60
#define LCD_DDADR_LINE4         0x54
61
62
uint_fast8_t _data;
63
uint_fast8_t _ddr;
64
uint_fast8_t _port;
65
static const unsigned char BitReverseTable16[] =
66
{
67
  0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F
68
};
69
////////////////////////////////////////////////////////////////////////////////
70
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
71
void lcd_init( void );
72
73
////////////////////////////////////////////////////////////////////////////////
74
// LCD löschen
75
void lcd_clear( void );
76
77
////////////////////////////////////////////////////////////////////////////////
78
// Cursor in die 1. Zeile, 0-te Spalte
79
void lcd_home( void );
80
81
////////////////////////////////////////////////////////////////////////////////
82
// Cursor an eine beliebige Position
83
void lcd_setcursor( uint8_t spalte, uint8_t zeile );
84
85
////////////////////////////////////////////////////////////////////////////////
86
// Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition
87
void lcd_data( uint8_t data );
88
89
////////////////////////////////////////////////////////////////////////////////
90
// Ausgabe eines Strings an der aktuellen Cursorposition
91
void lcd_string( const char *data );
92
93
////////////////////////////////////////////////////////////////////////////////
94
// Definition eines benutzerdefinierten Sonderzeichens.
95
// data muss auf ein Array[8] mit den Zeilencodes des zu definierenden Zeichens
96
// zeigen
97
void lcd_generatechar( uint8_t code, const uint8_t *data );
98
99
////////////////////////////////////////////////////////////////////////////////
100
//Schreiben eines Registers des MCP23017
101
void writeOut(uint8_t reg, uint_fast8_t value);
102
103
////////////////////////////////////////////////////////////////////////////////
104
// Ausgabe eines Kommandos an das LCD.
105
void lcd_command( uint8_t data );
106
107
108
109
110
111
////////////////////////////////////////////////////////////////////////////////
112
// LCD Befehle und Argumente.
113
// Zur Verwendung in lcd_command
114
115
// Clear Display -------------- 0b00000001
116
#define LCD_CLEAR_DISPLAY       0x01
117
118
// Cursor Home ---------------- 0b0000001x
119
#define LCD_CURSOR_HOME         0x02
120
121
// Set Entry Mode ------------- 0b000001xx
122
#define LCD_SET_ENTRY           0x04
123
124
#define LCD_ENTRY_DECREASE      0x00
125
#define LCD_ENTRY_INCREASE      0x02
126
#define LCD_ENTRY_NOSHIFT       0x00
127
#define LCD_ENTRY_SHIFT         0x01
128
129
// Set Display ---------------- 0b00001xxx
130
#define LCD_SET_DISPLAY         0x08
131
132
#define LCD_DISPLAY_OFF         0x00
133
#define LCD_DISPLAY_ON          0x04
134
#define LCD_CURSOR_OFF          0x00
135
#define LCD_CURSOR_ON           0x02
136
#define LCD_BLINKING_OFF        0x00
137
#define LCD_BLINKING_ON         0x01
138
139
// Set Shift ------------------ 0b0001xxxx
140
#define LCD_SET_SHIFT           0x10
141
142
#define LCD_CURSOR_MOVE         0x00
143
#define LCD_DISPLAY_SHIFT       0x08
144
#define LCD_SHIFT_LEFT          0x00
145
#define LCD_SHIFT_RIGHT         0x04
146
147
// Set Function --------------- 0b001xxxxx
148
#define LCD_SET_FUNCTION        0x20
149
150
#define LCD_FUNCTION_4BIT       0x00
151
#define LCD_FUNCTION_8BIT       0x10
152
#define LCD_FUNCTION_1LINE      0x00
153
#define LCD_FUNCTION_2LINE      0x08
154
#define LCD_FUNCTION_5x8    0x04
155
#define LCD_FUNCTION_5x11    0x00
156
157
#define LCD_SOFT_RESET          0x30
158
159
// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)
160
#define LCD_SET_CGADR           0x40
161
162
#define LCD_GC_CHAR0            0
163
#define LCD_GC_CHAR1            1
164
#define LCD_GC_CHAR2            2
165
#define LCD_GC_CHAR3            3
166
#define LCD_GC_CHAR4            4
167
#define LCD_GC_CHAR5            5
168
#define LCD_GC_CHAR6            6
169
#define LCD_GC_CHAR7            7
170
171
// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)
172
#define LCD_SET_DDADR           0x80
173
174
#endif

lcd-routines.c
1
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
2
// http://www.mikrocontroller.net/articles/HD44780
3
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
4
//
5
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar
6
7
#include <avr/io.h>
8
#include "lcd-routines.h"
9
#include "TWI_Master.h"
10
#include <util/delay.h>
11
12
////////////////////////////////////////////////////////////////////////////////
13
// Erzeugt einen Enable-Puls
14
static void lcd_enable( void )
15
{
16
  //Enable auf 1 setzen
17
  _data |= (1<<LCD_EN);
18
  writeOut(LCD_PORT, _data);
19
  //kurze Pause
20
  _delay_us( LCD_ENABLE_US );  // kurze Pause
21
  
22
  //Enable auf 0 setzen
23
  _data &= ~(1<<LCD_EN);
24
  writeOut(LCD_PORT, _data);
25
}
26
27
////////////////////////////////////////////////////////////////////////////////
28
// Sendet eine 4-bit Ausgabeoperation an das LCD
29
static void lcd_out( uint8_t data )
30
{
31
  data &= 0xF0;
32
  data = data >> 4;
33
  data = BitReverseTable16[data];
34
     data = data << 4; 
35
  
36
  _data &= ~(0xF0 >> (4-LCD_DB));
37
  writeOut(LCD_PORT, _data);
38
  
39
  _data |= (data>>(4-LCD_DB));
40
  writeOut(LCD_PORT, _data);
41
  
42
  lcd_enable();
43
}
44
45
////////////////////////////////////////////////////////////////////////////////
46
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
47
void lcd_init( void )
48
{
49
  _data = 0x01; // 0b00000001 schaltet LED des Panelolu 2 aus
50
  
51
  _ddr = 0b00000000;
52
  _port = 0x00;
53
  
54
  writeOut(LCD_DDR, _ddr);//Alle benötigten Pins als Ausgang definieren
55
  
56
  writeOut(LCD_PORT, _port);//Alle Ausgänge auf 0 setzen
57
  
58
  // warten auf die Bereitschaft des LCD
59
  _delay_ms( LCD_BOOTUP_MS );  
60
  
61
  // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
62
  _data = LCD_SOFT_RESET;
63
  lcd_out( _data );
64
  _delay_ms( LCD_SOFT_RESET_MS1 );
65
  
66
  lcd_enable();
67
  _delay_ms( LCD_SOFT_RESET_MS2 );
68
  
69
  lcd_enable();
70
  _delay_ms( LCD_SOFT_RESET_MS3 );
71
  
72
  // 4-bit Modus aktivieren
73
  _data = (LCD_SET_FUNCTION |  LCD_FUNCTION_4BIT);
74
  lcd_out( _data );
75
  _delay_ms( LCD_SET_4BITMODE_MS );
76
  
77
  // 4-bit Modus / 2 Zeilen / 5x7
78
  _data = (LCD_SET_FUNCTION |  LCD_FUNCTION_4BIT |  LCD_FUNCTION_2LINE |LCD_FUNCTION_5x8);
79
  lcd_command( _data);
80
  
81
  // Display ein / Cursor aus / Blinken aus
82
  _data = (LCD_SET_DISPLAY |LCD_DISPLAY_ON |LCD_CURSOR_OFF |LCD_BLINKING_OFF);
83
  lcd_command( _data );
84
  
85
  // Cursor inkrement / kein Scrollen
86
  _data = ( LCD_SET_ENTRY |LCD_ENTRY_INCREASE |LCD_ENTRY_NOSHIFT);
87
  lcd_command(_data);
88
  
89
  lcd_clear();  
90
}
91
92
////////////////////////////////////////////////////////////////////////////////
93
// Sendet ein Datenbyte an das LCD
94
void lcd_data( uint8_t data )
95
{
96
  _port |= (1<<LCD_RS);
97
  
98
  writeOut(LCD_PORT, _port);
99
  
100
  lcd_out( data );            // zuerst die oberen,
101
  lcd_out( data<<4 );         // dann die unteren 4 Bit senden
102
  
103
  _delay_us( LCD_WRITEDATA_US );
104
}
105
106
////////////////////////////////////////////////////////////////////////////////
107
// Sendet einen Befehl an das LCD
108
void lcd_command( uint8_t data )
109
{
110
  _port &= ~(1<<LCD_RS);
111
  writeOut(LCD_PORT, _port);
112
  
113
  lcd_out( data );             // zuerst die oberen,
114
  lcd_out( data<<4 );           // dann die unteren 4 Bit senden
115
  
116
  _delay_us( LCD_COMMAND_US );
117
}
118
119
////////////////////////////////////////////////////////////////////////////////
120
// Sendet den Befehl zur Löschung des Displays
121
void lcd_clear( void )
122
{
123
  lcd_command( LCD_CLEAR_DISPLAY );
124
  _delay_ms( LCD_CLEAR_DISPLAY_MS );
125
}
126
127
////////////////////////////////////////////////////////////////////////////////
128
// Sendet den Befehl: Cursor Home
129
void lcd_home( void )
130
{
131
  lcd_command( LCD_CURSOR_HOME );
132
  _delay_ms( LCD_CURSOR_HOME_MS );
133
}
134
135
////////////////////////////////////////////////////////////////////////////////
136
// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4)
137
138
void lcd_setcursor( uint8_t x, uint8_t y )
139
{
140
  uint8_t data;
141
  
142
  switch (y)
143
  {
144
    case 1:    // 1. Zeile
145
    data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
146
    break;
147
    
148
    case 2:    // 2. Zeile
149
    data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
150
    break;
151
    
152
    case 3:    // 3. Zeile
153
    data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
154
    break;
155
    
156
    case 4:    // 4. Zeile
157
    data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
158
    break;
159
    
160
    default:
161
    return;                                   // für den Fall einer falschen Zeile
162
  }
163
  
164
  lcd_command( data );
165
}
166
167
////////////////////////////////////////////////////////////////////////////////
168
// Schreibt einen String auf das LCD
169
170
void lcd_string( const char *data )
171
{
172
  while( *data != '\0' )
173
  lcd_data( *data++ );
174
}
175
176
////////////////////////////////////////////////////////////////////////////////
177
// Schreibt ein Zeichen in den Character Generator RAM
178
179
void lcd_generatechar( uint8_t code, const uint8_t *data )
180
{
181
  // Startposition des Zeichens einstellen
182
  lcd_command( LCD_SET_CGADR | (code<<3) );
183
  
184
  // Bitmuster übertragen
185
  for ( uint8_t i=0; i<8; i++ )
186
  {
187
    lcd_data( data[i] );
188
}
189
}
190
191
void writeOut(uint8_t reg, uint_fast8_t value)
192
{  
193
  if(!TWIM_Start(SLAVE, TWIM_WRITE))
194
  {
195
    TWIM_Stop();
196
  }
197
  else
198
  {
199
    TWIM_Write(reg);
200
    TWIM_Write(value);
201
    TWIM_Stop();
202
  }
203
}

Hoffentlich kann mir jemand helfen!
mit freundlichen Grüßen
Markus

von Schlaumeier (Gast)


Angehängte Dateien:

Lesenswert?

Man kann auch C-Dateien anhängen. Hat den Vorteil, dass es eine echte 
Codeansicht gibt.

von Schlaumeier (Gast)


Angehängte Dateien:

Lesenswert?

und ... (geht auch beides gleichzeitig)

von arget (Gast)


Lesenswert?

Danke, hat bei mir nicht funktioniert, habe immer die Meldung bekommen 
das es eine PNG oder JPG datei sein muss :/

von Mitlesa (Gast)


Lesenswert?

arget schrieb:
> habe immer die Meldung bekommen
> das es eine PNG oder JPG datei sein muss

Von einer Einschränkung des Uploads auf Grafik-Dateien ist nicht die 
Rede.

Auch ist es immer hilfreich sich den Hinweistext durchzulesen
und zu verstehen

----------------------------------------------
Formatierung (mehr Informationen...)
1
[c]C-Code[/c]
2
[avrasm]AVR-Assembler-Code[/avrasm]
3
[code]Code in anderen Sprachen, ASCII-Zeichnungen
4
[math]Formel in LaTeX-Syntax[/math]
5
[[Titel]] - Link zu Artikel
----------------------------------------------

von Forist (Gast)


Lesenswert?

arget schrieb:
> Danke, hat bei mir nicht funktioniert, habe immer die Meldung bekommen
> das es eine PNG oder JPG datei sein muss :/

Dann lies den Text mal genau.

von Schlaumeier (Gast)


Lesenswert?

arget schrieb:
> Jedoch scheine
> ich bereits beim initialiesieren einen Fehler zu haben da nur schwarze
> Balken angezeigt werden.

Am Kontrastregler hast Du mal gedreht?

von arget (Gast)


Lesenswert?

Ja habe ich. Am Kontrast liegt es nicht, ich habe versucht verschiedene 
Sachen auszugeben und dann denn Kontrast neu einzustellen aber das hat 
auch nichts gebracht

von Schlaumeier (Gast)


Lesenswert?

Ich bin kein Programmierprofi, aber bei der Pinzuordnung stimmt was 
nicht. E und RS liegen lt. Schaltplan auch auf PortB des MCP23017.
1
//  LCD DB4-DB7 <-->  PORTB an MCP23017 Bit GPB1-GPB4
2
#define LCD_PORT      0x13 //GPIOB Register Addresse des MCP23017
3
#define LCD_DDR       0x01 // IODIRB Register addresse des MCP23017
4
#define LCD_DB        1 // GPB1 
5
6
//  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
7
#define LCD_RS        7
8
9
//  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
10
#define LCD_EN        5

von Schlaumeier (Gast)


Lesenswert?

Ah, ok, da ist nur der Kommentar falsch
1
//Enable auf 1 setzen
2
  _data |= (1<<LCD_EN);
3
  writeOut(LCD_PORT, _data);

von arget (Gast)


Lesenswert?

Schlaumeier schrieb:
> Ich bin kein Programmierprofi, aber bei der Pinzuordnung stimmt
> was
> nicht. E und RS liegen lt. Schaltplan auch auf PortB des MCP23017.
> //  LCD DB4-DB7 <-->  PORTB an MCP23017 Bit GPB1-GPB4
> #define LCD_PORT      0x13 //GPIOB Register Addresse des MCP23017
> #define LCD_DDR       0x01 // IODIRB Register addresse des MCP23017
> #define LCD_DB        1 // GPB1
>
> //  LCD RS      <-->  PORTD Bit PD4     (RS: 1=Data, 0=Command)
> #define LCD_RS        7
>
> //  LCD EN      <-->  PORTD Bit PD5     (EN: 1-Impuls für Daten)
> #define LCD_EN        5

Ja das stimmt, die Kommentaren sind noch vom Originalfile, RS liegt am 
Pin 7 des PORTB and und EN an Pin 5 des PORTB. Demnach sollten die 
definitionen stimmen

von Schlaumeier (Gast)


Lesenswert?

Taktfrequenz 15 MHz stimmt?

von arget (Gast)


Lesenswert?

Ja ich verwende für den Mega16 einen externen 15MHz Quarz

von Schlaumeier (Gast)


Lesenswert?

Zeig mal bitte Dein vollständiges Test-Programm, denn das sehen wir 
bisher noch nicht.

von arget (Gast)


Angehängte Dateien:

Lesenswert?

Hier bitte

von Schlaumeier (Gast)


Lesenswert?

lcd_clear nach lcd_init ist überflüssig, weil lcd_init das mitmacht, 
aber das ist nicht das Problem.
1
lcd_init();
2
lcd_clear();

Kannst Du mit Oszi, Logikanalysator oder ähnlichem nachgucken, ob auf 
dem TWI/i2c was passiert?

Ich kenne den MCP23017 nicht. Stimmt die Adresse und die Ansprache gemäß 
Beschaltung und Datenblatt?

Kannst Du ein kleines Testprogramm schreiben, das nur die LED auf PortB 
des MCP23017 blinken läßt? Dann könnte man sicherstellen, dass i2c 
funktioniert.

von arget (Gast)


Lesenswert?

Also die Kommunikation funktioniert, die LED am PORT B0 kann ich blinken 
lassen!

von Schlaumeier (Gast)


Lesenswert?

Beschaltung geprüft? Fuses stimmen auch?

Dann bin ich mit meinem Latein am Ende. Vielleicht sieht jemand anders 
mehr.

von Schlaumeier (Gast)


Lesenswert?

Schlaumeier schrieb:
> Beschaltung geprüft?

Quatsch, ist ja eine fertige Platine ...

von arget (Gast)


Lesenswert?

Ja die Fuses stimmen auch, habe jz einen Fehler gefunden, ich muss bei 
lcd_out() die gedrehten Bits auch schreiben, dass habe ich nicht getan 
die funktion muss wie folgt aussehen:
1
static void lcd_out( uint8_t data )
2
{
3
  data &= 0xF0;
4
  data = data >> 4;
5
  data = BitReverseTable16[data];
6
     _data = data << 4; 
7
  
8
  _data &= ~(0xF0 >> (4-LCD_DB));
9
  _data |= (0b00000001);
10
  writeOut(LCD_PORT, _data);
11
  
12
  _data |= (data>>(4-LCD_DB));
13
  _data |= (0b00000001);
14
  writeOut(LCD_PORT, _data);
15
  
16
  lcd_enable();
17
}

Jetz wird mir etwas angezeigt, jedoch nur sehr komische zeichen!

von holger (Gast)


Lesenswert?

Versuch das mal so:
1
////////////////////////////////////////////////////////////////////////////////
2
// Sendet eine 4-bit Ausgabeoperation an das LCD
3
static void lcd_out( uint8_t data )
4
{
5
  data = data >> 4;
6
  data = BitReverseTable16[data];
7
     _data = data << 4; 
8
  
9
  _data = (_data>>(4-LCD_DB));
10
  _data |= (0b00000001);
11
  writeOut(LCD_PORT, _data);
12
  
13
  lcd_enable();
14
}

von arget (Gast)


Lesenswert?

holger schrieb:
> Versuch das mal so:
> //////////////////////////////////////////////////////////////////////// 
////////
> // Sendet eine 4-bit Ausgabeoperation an das LCD
> static void lcd_out( uint8_t data )
> {
>   data = data >> 4;
>   data = BitReverseTable16[data];
>      _data = data << 4;
>
>   _data = (_data>>(4-LCD_DB));
>   _data |= (0b00000001);
>   writeOut(LCD_PORT, _data);
>
>   lcd_enable();
> }

Mit dem Code scheint die Initialisierung zwar zu funktionieren, jedoch 
bekomme ich nichts angezeigt

von arget (Gast)


Lesenswert?

Ok der Code zeigt mir doch etwas an aber nur die selben komischen 
Symbole wie vorher

von Schlaumeier (Gast)


Lesenswert?

arget schrieb:
> Ok der Code zeigt mir doch etwas an aber nur die selben komischen
> Symbole wie vorher

Zuordnung der Datenbits überprüfen ...

von arget (Gast)


Lesenswert?

Schlaumeier schrieb:
> arget schrieb:
>> Ok der Code zeigt mir doch etwas an aber nur die selben komischen
>> Symbole wie vorher
>
> Zuordnung der Datenbits überprüfen ...

Wie kann ich die überprüfen ohne Logicanalyzer?

von Schlaumeier (Gast)


Lesenswert?

Wirre Zeichen sind bei normalem Anschluss (also ohne i2c) meist ein 
Indiz für Vertauschung der Datenleitungen o. ä., deswegen war das mein 
erster Impuls.

Ist die Reihenfolge Highnibble, lownibble so, wie es das LCD erwartet? 
Ich hab jetzt nicht geguckt, wie Du das machst.

von holger (Gast)


Lesenswert?

>Ok der Code zeigt mir doch etwas an aber nur die selben komischen
>Symbole wie vorher

Dss liegt daran das dir z.B. RS kaputt gemacht wird.
Du musst bei jedem  writeOut(LCD_PORT, _data);
darauf achten das alle Bits in _data gültig sind.
Also auch RS, E, RW.

von arget (Gast)


Lesenswert?

holger schrieb:
>>Ok der Code zeigt mir doch etwas an aber nur die selben komischen
>>Symbole wie vorher
>
> Dss liegt daran das dir z.B. RS kaputt gemacht wird.
> Du musst bei jedem  writeOut(LCD_PORT, _data);
> darauf achten das alle Bits in _data gültig sind.
> Also auch RS, E, RW.

Soll heißen, RS, E und RW müssen 0 sein?

von holger (Gast)


Lesenswert?

>Soll heißen, RS, E und RW müssen 0 sein?

Die müssen so stehen wie sie stehen müssen.
void lcd_out( uint8_t data ) berücksichtigt den Zustand
von RS nicht. Es ist immer 0 und deshalb kannst du
keine Zeichen schreiben.

Du kannst immer nur alle 8 Bits gleichzeitig schreiben.
Daran musst du denken wenn du den Port beschreibst.
Also sieh zu das auch die Steuerleitungen in lcd_out()
richtig gesetzt bleiben.

von arget (Gast)


Lesenswert?

Ok ich verstehe auf was du hinauswillst, ich habe jetzt die Funktion so 
umgeschrieben das wirklich nur die 4 Datenbits umgeschrieben werden die 
ich benötige und die restlichen Bits unbeeinflusst von dem 
schreibvorgang selbst sind. Die Funktion sieht jz so aus:
1
static void lcd_out( uint8_t data )
2
{
3
  data &= 0xF0;
4
  data = data >> 4;
5
  data = (BitReverseTable16[(data>>4)] << 4);
6
  
7
  _data &= ~(0xF0 >> (4-LCD_DB));
8
  writeOut(LCD_PORT, _data);
9
  
10
  _data |= (data>>(4-LCD_DB));
11
  writeOut(LCD_PORT, _data);
12
  
13
  lcd_enable();
14
}

Nun sollten die Bits passen da RS und E je nachdem wo die Funktion 
aufgerufen wird vorher oder nachher gesetzt/gelöscht werden.

Die ausgabe hat sich nicht geändert obwohl sie die richtigen Bits 
eigentlich jz nur verändern sollte

von holger (Gast)


Lesenswert?

>Nun sollten die Bits passen da RS und E je nachdem wo die Funktion
>aufgerufen wird vorher oder nachher gesetzt/gelöscht werden.

Ja, die alte Routine hatte doch Sinn.
Dummerweise setzt du RS in _port und nicht in _data;)

von arget (Gast)


Lesenswert?

holger schrieb:
>>Nun sollten die Bits passen da RS und E je nachdem wo die
> Funktion
>>aufgerufen wird vorher oder nachher gesetzt/gelöscht werden.
>
> Ja, die alte Routine hatte doch Sinn.
> Dummerweise setzt du RS in _port und nicht in _data;)

ja das habe ich auch schon gesehen, die Variable _port gibt es nicht 
mehr ich habe sie entfernt und alles durch _data ersetzt, somit habe ich 
den Zustand des Registers immer in der Variable _data drinnen

von arget (Gast)


Angehängte Dateien:

Lesenswert?

Danke an alle die mir geholfen haben, habe den Fehler nun gefunden. Ich 
habe in der Funktion lcd_out zweimal das Byte um 4 Bit nach links 
verschoben somit wurde das ganze byte gelöscht, nun funktioniert es! 
Falls jemand an den Dateien interessiert sein sollte, findet ihr diese 
im Anhang

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.