Forum: Mikrocontroller und Digitale Elektronik GLCD (HD61830) am Mega32


von Martin (Gast)


Lesenswert?

hallo allerseits.
ich habe mir ein glcd mit HD61830 Controller (Datenblatt: 
http://www.mikrocontroller.net/attachment/27964/hd61830.pdf ) 
ersteigert. hier im forum gabs schonmal einen beitrag zu dem thema, mit 
codeschnippsel. ich hab den code fast 1:1 übernommen. bei mir kommen 
aber komische sachen bei raus.
der text, den ich mit lcd_puts ausgebe soll natürlich nur 1 mal in der 
ersten zeile erscheinen. er erscheint aber in jeder zeile, also 12 mal- 
woran kann das liegen ?? das datenblatt hab ich schon einige male 
durchkämmt, ich finde keinen hinweis, vllt hab ich auch einfach ein 
brett vorm kopf ... kann mir jemand helfen ?
1
#define DATAPORT  PORTC
2
#define DATADDR    DDRC
3
#define DATAPIN    PINC
4
#define CTRLPORT  PORTB
5
#define CTRLDDR    DDRB
6
#define RS      0
7
#define RW      1
8
#define E      2
9
#define CS      3
10
#define F_CPU    12000000
11
12
#include <incl/delay.h>
13
#include <util/delay.h>
14
#include <stdint.h>
15
#include <avr/io.h>
16
17
void lcd_enable(void){
18
  // Erzeugt eine fallende Flanke am Enable-Pin
19
20
  CTRLPORT |= (1<<E);
21
  _delay_us(2);
22
  CTRLPORT &= ~(1<<E);
23
  _delay_us(2);
24
}
25
26
void lcd_busy(void) {
27
  // Wartet bis der Controller wieder Daten verarbeiten kann
28
 
29
  unsigned char tmp;
30
 
31
  DATAPORT = 0x00;      // Datenport wird gelöscht
32
  DATADDR = 0x00;        // Datenport wird als Eingang deklariert
33
34
  CTRLPORT |= (1<<RW);    // R/W auf logisch 1 -> R 
35
  CTRLPORT |= (1<<RS);    // RS auf logisch 1 -> aktiv
36
  
37
  do{
38
    CTRLPORT |= (1<<E);  // Steigende Flanke am Enable-Pin
39
    _delay_us(2);
40
    tmp = DATAPIN;      // Datenport wird eingelesen
41
    CTRLPORT &= ~(1<<E);  // Fallende Flanke am Enable-Pin
42
    _delay_us(2);
43
  }while(tmp & (1<<7));    // Schleife bis Busy Flag logisch 0 wird
44
  
45
  DATADDR = 0xff;        // Datenport wird wieder als Ausgang deklariert
46
}
47
 
48
void lcd_writecommand(uint8_t command) {
49
  // Kommandobyte -> HD61830
50
 
51
  lcd_busy();
52
  CTRLPORT &= ~(1<<RW);    // R/W auf logisch 0 -> W 
53
  CTRLPORT |= (1<<RS);    // RS auf logisch 1 -> aktiv
54
  DATAPORT = command;      // übergebenes Kommandobyte wird ausgegeben
55
  lcd_enable();
56
}
57
 
58
void lcd_writedata(uint8_t data) {
59
  // Datenbyte -> HD61830
60
 
61
  lcd_busy();
62
  CTRLPORT &= ~(1<<RW);    // R/W auf logisch 0 -> W 
63
  CTRLPORT &= ~(1<<RS);    // RS auf logisch 0 -> inaktiv
64
  DATAPORT = data;      // übergebenes Datenbyte wird ausgegeben
65
  lcd_enable();
66
}
67
  
68
void lcd_send(uint8_t command, uint8_t data) {
69
  // Kombination aus Kommando- und Datenbyte
70
71
  lcd_writecommand(command);
72
  lcd_writedata(data);
73
}
74
75
void lcd_init(unsigned char modus){
76
  // Initialisiert das Display
77
78
  DATADDR = 0xff;        // Datenport wird als Ausgang deklariert
79
  CTRLDDR|= (1<<RW)|(1<<RS)|(1<<E)|(1<<CS);        // Kommandoport wird als Ausgang deklariert
80
  
81
  CTRLPORT &= ~(1<<CS);    // CS auf logisch 0 -> aktiv
82
  
83
  if(modus == 'c'){
84
    // Charaktermodus
85
    
86
    lcd_send(0x00, 0x30);  // Mode Control
87
    lcd_send(0x01, 0x75);  // Set Character Pitch
88
    lcd_send(0x02, 0x27);  // Set Number of Characters
89
    lcd_send(0x03, 0x0A);  // Set Number of Time Divisions
90
    lcd_send(0x04, 0x07);  // Set Cursor Position
91
  }
92
  else{
93
    // Grafikmodus
94
    
95
    lcd_send(0x00, 0x32);  // Mode Control
96
    lcd_send(0x01, 0x07);  // number of bits of 1-byte display data to be displayed
97
    lcd_send(0x02, 0x1d);  // number of horizontal bytes
98
    lcd_send(0x03, 0x0A);  // Set Number of Time Divisions 
99
  }
100
  
101
  lcd_send(0x08, 0x00);    // Set Display Start Low Order Address
102
  lcd_send(0x09, 0x00);    // Set Display Start High Order Address
103
  
104
105
}
106
107
void lcd_clear(unsigned char modus){
108
  // Löscht das Display
109
110
  lcd_gotoxy(modus, 0, 0);      // Cursor an den Anfang setzen
111
  
112
  if(modus == 'c'){
113
    // Charaktermodus
114
    
115
    for(uint16_t i=0; i<320; i++)  // Alle Chars durchlaufen und löschen
116
      lcd_send(0x0c, 0x20);
117
  }
118
  else{
119
    // Grafikmodus
120
    
121
    for(uint16_t i=0; i<1920; i++)  // Alle Bytes durchlaufen und löschen
122
      lcd_send(0x0c, 0x00);
123
  }
124
125
  lcd_gotoxy(modus, 0, 0);      // Cursor an den Anfang setzen
126
}
127
128
void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
129
  // Setzt den Cursor an eine bestimmte Position
130
  
131
  uint16_t adress;
132
  
133
  if(modus == 'c'){
134
    // Charaktermodus
135
    
136
    adress = (y * 40) + x;
137
  }
138
  else{
139
    // Grafikmodus
140
    
141
    adress = (y * 30) + x;
142
  }
143
  
144
  lcd_send(0x0a, (uint8_t)(adress));  // Set Cursor Address (Low Order)
145
  lcd_send(0x0b, (uint8_t)(adress >> 8));  // Set Cursor Address (High Order)
146
}
147
148
void lcd_setdot(uint8_t x, uint8_t y){
149
  // Setzt ein Pixel an einer bestimmte Position
150
151
  lcd_gotoxy('g', (x >> 3), y);
152
  lcd_send(0x0f, (x & 0x07));
153
}
154
155
void lcd_cleardot(uint8_t x, uint8_t y){
156
  // Löscht ein Pixel an einer bestimmte Position
157
158
  lcd_gotoxy('g', (x >> 3), y);
159
  lcd_send(0x0e, (x & 0x07));
160
}
161
162
void lcd_puts(char *string){
163
  #define lcd_putc(c)  lcd_send(0x0c,c)
164
  uint8_t i=0;
165
  char c = string[0];
166
  
167
  while(c != 0) {
168
  /*  if(c == '\n')
169
      lcd_newline(font.height, startx);
170
    else*/
171
      lcd_putc(c);
172
    c = string[++i];
173
  }
174
}
175
176
int main(void){
177
  _delay_ms(10);
178
  lcd_init('c');
179
  lcd_clear('c');
180
  lcd_puts("Hallo ! Test XY Test XY Test XY Test XY ");
181
  while(1);
182
}
mfg martin

von Martin (Gast)


Lesenswert?

Das gleiche passiert auch im grafik modus... wenn ich ein datenbyte zum 
controller sende, erscheint das gleiche byte immer 12 mal untereinander, 
immer im vertikalen abstand von je 10 pixeln

von Martin (Gast)


Lesenswert?

kennt jemand eine funktionierende library für den controller ?

von gast (Gast)


Lesenswert?

Hallo,

ich hab das Problem durch ändern des Wertes  Set Number of Time 
Divisions (lcd_send(0x03, 0x0A); ) gelöst.
Bei mir (240x128 Zeichen) hab ich eine 0x7F geschickt.Ich musste aber 
Vee auf 15.2V und den Kontrast recht weit aufdrehen.
Beim löschen des Displays in Grafik-Mode noch die Anzahl der Pixel 
ändern

(240 x 128) / 8 = 3840
  else{
    // Grafikmodus

    for(uint16_t i=0; i< 3840 ; i++)  // Alle Bytes durchlaufen und 
löschen
      lcd_send(0x0c, 0x00);
  }


Gruß Ralf

von Axel P. (funkydunky)


Lesenswert?

hi,

ich kämpfe in der uni gerade mit diesem display...ich bekomme es ums 
verrecken nicht hin, ein pixel an jeder x-beliebigen stelle zu setzen.

ich weiß nicht, ob es eine einstellungssache ist, aber der 
grafikspeicher wird ja immer in 1-byte blöcken angesprochen(jedes bit 
repräsentiert dann ein pixel), und nicht pixelweise

ich habe es nicht hinbekommen denn cursor(im grafikmodus) an die 
gewünschte stelle zu setzen. die cursor register sind ja 0x08 und 0x09

setze ich register 0x08 und 0x09 jeweils auf 0, und gebe ein pixel aus, 
dann sitzt es auch wie erwartet in der linken oberen ecke.
setze ich höhere werte in 0x08 ein, dann wandert der cursor nach rechts. 
ok!
ich dachte jetzt, 0x08 würde die x-position ansprechen, und 0x09 die 
y-position. aber dem ist nicht so.

kann mir jemand mal erklären wie da der grafikspeicher aufgebaut ist? 
ein register die x, das andere die y position scheint ja nicht der fall 
zu sein. aus der gotoxy position weiter oben werde ich leider nicht 
wirklich  schlau.


danke für hilfe,
xel

von Spess53 (Gast)


Lesenswert?

Hi

Die Grafikspeicher sind in der Regel linear aufgebaut. Um mit x,y zu 
arbeiten müsstest du rechnen: Adresse= Grafikarea + y*Bytes/Zeile + x.

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.