Forum: Mikrocontroller und Digitale Elektronik RAM-buffer auf Display (EA-DOGM128) ausgeben


von Tobias J. (tobiasjohn) Benutzerseite


Lesenswert?

Hallo zusammen,

ich möchte bei einem EA-DOGM128 die Pixel "pixelweise" setzen können. Da 
man den Display-RAM nicht auslesen kann habe ich einen "Buffer" dafür im 
PIC-RAM definiert.

Leider habe ich diverse Probleme mit der Ausgabe des Buffers. Es werden 
zwar auch die richtigen Pixel gesetzt - jedoch wiederholt sich die 
Ausgabe entweder in x- oder y-Richtung (je nachdem was ich für routinen 
benutze).

Es ist bestimmt nur ein Denkfehler meinerseits.

Hier die Routine zum setzen der Pixel im PIC-RAM:
1
void display_setpixel(unsigned char x, unsigned char y, unsigned char color) {
2
  if (x < 128 && y < 64)
3
    if (color != 0)
4
      disp_ram[(y >> 3) + (x << 3)] |=  (1 << (y & 0x07));
5
    else
6
      disp_ram[(y >> 3) + (x << 3)] &= ~(1 << (y & 0x07));
7
  
8
}

und hier die Routine zum Ausgeben:
1
void display_flush()
2
{
3
  unsigned char page, column;
4
  for (page = 0; page < 8; page++)
5
  {
6
    display_write(0xB0 + page, CMD); //Set page address to <page>
7
    display_write(0x10, CMD);
8
    display_write(0x00, CMD);
9
10
    for (column = 0; column < 128; column++) {
11
      display_write(disp_ram[((page) + (column << 3))],DATA);
12
    }
13
  }
14
}

definiert ist "disp_ram" wie folgt:
1
char disp_ram[1024];

Bin für jeden Hinweis dankbar. Ich habe nun so ziemlich alle Variationen 
zur Errechnung der Adresse und zur Ausgabe ausprobiert ;-)

Gruß,
 Tobias

von P. S. (Gast)


Lesenswert?

Tobias John schrieb:

>       disp_ram[(y >> 3) + (x << 3)] |=  (1 << (y & 0x07));

Also, das passt mir nicht. Du hast ja immer 8 Pixel uebereinander in 
einem Byte. 128 Byte pro Page und 8 Pages.

Ich wuerde arbeiten mit

uint8_t Column = x;
uint16_t Page = y >> 3;
uint8_t Pixel = y & 0x07;
uint16_t Address = ( Page * 128) + Column;

disp_ram[ Address] |= Pixel;

Bei der ausgabe dann genauso:

uint16_t Address = ( Page * 128) + Column;

write( disp_ram[ Address]);

Alternativ koennte man disp_ram auch gleich zweidimensional 
deklarieren...

von Tobias J. (tobiasjohn) Benutzerseite


Lesenswert?

Peter Stegemann schrieb:
> Ich wuerde arbeiten mit
>
> uint8_t Column = x;
> uint16_t Page = y >> 3;
> uint8_t Pixel = y & 0x07;
> uint16_t Address = ( Page * 128) + Column;
>
> disp_ram[ Address] |= Pixel;
>
> Bei der ausgabe dann genauso:
>
> uint16_t Address = ( Page * 128) + Column;
>
> write( disp_ram[ Address]);

Ich habe es jetzt so gemacht:
1
void display_setpixel(unsigned char x, unsigned char y, unsigned char color) {
2
  if (x < 128 && y < 64)
3
    if (color != 0)
4
      disp_ram[( (y >> 3) * 128) + x] |=  (1 << (y & 0x07));
5
    else
6
      disp_ram[( (y >> 3) * 128) + x] &= ~(1 << (y & 0x07));
7
  
8
}
9
10
void display_flush()
11
{
12
  unsigned char page, column;
13
  for (page = 0; page < 8; page++)
14
  {
15
    display_goto(0,page);
16
    for (column = 0; column < 128; column++) {
17
      display_write(disp_ram[( page * 128) + column],DATA);
18
    }
19
  }
20
}

Jetzt wird das ganze 4x in y-Richtung wiederholt.

Irgendwie klappt auch das nicht.

Ne Idee wo der Fehler liegt?

von Michael P. (protactinium)


Lesenswert?

Hallo Tobias,

hier
http://msp430.ms.funpic.de/doku.php?id=projekte:grafiktreiber_spi
gibts routinen die funktionieren. kannst sie dir ja mal anschauen.

Michael

von Tobias J. (tobiasjohn) Benutzerseite


Lesenswert?

Manchmal kann die Lösung so einfach sein.

Ich habe jetzt mal den Vorschlag von Peter verfolgt und ein 
zwei-dimensionales array als buffer genommen.

Ist übersichtlicher und einfacher anzusprechen - und schon geht es... 
und zwar so:
1
void display_setpixel(unsigned char x, unsigned char y, unsigned char color) {
2
  disp_ram[y/8][x] |= (1 << (y & 0x07));
3
}
4
5
void display_flush() {
6
  unsigned char page, x;
7
  for(page=0;page<8;page++) {
8
    display_goto(0,page);
9
    for(x=0;x<128;x++) {
10
      display_write(disp_ram[page][x],DATA);
11
    }
12
  }
13
}

Dank euch für die Hilfe!

Gruß,
 Tobias

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.