Forum: Compiler & IDEs Zugriff auf mehrdimensionalen Char-Array AVR


von Matthias J. (weteor)


Lesenswert?

Hallo,

Ich versuche gerade eine LCD-Display mit einem ATMega16 anzusteuern. Das 
Display ist ein DOGM131 mit einem ST7565R-Controller. Das funktionert 
soweit auch gut.
Nun hab ich versucht, Text auf dem Display auszugeben.
Dafür habe ich eine Header Datei font.h, in welcher die einzelnen 
Buchstaben in einem zweidimensionalen Array gespeichert sind (Das ganze 
hab ich glaube ich irgendwo hier aus dem Forum). Die erste "Dimension" 
gibt an welcher Buchstabe gemeint ist (Reihenfolge ist wie 
dezimal-Ascii) und in der zweiten sind die Spalten-Bytes für das Display 
gespeichert. das ganze sieht dann so aus:
1
const char font[256][6] ={
2
{0x00,0x00,0x00,0x00,0x00,0x00},  //0x00
3
//...
4
//...
5
{0x00,0x7E,0x11,0x11,0x11,0x7E},  // 0x41 = 'A'
6
{0x00,0x7F,0x49,0x49,0x49,0x36},  // 0x42 = 'B'
7
{0x00,0x3E,0x41,0x41,0x41,0x22},  // 0x43 = 'C'
8
//.. usw.
9
}

Im Programm definiere ich nun einen char-Array und versuche diesen über 
die Funktion "PrintMessage" auf dem Display ausgeben zu lassen, was 
nicht klappt. Hier ist einmal der Code, Fehlerbeschreibung kommt danach 
;)
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#include <string.h>
5
6
#include "font.h"
7
8
// *Data->Pointer auf Char-Array, Page -> Welche DisplayZeile, Flip-> Zeichenumbruch ja/nein
9
10
uint8_t PrintMessage( char *Data, uint8_t Page, uint8_t Flip );
11
12
int main(void)
13
{
14
    // Hier stehen einige Hardwareinitialisierungen
15
        
16
    char Message[]  = {'a','b','c','\0'}; //wird komplett richtig angezeigt
17
    char Message2[] = {'A','b','c','\0'}; //das 'A' wird nicht richtig
18
                                          //angezeigt
19
    char Message1[] = "Abc"; //funktioniert gar nicht ... nur Datenmüll,
20
                             //viel länger als 3 Zeichen
21
    
22
    PrintMessage( Message , 0, 0);
23
    PrintMessage(Message1 , 1, 0);
24
    PrintMessage(Message2 , 2, 0);
25
26
    while(1)
27
    {
28
        //Ein bisschen Aktivitätsblinken
29
        ToggleBit( PORTC, PC5 );
30
        _delay_ms(1000);
31
    }
32
    return 0;
33
}
34
35
uint8_t PrintMessage( const char *Data, uint8_t Page, uint8_t Flip )
36
{
37
38
    uint8_t i=0;
39
    uint8_t Error = 0;
40
    
41
    SetCommand;                  //Display-KommandoModus
42
    SendByte( ( 0xb0 | Page ) ); // Set Page
43
    SendByte( 0x10 );            //Set Start Column
44
    SendByte( 0x00 );
45
    SetData;                     // Display-Datenmodus
46
    
47
    //Array bis zur Terminierung durchlaufen und ausgeben
48
    while ( ( 0 == Error ) && ( '\0' != *Data ) )
49
    {
50
        //Testfall, wenn 'A' gefunden ausgeben-> funktioninert immer
51
        if ( 65 == *Data) //auch mit if ('A' == *Data)
52
        {
53
            //SendByte sendet ein Byte per SPI an Display
54
            SendByte(font[65][0]);
55
            SendByte(font[65][1]);
56
            SendByte(font[65][2]);
57
            SendByte(font[65][3]);
58
            SendByte(font[65][4]);
59
            SendByte(font[65][5]);
60
61
        }
62
        
63
        // alle sechs Spalten für einen Buchstaben ausgeben
64
        // Das funktioniert nur für Zeichen > 'V'
65
        for (i = 0;i < 6; i++)
66
        {
67
            SendByte( font[*Data][i] );
68
        }
69
        
70
        // Pointer weitersetzen
71
        Data++;
72
    }
73
74
    return Error;
75
}

Die Anzeige funktioniert für alle Buchstaben und Zeichen die größer 
ascii-Zeichen 'V' (bzw dezimal 86)  sind . Für alle Zeichen darunter 
wird nur Datenmüll angezeigt. Ich kann sie aber richtig anzeigen, wenn 
ich die einzelnen Zeichen explizit mit SendByte(font[Zahl][Zahl]) 
angebe. Mir scheint also irgendetwas mit den Indizes falsch zu laufen. 
Ich hab im Quelltext noch ein paar Variationen mit Fehlerbild eingefügt.

Außerdem funktionieren die Zuordnungen
1
Message[] = "foo bar";
2
Message[8] = "foo bar";
nicht, was in C doch eigentlich funktionieren sollte, oder?

Wäre schön, wenn mir jemand auf die Sprünge helfen kann, was ich 
verkehrt mache....ich hab so das Gefühl, das ist was ganz fundamentales 
und ich sehe es vor lauter Probieren nur nicht mehr.

Gruß, Matthias

von Tim (Gast)


Lesenswert?

1
const char font[256][6]
Benötigt 1563 Byte Ram. Du hast aber beim ATmega16
nur 1k zur Verfügung....

Pack den Font erst mal ins Flash:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

von Matthias J. (weteor)


Lesenswert?

Woah, vielen Dank!

Das wars. Ist ja auch total logisch, hab ich nur überhaupt nicht dran 
gedacht.

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.