Forum: Mikrocontroller und Digitale Elektronik 16x2 LCD nur eine Zeile mit Bitte den Code zu prüfen


von Tim (Gast)


Lesenswert?

Hallo zusammen,

warum zeigt das 16x2 Display nur eine, nämlich bei der oberen Zeilen die 
Buchstaben an?
1
#define F_CPU  4000000UL
2
#include <avr/delay.h>
3
4
#include <avr/io.h>
5
6
7
/*LCD function declarations */
8
void LCD_send_command(unsigned char cmnd);
9
void LCD_send_data(unsigned char data);
10
void LCD_init();
11
void LCD_goto(unsigned char y, unsigned char x);
12
void LCD_print(char *string);
13
void LCD_blink();
14
void LCD_scroll(unsigned char direction);
15
16
#define LCD_DATA_PORT PORTC
17
#define LCD_DATA_DDR  DDRC
18
#define LCD_DATA_PIN  PINC
19
20
#define LCD_CNTRL_PORT  PORTD
21
#define LCD_CNTRL_DDR  DDRD
22
#define LCD_CNTRL_PIN  PIND
23
24
#define LCD_RS_PIN    2
25
#define LCD_RW_PIN    3
26
#define LCD_ENABLE_PIN  4
27
28
int main(void)
29
{
30
  unsigned char i;
31
  
32
  LCD_init();
33
  LCD_goto(1,2);
34
  LCD_print("AVR TUTORIALS");
35
  LCD_goto(2,1);
36
  LCD_print("WELCOMES YOU");
37
  
38
    while(1)
39
    {/*
40
         for(i=0;i<2;i++)
41
         LCD_blink();
42
         
43
         for(i=0;i<2;i++)
44
         LCD_scroll(0);
45
         
46
         for(i=0;i<4;i++)
47
         LCD_scroll(1);
48
         
49
         for(i=0;i<2;i++)
50
         LCD_scroll(0);*/
51
    }
52
}
53
54
/* This function sends a command 'cmnd' to the LCD module*/
55
void LCD_send_command(unsigned char cmnd)
56
{
57
  LCD_DATA_PORT = cmnd;
58
  LCD_CNTRL_PORT &= ~(1<<LCD_RW_PIN);
59
  LCD_CNTRL_PORT &= ~(1<<LCD_RS_PIN);
60
  
61
  LCD_CNTRL_PORT |= (1<<LCD_ENABLE_PIN);
62
  _delay_us(2);
63
  LCD_CNTRL_PORT &= ~(1<<LCD_ENABLE_PIN);
64
  _delay_us(100);
65
}
66
67
/* This function sends the data 'data' to the LCD module*/
68
void LCD_send_data(unsigned char data)
69
{
70
  LCD_DATA_PORT = data;
71
  LCD_CNTRL_PORT &= ~(1<<LCD_RW_PIN);
72
  LCD_CNTRL_PORT |= (1<<LCD_RS_PIN);
73
  
74
  LCD_CNTRL_PORT |= (1<<LCD_ENABLE_PIN);
75
  _delay_us(2);
76
  LCD_CNTRL_PORT &= ~(1<<LCD_ENABLE_PIN);
77
  _delay_us(100);
78
}
79
80
void LCD_init()
81
{
82
  LCD_CNTRL_DDR = 0xFF;
83
  LCD_CNTRL_PORT = 0x00;
84
  LCD_DATA_DDR = 0xFF;
85
  LCD_DATA_PORT = 0x00;
86
  
87
  _delay_ms(10);
88
  LCD_send_command(0x38);
89
  LCD_send_command(0x0C);
90
  LCD_send_command(0x01);
91
  _delay_ms(10);
92
  LCD_send_command(0x06);
93
}
94
95
/* This function moves the cursor the line y column x on the LCD module*/
96
void LCD_goto(unsigned char y, unsigned char x)
97
{
98
  unsigned char firstAddress[] = {0x80,0xC0,0x94,0xD4};
99
  
100
  LCD_send_command(firstAddress[y-1] + x-1);
101
  _delay_ms(10);
102
}
103
104
void LCD_print(char *string)
105
{
106
  unsigned char i;
107
  
108
  while(string[i]!=0)
109
  {
110
    LCD_send_data(string[i]);
111
    i++;
112
  }
113
}
114
115
void LCD_blink()
116
{
117
  LCD_send_command(0x08);
118
  _delay_ms(250);
119
  LCD_send_command(0x0C);
120
  _delay_ms(250);
121
}
122
123
void LCD_scroll(unsigned char direction)
124
{
125
  if(direction == 0)
126
  LCD_send_command(0x18);
127
  else
128
  LCD_send_command(0x1C);
129
  
130
  _delay_ms(500);
131
}

Kann mir jemand sagen wo der Fehler ist?

Dank

Tim

von Karl H. (kbuchegg)


Lesenswert?

Tim schrieb:

> warum zeigt das 16x2 Display nur eine, nämlich bei der oberen Zeilen die
> Buchstaben an?

Weil diese Schreibweise
1
  LCD_send_command(0x38);
2
  LCD_send_command(0x0C);
3
  LCD_send_command(0x01);
scheisse ist.
Jetzt heisst es wieder Datenblatt bzw. die LCD Kommandos studieren um 
rauszufinden welches das Kommando ist, mit dem eigentlich dem LCD 
mitgeteilt wird, dass es auf 2 Zeilen schalten soll und um rauszufinden 
ob das passiert ist oder nicht.

von Tim (Gast)


Lesenswert?

Darf ich fragen, wie die gute Programmierung aussieht?

speziell nur mal die 3 Zeilen.

Danke

von Karl H. (kbuchegg)


Lesenswert?

So zum Beispiel
1
...
2
 
3
    // 4-bit Modus / 2 Zeilen / 5x7
4
    lcd_command( LCD_SET_FUNCTION |
5
                 LCD_FUNCTION_4BIT |
6
                 LCD_FUNCTION_2LINE |
7
                 LCD_FUNCTION_5X7 );
8
...

Quelle:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung

Kann natürlich sein, dass du 2 Zeilen aktivierst und ganz einfach nur 
die Konstanten für den Zeilenversatz in der Cursorpositionierung falsch 
sind. Kann alles sein. Aber ohne die Bits in
1
  LCD_send_command(0x38);
2
  LCD_send_command(0x0C);
3
  LCD_send_command(0x01);
in ihre Bedeutung aufzudröseln, werden wir es nie erfahren.

von John (Gast)


Angehängte Dateien:

Lesenswert?

Karl Heinz schrieb:
> Kann alles sein. Aber ohne die Bits in
>   LCD_send_command(0x38);
>   LCD_send_command(0x0C);
>   LCD_send_command(0x01);
> in ihre Bedeutung aufzudröseln, werden wir es nie erfahren.

Man könnte auch einfach die HEX-Werte in das Hex-Feld im LCD Simulator 
eingeben. Und schon wird in der Tip-Box angezeigt was der Befehl macht. 
Für Befehle muss R/W und RS low sein (Grundeinstellung vom Simulator).
Nach zwei Klicks auf die Schaltfläche unter den E (-> Enabel high -> 
Enable low), wird der Befehl im Simulator ausgeführt.

LCD Simulator:
http://www.dinceraydin.com/djlcdsim/djlcdsim.html

Gruß
John

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.