www.mikrocontroller.net

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


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?
#define DATAPORT  PORTC
#define DATADDR    DDRC
#define DATAPIN    PINC
#define CTRLPORT  PORTB
#define CTRLDDR    DDRB
#define RS      0
#define RW      1
#define E      2
#define CS      3
#define F_CPU    12000000

#include <incl/delay.h>
#include <util/delay.h>
#include <stdint.h>
#include <avr/io.h>

void lcd_enable(void){
  // Erzeugt eine fallende Flanke am Enable-Pin

  CTRLPORT |= (1<<E);
  _delay_us(2);
  CTRLPORT &= ~(1<<E);
  _delay_us(2);
}

void lcd_busy(void) {
  // Wartet bis der Controller wieder Daten verarbeiten kann
 
  unsigned char tmp;
 
  DATAPORT = 0x00;      // Datenport wird gelöscht
  DATADDR = 0x00;        // Datenport wird als Eingang deklariert

  CTRLPORT |= (1<<RW);    // R/W auf logisch 1 -> R 
  CTRLPORT |= (1<<RS);    // RS auf logisch 1 -> aktiv
  
  do{
    CTRLPORT |= (1<<E);  // Steigende Flanke am Enable-Pin
    _delay_us(2);
    tmp = DATAPIN;      // Datenport wird eingelesen
    CTRLPORT &= ~(1<<E);  // Fallende Flanke am Enable-Pin
    _delay_us(2);
  }while(tmp & (1<<7));    // Schleife bis Busy Flag logisch 0 wird
  
  DATADDR = 0xff;        // Datenport wird wieder als Ausgang deklariert
}
 
void lcd_writecommand(uint8_t command) {
  // Kommandobyte -> HD61830
 
  lcd_busy();
  CTRLPORT &= ~(1<<RW);    // R/W auf logisch 0 -> W 
  CTRLPORT |= (1<<RS);    // RS auf logisch 1 -> aktiv
  DATAPORT = command;      // übergebenes Kommandobyte wird ausgegeben
  lcd_enable();
}
 
void lcd_writedata(uint8_t data) {
  // Datenbyte -> HD61830
 
  lcd_busy();
  CTRLPORT &= ~(1<<RW);    // R/W auf logisch 0 -> W 
  CTRLPORT &= ~(1<<RS);    // RS auf logisch 0 -> inaktiv
  DATAPORT = data;      // übergebenes Datenbyte wird ausgegeben
  lcd_enable();
}
  
void lcd_send(uint8_t command, uint8_t data) {
  // Kombination aus Kommando- und Datenbyte

  lcd_writecommand(command);
  lcd_writedata(data);
}

void lcd_init(unsigned char modus){
  // Initialisiert das Display

  DATADDR = 0xff;        // Datenport wird als Ausgang deklariert
  CTRLDDR|= (1<<RW)|(1<<RS)|(1<<E)|(1<<CS);        // Kommandoport wird als Ausgang deklariert
  
  CTRLPORT &= ~(1<<CS);    // CS auf logisch 0 -> aktiv
  
  if(modus == 'c'){
    // Charaktermodus
    
    lcd_send(0x00, 0x30);  // Mode Control
    lcd_send(0x01, 0x75);  // Set Character Pitch
    lcd_send(0x02, 0x27);  // Set Number of Characters
    lcd_send(0x03, 0x0A);  // Set Number of Time Divisions
    lcd_send(0x04, 0x07);  // Set Cursor Position
  }
  else{
    // Grafikmodus
    
    lcd_send(0x00, 0x32);  // Mode Control
    lcd_send(0x01, 0x07);  // number of bits of 1-byte display data to be displayed
    lcd_send(0x02, 0x1d);  // number of horizontal bytes
    lcd_send(0x03, 0x0A);  // Set Number of Time Divisions 
  }
  
  lcd_send(0x08, 0x00);    // Set Display Start Low Order Address
  lcd_send(0x09, 0x00);    // Set Display Start High Order Address
  

}

void lcd_clear(unsigned char modus){
  // Löscht das Display

  lcd_gotoxy(modus, 0, 0);      // Cursor an den Anfang setzen
  
  if(modus == 'c'){
    // Charaktermodus
    
    for(uint16_t i=0; i<320; i++)  // Alle Chars durchlaufen und löschen
      lcd_send(0x0c, 0x20);
  }
  else{
    // Grafikmodus
    
    for(uint16_t i=0; i<1920; i++)  // Alle Bytes durchlaufen und löschen
      lcd_send(0x0c, 0x00);
  }

  lcd_gotoxy(modus, 0, 0);      // Cursor an den Anfang setzen
}

void lcd_gotoxy(unsigned char modus, uint8_t x, uint8_t y){
  // Setzt den Cursor an eine bestimmte Position
  
  uint16_t adress;
  
  if(modus == 'c'){
    // Charaktermodus
    
    adress = (y * 40) + x;
  }
  else{
    // Grafikmodus
    
    adress = (y * 30) + x;
  }
  
  lcd_send(0x0a, (uint8_t)(adress));  // Set Cursor Address (Low Order)
  lcd_send(0x0b, (uint8_t)(adress >> 8));  // Set Cursor Address (High Order)
}

void lcd_setdot(uint8_t x, uint8_t y){
  // Setzt ein Pixel an einer bestimmte Position

  lcd_gotoxy('g', (x >> 3), y);
  lcd_send(0x0f, (x & 0x07));
}

void lcd_cleardot(uint8_t x, uint8_t y){
  // Löscht ein Pixel an einer bestimmte Position

  lcd_gotoxy('g', (x >> 3), y);
  lcd_send(0x0e, (x & 0x07));
}

void lcd_puts(char *string){
  #define lcd_putc(c)  lcd_send(0x0c,c)
  uint8_t i=0;
  char c = string[0];
  
  while(c != 0) {
  /*  if(c == '\n')
      lcd_newline(font.height, startx);
    else*/
      lcd_putc(c);
    c = string[++i];
  }
}

int main(void){
  _delay_ms(10);
  lcd_init('c');
  lcd_clear('c');
  lcd_puts("Hallo ! Test XY Test XY Test XY Test XY ");
  while(1);
}
mfg martin

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kennt jemand eine funktionierende library für den controller ?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Axel Preuss (funkydunky)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.