Forum: Compiler & IDEs AVR-GCC - seltsames array-index verhalten


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Wim M. (kaputteshirn)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

vorab:
 - Ich benutzte Atmel Studio 7.0.1931
 - ein "normales" GCC C++ Projekt mit einem ATMEGA328P

Was mache ich:
ASCII-Zeichen via 2D-Bitmap Byte-Weise auslesen und über SPI auf eine 
Dot-Matrix ausgeben.

Problem:
In einer for-Schleife werden eine bestimmte Anzahl an Zeichen ausgelesen 
und in das Display geschrieben. Lese ich ein Zeichen ungespiegelt aus, 
starte also mit index = 0, erscheint das Zeichen fehlerhaft auf dem 
Display. Lese ich ein Zeichen allerdings "rückwärts"/"gespiegelt" aus, 
also index = 7 (ein Zeichen = 8x8 pixel), wird es richtig dargstellt.
Das ist sehr merkwürdig und diesem Problem bin ich bisher noch nie 
begegnet.
Zuerst dachte ich, vielleicht hat der Compiler ein Problem mit den 
Index-Variablen, und "volatile" benutzt, das hat nicht geholfen. Auch 
die Compiler-Optimierung "-O0 (none)" hat nichts gebracht.
Weiß jemand, warum das "vorwärts"-Auslesen probleme macht, das 
"rückwärts"-Auslesen aber nicht?

MfG

Hier der Code für "vorwärts":
//Bitmap:
char font8x8_basic[128][8]  = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
    // [...]
    { 0x55, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
    { 0x55, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
    { 0xaa, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
    //[...]
    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff}    // U+007F
};

int charPtr = 0x40; // start at '@'
int segmentPtr = 0;
for (int i = 0; i < (128 * 2); i++) // 128 x 64 dot-matrix - print two lines
{
    spi.write((uint8_t)(font8x8_basic[charPtr][segmentPtr]));
    segmentPtr++;
    if (segmentPtr == 8)
        segmentPtr = 0;
    if ((i % 8 == 0) && (i != 0))
        charPtr++;
}

Hier der Code für "vorwärts":
int charPtr = 0x40; // start at '@'
int segmentPtr = 7;
for (int i = 0; i < (128 * 2); i++) // 128 x 64 dot-matrix - print two lines
{
    spi.write((uint8_t)(font8x8_basic[charPtr][segmentPtr]));
    segmentPtr++;
    if (segmentPtr < 0)
        segmentPtr = 7;
    if ((i % 8 == 0) && (i != 0))
        charPtr++;
}

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich würde erst einmal Pixel und Linien auf dem Display setzen.
Orientierung/RAM lässt sich verschieden einstellen.

Das muss man zuerst verstehen.

von Wim M. (kaputteshirn)


Bewertung
0 lesenswert
nicht lesenswert
oooooohhh meine Güte wie peinlich...meine Augen brauchen wohl Pause.
Sry für die Frage.
Auf den Bildern ist mir aufgefallen, dass "rückwärts" auch falsch ist.

Das Problem ist, dass if ((i % 8 == 0) && (i != 0)) am Ende der 
for-Schleife steht. Es müsste am Anfang stehen. Noch besser ist das if 
wegzulassen und in
if (segmentPtr == 8) mit rein zupacken.

richtiger Code:
int charPtr = 0x40; // start at '@'
int segmentPtr = 0;
for (int i = 0; i < (128 * 2); i++) // 128 x 64 dot-matrix - print two lines
{
    spi.write((uint8_t)(font8x8_basic[charPtr][segmentPtr]));
    segmentPtr++;
    if (segmentPtr == 8)
    {
        segmentPtr = 0;
        charPtr++;
    }
}

nja die Probleme sind doch meist so simpel^^

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.

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