Problem mit pgm_read_byte

Gast #3569655
Lesenswert?

Hallo!
Ich habe hier eine 5*7 Fonttabelle und eine 16*12 Font Tabelle
und diese haben folgende struktur
1
const uint8_t __Font5x7[] PROGMEM = {
2
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// (space)
3

4
...
5
tFont Font5x7 = {(PGM_P)__Font5x7, 7, 8, 7, 1, 0};
1
const uint8_t __Font12x16[] PROGMEM = {
2
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "(space)"
3
  0x7C, 0x00, 0xFF, 0x33, 0xFF, 0x33, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "!"
4

5
...
6
tFont Font12x16 = {(PGM_P)__Font12x16, 11, 16, 22, 2, 0};

diese müssen über eine funktion putstr auf dem display DOGS102 zu sehen 
sein, nun für die kleiensc hriftart funktioniert es, aber weshalb auch 
immer gehts beim großen font nicht

hier die vorgegebene font struktur:
1
typedef struct
2
{
3
  PGM_P font;
4
  unsigned char Width;
5
  unsigned char Height;
6
  unsigned char CharSize;
7
  unsigned char Lines;
8
  unsigned char Prop;
9
} tFont;
1
void DOGS102_PutStr(unsigned char PosX, unsigned char Line, char * pdata, tFont font)
2
{
3
  unsigned int Len = 0;
4
  unsigned char Data = 0;
5
  unsigned char l;
6
  unsigned char FontIndex;
7
  unsigned char ZeroLine;
8

9
  while (*pdata)
10
  {
11
    unsigned char w;
12
    FontIndex = 0;
13
    for (w = 0; w < font.Width; w++)
14
    {
15
      ZeroLine = 0;
16
      for (l = 0; l < font.Lines; l++)
17
      {
18
        Data = pgm_read_byte(&font.font[(*pdata-Font_AsciiOffset)*(font.CharSize)+(w+1)*(l+1)-1]);// PROBLEM LIEGT HIER
19
        FontIndex++;
20
        ZeroLine |= Data;
21
        LCDCache[(DOGS102_PIXELX * (Line + l)) + PosX + Len] = Data;
22
      }
23
      Len++;
24
      if (ZeroLine == 0 && w > 1 && font.Prop == 0)
25
      break;
26
      
27
      // falls ein Zeichen genau font.Width Bytes benoetigt, dann am Ende noch
28
      // eine Leerspalte einfuegen
29
      if (w == font.Width - 1)
30
      {
31
        Data = 0x00;
32
        
33
        for (l = 0; l < font.Lines; l++)
34
        LCDCache[(DOGS102_PIXELX * Line) + PosX + Len] = Data;
35
        Len++;
36
      }
37
    }
38
    pdata++;
39
  }
40
  
41
  // write all lines needed for the font
42
  for (l = 0; l < font.Lines; l++)
43
  {
44
    WriteCache(PosX, Line + l, Len);
45
  }
46
}

format_ascii_font ist ascii wert vom space

kann mir vllt jemand da weiterhelfen?
#3569775
Lesenswert?

Der Teil hier
1
   .... (w+1)*(l+1)-1
ist unlogisch.

Da Arrays in C beginnend mit 0 indiziert werden und das ganze im Grunde 
ein 2-dimensionales Array abbildet, wäre
1
   .... w * font.Lines + l
wesentlich logischer
Eventuell auch
1
   .... w * l * font.width
je nachdem in welcher Reihenfolge die Bytes in den Font Pixeldaten 
angeordnet sind.
#3569937
Lesenswert?

Karl Heinz schrieb:

Die Variante hier

> ein 2-dimensionales Array abbildet, wäre
>
1
>    .... w * font.Lines + l
2
>

ist aufgrund

>   0x7C, 0x00, 0xFF, 0x33, 0xFF, 0x33, 0x7C, 0x00,
>   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "!"

die richtige. Die beiden Bytes, die senkrecht aneinander gelegt das 
Zeichen ergeben, folgen offenbar unmittelbar hintereinander.

d.h das ist
1
O = Byte oben
2
U = Byte unten
3

4
                 O   U   O   U   O   U   O   U ...
5
                7C  00  FF  33  FF  33  7C  00 ...
6

7
Pixelspalte      1   1   2   2   3   3   4   4 ....

Um also an die Bytes der x-ten Pixelspalte zu kommen, muss man die 
Spaltennummer mit der Anzahl der Bytes pro Spalte multiplizeren. Die 
einzelnen Bytes jeder Spalte folgen dann direkt hintereinander.
Font.Lines ist genau diese Anzahl an Bytes
w ist die Nummer der jeweils auszugebenden Pixelspalte.

Daher
1
    for (w = 0; w < font.Width; w++)
2
    {
3
      for (l = 0; l < font.Lines; l++)
4
      {
5
        gib das Byte mit den Pixeln von
6
          Pixeldaten_des_Zeichen[ w * Font.Lines + l ]
7
        aus.
8
      }
9
    }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren