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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.