LCD (HD44780) Amoklauf?

Gast #1281190
Lesenswert?

Hallo liebe Leute,

so... hier der 1000ste 44780-lcd-Beitrag : )

Ich mach's kurz:
Entwicklungsboard mikroelektronika easyavr5a
uc Atmega8
c mit winavr/gcc
2x16 LCD, Industriestandard
Leine Busy-Abfrage (RW nicht geroutet)
Verdrahtung fix, siehe header.

Hier der Header für die LCD-Funktionen:
1
/* lcd-routinen hd44780 4-bit */
2

3
#include <util/delay.h>
4
#include <inttypes.h>
5

6
#define _lcdport   PORTD
7
#define _lcddirection  DDRD
8
#define _rs    PD2
9
#define _en    PD3
10
#define _d4    PD4
11
#define _d5    PD5
12
#define _d6    PD6
13
#define _d7    PD7
14

15

16
void initlcd (void);
17
void lcden (void);
18
void lcdcom (uint8_t sendbyte);
19
void lcddata (uint8_t sendbyte);
20
void lcdstring (char *stringpointer);
21
char lcdcursor (uint8_t line, uint8_t column);
22

23
void initlcd (void) {
24
_delay_ms(20);
25
_delay_ms(20);
26
_delay_ms(20);
27
_delay_ms(20);
28
_delay_ms(20);
29

30
  _lcddirection|=(1<<_rs)|(1<<_en)|(1<<_d4)|(1<<_d5)|(1<<_d6)|(1<<_d7);
31
  _lcdport|=(1<<_d6)|(1<<_d7);  // init command 0x30
32
  lcden();
33
  _delay_ms(20);
34
  lcden();
35
  _delay_ms(20);
36
  lcden();
37
  _delay_ms(20);
38
  _lcdport=(1<<_d5);    // init command 0x20 4-bit-mode
39
  _delay_ms(20);
40
  lcdcom(0b00101000);
41
  lcdcom(0b00001100);
42
  lcdcom(0b00010100);
43
  lcdcom(0b00000110);
44
  lcdcom(0b00000001);
45
  lcdcom(2);
46
  _delay_ms(20);
47

48
  }
49
  
50
void lcden (void) {      // enable-pulse 
51
  _lcdport|=(1<<_en);
52
  _delay_ms(1);
53
  _lcdport&=~(1<<_en);
54
  _delay_ms(1);
55
  }
56
  
57
void lcdcom (uint8_t sendbyte) {
58
_lcdport=sendbyte;      // erst upper nibble
59
_lcdport=_lcdport&0xF0;      // mask lower nibble
60
lcden();        
61
sendbyte=sendbyte<<4;      // lower nibble hochschieben
62
_lcdport=sendbyte;          
63
_lcdport=_lcdport&0xF0;      // mask lower nibble    
64
lcden();
65
}
66

67
void lcddata (uint8_t sendbyte) {
68
_lcdport=sendbyte;      // erst upper nibble
69
_lcdport=_lcdport&0xF0;      // mask lower nibble
70
_lcdport|=(1<<_rs);      // rs setzen, daten
71
lcden();              
72
sendbyte=sendbyte<<4;      // lower nibble hochschieben
73
_lcdport=sendbyte;          
74
_lcdport=_lcdport&0xF0;      // mask lower nibble
75
_lcdport|=(1<<_rs);      // rs setzen, daten        
76
lcden();              
77
_lcdport&=~(1<<_rs);      // rs zurücksetzen
78

79

80
void lcdstring (char *stringpointer){
81
  while(*stringpointer)
82
    lcddata(*stringpointer++);
83
  }

Jetzt die Preisfrage:
Wenn ich den header includiere, die init gefolgt von einer Textausgabe 
aufrufe, passiert folgendes:
- Es werden je nach Text tlw. völlig sinnlose Zeichen ausgegeben. So 
führt zum Beispiel der String "Test" zur Ausgabe von "Test". Der String 
"KURTKROEMER" bringt aber "D_einhalb_U%". Mehr als vier Zeichen werde 
nie angezeigt. Selstamerweise verhält es sich bei einem Einzelnen 
Zeichen (gehen auch nich alle. "Q" z.B. geht) so, dass exakt jeder 
zweite Reset eine Ausgabe bringt. In den Resets dazwischen wird nichts 
angezeigt.
Hat jemand die Glaskugel gerade NICHT in reparatur und eine Idee?
Oder vielleicht zufällig gerade was in der Richtung aufgebaut, um den 
Code an einem Anderen Display zu testen?

Tausen Dank im Voraus,

Thomas
#1281212
Lesenswert?

Hallo,


void lcdcom (uint8_t sendbyte) {
_lcdport=sendbyte;      // erst upper nibble
_lcdport=_lcdport&0xF0;      // mask lower nibble
lcden();

Du schreibst hier sendbyte auf _lcdport.
Damit setzt Du aber je nach Inhalt der unteren 4 Bit sowohl RS als auch 
E auf irgendeinen Pegel...

Gruß aus Berlin
Michael
#1281241
Lesenswert?

Hallo,

Thomas schrieb:

> Hallo Micha,
>
> jau das ist klar, aber mach ja nix. Auf den unteren 4 Bit befinden sich
> ja nur noch RS (wird nach der Maskierung einzeln gesetzt) und EN.

wie verhält sich das Display, wenn unten bei
_lcdport=sendbyte;      // erst upper nibble

RS und E oder nur E zufällig auf H gesetzt werden und mit

_lcdport=_lcdport&0xF0;      // mask lower nibble

anschließend auf L?

Dann hast Du einen E-Impuls im falschen Mode erzeugt oder mit falschen 
Daten.
Anschließend machst Du den regulären E-Impuls und das Display liest die 
Datenbits nochmal als Data ein usw.

Gruß aus Berlin
Michael
Gast #1281243
Lesenswert?

So... nochmal drüber nachgedacht und zum Schluss gekommen, dass es wohl 
doch nicht ganz so egal ist.
Hier die bis hierhin korrigierte Version.
Init klappt jetzt immer (nicht nur bei jedem 2. Reset o.ä.), Ausgabe ist 
aber noch nicht Korrekt... Es wird immer das gleiche Zeichen bei einem 
String ausgegeben.
1
/* lcd-routinen hd44780 4-bit */
2

3
#include <util/delay.h>
4
#include <inttypes.h>
5

6
#define _lcdport     PORTD
7
#define _lcddirection  DDRD
8
#define _rs        PD2
9
#define _en        PD3
10
#define _d4        PD4
11
#define _d5        PD5
12
#define _d6        PD6
13
#define _d7        PD7
14

15

16
void initlcd (void);
17
void lcden (void);
18
void lcdcom (uint8_t sendbyte);
19
void lcddata (uint8_t sendbyte);
20
void lcdstring (char *stringpointer);
21
char lcdcursor (uint8_t line, uint8_t column);
22

23
void initlcd (void) {
24
_delay_ms(20);
25
_delay_ms(20);
26
_delay_ms(20);
27
_delay_ms(20);
28
_delay_ms(20);
29

30
  _lcddirection|=(1<<_rs)|(1<<_en)|(1<<_d4)|(1<<_d5)|(1<<_d6)|(1<<_d7);
31
  _lcdport=(0x30);  // init command 0x30
32
  lcden();
33
  _delay_ms(20);
34
  lcden();
35
  _delay_ms(20);
36
  lcden();
37
  _delay_ms(20);
38
  _lcdport=(0x20);  // init command 0x20 4-bit-mode
39
  _delay_ms(20);
40
  lcdcom(0b00101000);
41
  lcdcom(0b00001100);
42
  lcdcom(0b00010100);
43
  lcdcom(0b00000110);
44
  lcdcom(0b00000001);
45
  lcdcom(2);
46
  _delay_ms(20);
47

48
  }
49
  
50
void lcden (void) {    // enable-pulse 
51
  _lcdport|=(1<<_en);
52
  _delay_ms(1);
53
  _lcdport&=~(1<<_en);
54
  _delay_ms(1);
55
  }
56
  
57
void lcdcom (uint8_t sendbyte) {
58
sendbyte=sendbyte&0xF0;
59
_lcdport|=sendbyte;    // erst upper nibble
60
lcden();        
61
sendbyte=sendbyte<<4;
62
sendbyte=sendbyte&0xF0;    // lower nibble hochschieben
63
_lcdport|=sendbyte;    // mask lower nibble    
64
lcden();
65
}
66

67
void lcddata (uint8_t sendbyte) {
68
sendbyte=sendbyte&0xF0;
69
_lcdport|=sendbyte;    // erst upper nibble      
70
_lcdport|=(1<<_rs);    // rs setzen, daten
71
lcden();              
72
sendbyte=sendbyte<<4;
73
sendbyte=sendbyte&0xF0;    // lower nibble hochschieben
74
_lcdport|=sendbyte;              // mask lower nibble
75
_lcdport|=(1<<_rs);    // rs setzen, daten        
76
lcden();              
77
_lcdport&=~(1<<_rs);    // rs zurücksetzen
78
}
79

80
void lcdstring (char *stringpointer){
81
while(*stringpointer)
82
lcddata(*stringpointer++);
83
  }
#1281248
Lesenswert?

Hallo,

gerade Deine neue Version gesehen:

sendbyte=sendbyte&0xF0;
_lcdport|=sendbyte;    // erst upper nibble

Auch hier wieder: was ist, wenn das RS-Bit H ist bei Daten?

Nur Datenbits des Ports auf L setzen.
Daten in Hilfvariable an die passende Stelle legen, Steuerbits auf L 
setzen und mit dem Portinhalt vor-odern als Möglichkeit.

_lcdport &= 0x0F;
temp = sendbyte & 0xF0;
_lcdport |= temp;
lcden();
_lcdport &= 0x0F;
temp = (sendbyte<<4) & 0xF0;
_lcdport |= temp;
lcden();

sollte passen.

Gruß aus Berlin
Michael
Gast #1281255
Lesenswert?

Hm...
RS kann doch nach der verUNDung "&0xF02" gar nicht mehr H sein. Und wenn 
ich es für Daten brauche, setz ich es ja "manuell" in der nächsten Zeile 
mit |(1<<_RS).
Oder ich steh komplett auf dem Schlauch?

Ahoi,

Thomas
Gast #1281287
Lesenswert?

Wie erwartet : )

Ich bekomm beim compilieren von main.c (und natprlich lcd_drv.c) ne 
Fehlermeldung, mit der ich mal gar nichts anfangen kann.. voltile struct 
bits...

>Compiling C: lcd_drv.c
>avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char 
-funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes 
-Wa,-adhlns=./lcd_drv.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/lcd_drv.o.d 
lcd_drv.c -o lcd_drv.o
>lcd_drv.c:4:1: warning: "F_CPU" redefined
><command-line>: warning: this is the location of the previous definition
>lcd_drv.c: In function 'lcd_init':
>lcd_drv.c:60: error: 'volatile struct bits' has no member named 'b'
>make.exe: *** [lcd_drv.o] Error 1
#1281290
Lesenswert?

Thomas schrieb:
>>lcd_drv.c:4:1: warning: "F_CPU" redefined

Dann nimm eben eine Definition raus.

>>lcd_drv.c:60: error: 'volatile struct bits' has no member named 'b'
>>make.exe: *** [lcd_drv.o] Error 1

Dazu müßte man die Zeile 60 wissen.
Sende einfach mal den kompletten Code als Anhang.


Peter

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