Forum: Mikrocontroller und Digitale Elektronik Ausgabe von Font aus Programm Memory


von SimSalabim (Gast)


Lesenswert?

Hallo,

ich komm da einfach nicht weiter und bitte um Hilfe.

ich möchte in meinen Quellcode bzw Bibliothek Font von einem anderem 
Maßstab benutzen, da ich nur kleine Schrift habe in Form von 6x8.

so sieht der Quellcode momentan aus für 6x8 Font:
1
 
2
#include <avr/pgmspace.h>
3
typedef char PROGMEM   prog_char;
4
5
const prog_char Font[256] [6] = {
6
{ 0, 255, 255, 255, 255, 255},
7
{ 0, 255, 255, 255, 255, 255},
8
{ 0, 255, 255, 255, 255, 255},
9
{ 0, 255, 255, 255, 255, 255},
10
..
11
.
12
{ 0, 28, 161, 160, 161, 124}};

so der neue Quellcode mit großen Schrift:
1
typedef char PROGMEM   prog_char2;
2
3
const prog_char2 Font2[80] [2] = {
4
{0x00, 0x00}, //  ········ ·······
5
{0x00, 0x00}, //  ········ ·······
6
{0x0f, 0xe0}, //  ····#### ###····
7
{0x3f, 0xf8}, //  ··###### #####··
8
{0x3f, 0xf8}, //  ··###### #####··
9
{0x7f, 0xfc}, //  ·####### ######·
10
{0x7e, 0xfc}, //  ·######· ######·
11
{0x7c, 0x7c}, //  ·#####·· ·#####·
12
{0x7c, 0x7c}, //  ·#####·· ·#####·
13
{0x7c, 0x7c}, //  ·#####·· ·#####·
14
{0x7c, 0x7c}, //  ·#####·· ·#####·
15
{0x7c, 0x7c}, //  ·#####·· ·#####·
16
{0x7c, 0x7c}, //  ·#####·· ·#####·
17
{0x7c, 0x7c}, //  ·#####·· ·#####·
18
{0x7c, 0x7c}, //  ·#####·· ·#####·
19
{0x7c, 0x7c}, //  ·#####·· ·#####·
20
{0x7c, 0x7c}, //  ·#####·· ·#####·
21
{0x7c, 0x7c}, //  ·#####·· ·#####·
22
{0x7c, 0x7c}, //  ·#####·· ·#####·
23
{0x7c, 0x7c}, //  ·#####·· ·#####·
24
{0x7c, 0x7c}, //  ·#####·· ·#####·
25
{0x7c, 0x7c}, //  ·#####·· ·#####·
26
{0x7c, 0x7c}, //  ·#####·· ·#####·
27
{0x7c, 0x7c}, //  ·#####·· ·#####·
28
{0x7c, 0x7c}, //  ·#####·· ·#####·
29
{0x7c, 0x7c}, //  ·#####·· ·#####·
30
{0x7c, 0x7c}, //  ·#####·· ·#####·
31
{0x7c, 0x7c}, //  ·#####·· ·#####·
32
{0x7c, 0x7c}, //  ·#####·· ·#####·
33
{0x7c, 0x7c}, //  ·#####·· ·#####·
34
{0x7c, 0x7c}, //  ·#####·· ·#####·
35
{0x7c, 0x7c}, //  ·#####·· ·#####·
36
{0x7c, 0x7c}, //  ·#####·· ·#####·
37
{0x7e, 0xfc}, //  ·######· ######·
38
{0x7f, 0xfc}, //  ·####### ######·
39
{0x7f, 0xfc}, //  ·####### ######·
40
{0x3f, 0xf8}, //  ··###### #####··
41
{0x1f, 0xf0}, //  ···##### ####···
42
{0x00, 0x00}, //  ········ ·······
43
{0x00, 0x00}, //  ········ ·······

das wird ganz anders aus dem speicher aufgerufen wie das oben, so viel 
ist mir klar :)

dann zu dem Prog selbst:
1
#define lcd_string_P(__s)       lcd_string(P(__s))
2
#define lcd_writecom(__c)       lcd_write(__c,1)
3
#define lcd_writedata(__c)       lcd_write(__c,0)
4
#define lcd_readcom()       lcd_read(1)
5
#define lcd_readdata()       lcd_read(0)
6
7
#ifndef P
8
#define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;})
9
#endif
10
11
#ifndef cbi
12
#define cbi(sfr, bit)     (sfr &= ~(1<<bit)) 
13
#endif
14
#ifndef sbi
15
#define sbi(sfr, bit)     (sfr |= (1<<bit))  
16
#endif

..
1
void lcd_write (unsigned char byte, unsigned char com)
2
{
3
  if (com==1) {cbi(LCD1,A0);}
4
  else {sbi(LCD1,A0);}
5
  ausgabeP(byte);   //  LCDP=byte; // ausgabeP(byte);
6
  cbi(LCD2,Enable);
7
  cbi(LCD2,RW);
8
  sbi(LCD2,Enable);
9
  cbi(LCD2,CS);
10
  cbi(LCD2,Enable);
11
  sbi(LCD2,CS);
12
}
13
14
unsigned char lcd_read (unsigned char com)
15
{
16
  unsigned char byte;
17
  if (com==1) {cbi(LCD1,A0);}
18
  else {sbi(LCD1,A0);}
19
  ausgabeP(255);         //LCDP=255;
20
  // 0
21
   LCDDD1 &= 0b00000011;     
22
   LCDDD2 &= 0b00111111;
23
//  LCDDD = 0;
24
  
25
  cbi(LCD2,CS);
26
  sbi(LCD2,RW);
27
  sbi(LCD2,Enable);
28
  cbi(LCD2,Enable);
29
  sbi(LCD2,CS);
30
31
  cbi(LCD2,CS);
32
  sbi(LCD2,Enable);
33
  _delay_us(1);
34
  byte= einlesenP(); //LCDPI   einlesenP();
35
  cbi(LCD2,Enable);
36
  sbi(LCD2,CS);
37
38
//  LCDDD=255;
39
   LCDDD1 |=  0b11111100; // direction PortC mit 6 Bits von MSB
40
   LCDDD2 |=  0b11000000; // direction PortA mit 2 Bits von MSB
41
  return byte;
42
}
43
44
void lcd_setadress(unsigned char Spalte, unsigned char Zeile)    //Set Adresspointer
45
{   
46
  lcd_writecom(0xB0|Zeile);
47
  lcd_writecom(0x10|(Spalte/16));
48
  lcd_writecom(Spalte&15);
49
}
50
51
52
void lcd_clear(void)
53
{
54
  unsigned char x, y;
55
  for (y=0;y<8; y++)
56
  {
57
    lcd_setadress(0,y);
58
    for (x=0;x<128; x++)
59
      lcd_writedata(0x00);
60
  }
61
    lcd_setadress(0,0);
62
}
63
64
void lcd_setpixel(unsigned char x, unsigned char y, unsigned char color)
65
{
66
  unsigned char temp;  
67
  lcd_setadress(x,y / 8);
68
  temp = lcd_readdata();
69
  lcd_setadress(x,y / 8);
70
  if(color)
71
    lcd_writedata(temp | (1 << (y % 8))); 
72
  else
73
    lcd_writedata(temp & ~(1 << (y % 8))); 
74
}
75
76
void lcd_writechar (unsigned char byte)     //Display char
77
{
78
  unsigned char i;
79
  for (i=0; i<6; i++)
80
    lcd_writedata(pgm_read_byte(&Font[byte][i]));
81
}
82
83
void lcd_stringr (unsigned char *s)         //Display String from RAM
84
{
85
  unsigned char i;
86
  while (*s) 
87
    for (i=0; i<6; i++)
88
      lcd_writedata(pgm_read_byte(&Font[*s++][i]));
89
}
90
91
void lcd_string (const char *progmem_s)     //Display String from Flash
92
{
93
  unsigned char i,c;
94
  while ((c = pgm_read_byte(progmem_s++)))
95
    for (i=0; i<6; i++)
96
      lcd_writedata(pgm_read_byte(&Font[c][i]));
97
}

Ich glaub mehr braucht mannicht.

Bitte helft mir :)

: Gesperrt durch User
von SimSalabim (Gast)


Lesenswert?

Also soviel ist mir klar, in Momentanen Code wird der Font 6x8 aus dem 
Speicher wie folgt aufgerufen, 8 pixel stehen in einem Byte als 
information die aus 6 Byte besteht.
1
#include <avr/pgmspace.h>
2
typedef char PROGMEM   prog_char;
3
4
const prog_char Font[256] [6] = {
5
{ 0, 255, 255, 255, 255, 255},
6
{ 0, 255, 255, 255, 255, 255},
7
{ 0, 255, 255, 255, 255, 255},
8
{ 0, 255, 255, 255, 255, 255},
9
{ 0, 255, 255, 255, 255, 255},
10
{ 0, 255, 255, 255, 255, 255},
11
{ 0, 255, 255, 255, 255, 255},
12
{ 0, 255, 255, 255, 255, 255},
13
{ 0, 255, 255, 255, 255, 255},

was muss ich im Hauptprogramm ändern, um den anderen Font aufzurufen, so 
dass ich auch die Kleine Schrift verwenden kann..

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Na, sieh Dir den Quellcode doch genau an: Wo wird auf "Font" 
zugegriffen?

An den Stellen musst Du zwei Dinge tun: Einerseits wahlweise auf Font2 
zugreifen, andererseits die Schleife in write_char darauf anpassen, daß 
jetzt mehr Bytes in mehreren Zeilen auszugeben sind, denn Dein Zeichen 
ist ja jetzt höher als 8 Pixel und auch breiter als 6.

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Na, sieh Dir den Quellcode doch genau an: Wo wird auf "Font"
> zugegriffen?
>
> An den Stellen musst Du zwei Dinge tun: Einerseits wahlweise auf Font2
> zugreifen, andererseits die Schleife in write_char darauf anpassen, daß
> jetzt mehr Bytes in mehreren Zeilen auszugeben sind, denn Dein Zeichen
> ist ja jetzt höher als 8 Pixel und auch breiter als 6.

... und anders organisiert.


Im übrigen denke ich ehrlich gesagt nicht, dass du diesen "Font" 
verwenden willst.
Mal kurz überlegen.
Im Original brauchte man für 1 Zeichen 6 Bytes um 1 Zeichen zu kodieren. 
Dein neues Machwerk sieht aber nicht so aus als ob das ein ganzer Font 
wäre. Das ist nur 1 Zeichen und kein ganzer Font! Und für dieses 1 
Zeichen werden 160 Bytes(!) benötigt. D.h. dieses 1 Zeichen ist in 
Relation dazu riesengroß! Nicht einfach nur groß, sondern riesengroß.

von Karl H. (kbuchegg)


Lesenswert?

SimSalabim schrieb:
> Also soviel ist mir klar, in Momentanen Code wird der Font 6x8 aus dem
> Speicher wie folgt aufgerufen, 8 pixel stehen in einem Byte als
> information die aus 6 Byte besteht.

Das sind einfach jeweils 8 übereinanderliegende Pixel. Jedes Byte steht 
für eine komplette Spalte aus 8 Pixel. Wenn du dir die Info im Array 
Hexadezimal bzw. Binär anschreiben würdest, dann könntest du das auch 
direkt sehen. Wieder mal hat der Originalprogrammierer genau die 
Zahlendarstellung benutzt (Dezimal), die für den Einsatzzweck die am 
schlechtest geeignete darstellt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ein wesentlich speicherplatzsparender Ansatz wäre, für doppelte Breite 
einfach nur jede Spalte des Buchstabens zweimal auf das Display zu 
schreiben, für doppelte Höhe eben dann jede Zeile. Auf einem SPI Display 
vom Typ DOGM132 mache ich das schon lange so und es sieht besser aus, 
als es sich anhört.
Die Ausgaberoutine prüft ein 'Doppelte Breite' Flag und schickt dann 
entweder einmal oder zweimal die Daten. Für doppelte Höhe wird vor der 
Ausgabe ein bisschen gerechnet, weil das DOGM dafür zwei native Zeilen 
benötigt.

von Karl H. (kbuchegg)


Lesenswert?

Matthias Sch. schrieb:

> Die Ausgaberoutine prüft ein 'Doppelte Breite' Flag und schickt dann
> entweder einmal oder zweimal die Daten.

:-)

Dann müsste SimSalabim aber analysieren wie eigentlich die Buchstaben 
aus den Pixel entstehen, die bitmässig in seiner Fonttabelle in den 
Bytes liegen. Und dazu hat er keine Lust.

von SimSalabim (Gast)


Lesenswert?

Dass der Neue Font mehr Speicher benötigt ist mir klar, aber anders geht 
es nicht. Ich Brauche große Schrift, sonst sehe ich gar nichts.

ich weiß nicht genau was ich bei dem Aufruf alles machen soll.
z.B.
was die Zahl 80 in dem Fall : Font2[80] für Bedeutung hat.
Der 2te Array mit [2] steht wahrschenlich für die 2 Bytes.

Es ist Frechheit zu sagen "ich hätte keine Lust" nur weil einer sich 
auskennt. In dem Fall am besten einfach still sein. Ich versuch schon 
die ganze zeit, aber bei mir klappt es nicht.
:(

1
typedef char PROGMEM   prog_char2;
2
3
const prog_char2 Font2[80] [2] = {
4
{0x00, 0x00}, //  ········ ·······
5
{0x00, 0x00}, //  ········ ·······
6
{0x0f, 0xe0}, //  ····#### ###····
7
{0x3f, 0xf8}, //  ··###### #####··

von Karl H. (kbuchegg)


Lesenswert?

SimSalabim schrieb:

> Es ist Frechheit zu sagen "ich hätte keine Lust" nur weil einer sich
> auskennt.

Im Gegen...   ach was solls.

> In dem Fall am besten einfach still sein. Ich versuch schon
> die ganze zeit, aber bei mir klappt es nicht.
> :(

Dann mal dir halt mal von deinem ursprünglichen Font die Pixel auf!
Nimm dir ein Zeichen heraus, zb den Buchstaben 'K'.
K hat den ASCII Code 0x4B, also dezimal 75.

Also nimmst du dir mal die 6 Bytes in der 75.ten Zeile raus, drückst die 
6 Dezimalzahlen mal als Binärzahlen aus und spielst mal ein bischen mit 
der Anordnung der 6 Bytes, bis du in dem Haufen aus 0-en und 1-en das 
Bild eines 'K' siehst. Wenn es dir partout nicht gelingt, die 6 Bytes so 
anzuordnen, dass du ein K entdecken kannst, dann kannst du vielleicht 
einen anderen Buchstaben entdecken, und die erste Zeile in der 
Fontbeschreibung ist vielleicht gar nicht für das Zeichen mit dem ASCII 
Code 0 (ist es nicht, das kann man am Code ablesen, denn dann würde 
nicht auf &Font[byte][i] zugegriffen, sondern es gäbe einen Offset der 
zu byte dazuaddiert wird. Aber egal.)
´
Das gibt dir dann schon eine gewisse Vorstellung davon, wie eigentlich 
die Bits die Pixel weiß/schwarz färben, so dass du als Mensch im 
angezeigten Pixelhaufen ein K erkennst.


Bei deinem 2-ten 'Font' hat derjenige, der den zusammengstellt hat, das 
schon für dich gemacht. Wenn man 2 Meter vom Monitor entfernt auf die 
Tabelle schaut, dann ist unzweifelhaft im Muster im Kommentar die Ziffer 
0 zu erkennen. Wieder mit einer 1:1 Korrespondenz zu den Hex-Ziffern. 
Drückt man die als Binärziffern aus, dann ist der Zusammenhang zwischen 
0 und 1 Bits auf der einen Seite und Leerzeichen und # Zeichen auf der 
anderen Seite unübersehbar.

Das das ganze kein kompletter Font ist, ist auch klar. Denn wenn 1 
Zeichen sich über 32 Zeilen hinzieht, dann können 80 Zeilen nicht einen 
kompletten Font beschreiben!


So. Wenn du soweit bist, dann wird der Originalcode analysiert und 
festgestellt, wie das ganze Programmtechnisch gemacht wird, so dass die 
bitkodierten Bildspalten für 1 Zeichen aufs LCD übertragen werden. Und 
dann muss man sich mal eben etwas einfallen lassen, wie man das ganze 
dann mit dem anderen Font machen kann. Jaaaaaa, das nennt man 
programmieren. Ich finde es nämlich im Gegenzug als eine Frechheit, dass 
wir jedem Anfänger, der meint er könne in einer halben Stunde 
Programmieren lernen ständig die banalsten Grundlagen vorkauen sollen, 
für ihn auch noch mitdenken sollen und ihm auch noch beibringen sollen, 
wie man systematisch Probleme löst.

> was die Zahl 80 in dem Fall : Font2[80] für Bedeutung hat.
Das ist dann nur noch das i-Tüpfelchen, welches das Fass zum Überlaufen 
bringt.
DANN LERNE ES!  Dafür gibt es Bücher, in denen das und noch viele andere 
1000 Dinge ausführlichst beschrieben sind. Die Summe davon nennt man 
eben Programmiersprache und ja, wenn man Programmieren will, dann muss 
man die lernen. Wir alle mussten das. Kein Mensch wird geboren und kann 
das alles.

von SimSalabim (Gast)


Lesenswert?

@ Karl Heinz Buchegger

so ganz der Hellste bist du aber nicht! Aber wer lesen kann ist klar im 
Vorteil!

Ich verstehe genau wie sich der kleine 'Font' aufbaut! Und den 2ten habe 
ich selbst erstellt! Also ist über 70% Text dass du geschrieben hast 
eig. überflüssig.

Danke für die Mühe, aber die ist für die Katz, denn wenn du richtig 
gelesen hättest, hättest du es dir sparen können Klugscheißer zu 
spielen, und hätest wie ein Mensch geholfen, und nicht wie ein 
Besserwiser!
Ich habe Problem mein Neu Erstellten Font aufzurufen und welche Zahl ich 
an stelle von 80 eintargen muss. Hab es als Hex Eingetragen, dezimal 
sollte es dann 128 sein!
Da es nach meinem Muster ganz anders aufgerufen werden müsste habe ich 
problem, du Genie!

Keiner sagt dir, dass du es sollst, DU am besten still sien wenn du 
nicht helfen willst, vllt. findet sich ein Hilfsbereiter Mensch der 
nicht nur mäckert sondern ziel hat zu helfen!

von Spess53 (Gast)


Lesenswert?

Hi

>so ganz der Hellste bist du aber nicht!

Karl-Heinz ist wesentlich heller wie du.

>Ich verstehe genau wie sich der kleine 'Font' aufbaut! Und den 2ten habe
>ich selbst erstellt! Also ist über 70% Text dass du geschrieben hast
>eig. überflüssig.

Hast du nicht verstanden. Dein selbsterstellter Font ist für Displays, 
bei denen ein Byte acht nebeneinander liegende Pixel darstellt. Bei 
Deinem liegen die aber untereinander. Oder hast du dein Display gedreht?

MfG Spess

von troll (Gast)


Lesenswert?

SimSalabim schrieb:
> @ Karl Heinz Buchegger
>
> so ganz der Hellste bist du aber nicht! Aber wer lesen kann ist klar im
> Vorteil!
>
> hättest du es dir sparen können Klugscheißer zu
> spielen
Und tschüsss...

von SimSalabim (Gast)


Lesenswert?

Spess53 schrieb:
> Hi
>
>>so ganz der Hellste bist du aber nicht!
>
> Karl-Heinz ist wesentlich heller wie du.
>
>>Ich verstehe genau wie sich der kleine 'Font' aufbaut! Und den 2ten habe
>>ich selbst erstellt! Also ist über 70% Text dass du geschrieben hast
>>eig. überflüssig.
>
> Hast du nicht verstanden. Dein selbsterstellter Font ist für Displays,
> bei denen ein Byte acht nebeneinander liegende Pixel darstellt. Bei
> Deinem liegen die aber untereinander. Oder hast du dein Display gedreht?
>
> MfG Spess

Lieber bin ich nicht der Hellste, aber menschlicher und hilfsbereiter.

Mekern kann jeder, und die Klugscheisser müssen immer dort reinkacken wo 
die sich selbst auskennen, und andere dabei anschmieren die gerade dabei 
sind was zu lernen. Ich habe sicher Bereiche wo ich mich gut auskenne 
und ich gehe dabei versändnissvoller die das eine oder andere nicht 
verstehen!

.... so viel dazu!

Sag mir was neues!

Darum dreht es sich doch, .. aber weißt du was, ich versuches dann 
selbst! Dauert halt länger bis ich das kann, aber dafür muss ich mir so 
ein Assozialen gelaber nicht anhören!!!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das ist wirklich beeindruckend. Karl Heinz ist hier einer der 
hilfsbereitesten und geduldigsten Menschen überhaupt, der gründlichst 
und mit Engelsgeduld wieder und wieder Details erläutert -- und Du pisst 
ihn derartig derb an.

Ich denke, damit hat sich die Diskussion hier erübrigt, und Du suchst 
Dir besser andernorts eine andere Beschäftigung.

von Karl H. (kbuchegg)


Lesenswert?

> und mit Engelsgeduld wieder und wieder Details erläutert -- und Du pisst
> ihn derartig derb an.

Och, das macht nix.

Denn ....
> aber weißt du was, ich versuches dann selbst!
.... genau das war das Ziel der Sache.

Denn weißt du SimSalabim: Die Sache an sich ist nämlich nicht schwer. 
Und lernen kannst du nur, in dem du selber die Dinge machst. Ist wie 
beim Radfahren.

> Dauert halt länger bis ich das kann

Es dauert so lang, wie es dauert. Das ist zwar bei jedem etwas anders, 
aber bis du ein halbwegs brauchbarer Industrieprogrammierer bist, dauert 
das mindestens 2 bis 3 Jahre. Und dann stehst du erst am Anfang deiner 
Karriere. Ausgelernt hat man nie.

Und nö: Assozial sind die Schnorrer, die meinen sie könnten sich Arbeit 
sparen, in dem sie andere ihre Arbeit machen lassen. Ich hab nicht Jahre 
in meine Ausbildung investiert, damit ich jetzt den Handlanger für dich 
spiele. Und zu meiner Zeit gab es noch kein Internet. Ich bin über 
Monate nächtelang alleine vor dem Computer gesessen, ohne das mir wer 
Händchen gehalten hat und hab genau das gemacht, was du jetzt auch 
machen willst - gelernt, probiert, geflucht, gefreut, nachgedacht, 
getüfftelt, an die Decke gegangen, beruhigt, zum 200ten mal den Code 
durchgegangen und den Fehler nicht gesehen, x-mal Artikel gelesen, 
anderen Code studiert, in Sackgassen gelaufen, frustriert alles in die 
Ecke geschmissen, ... das volle Programm, durch das alle durch müssen.
Ich seh wirklich nicht ein, warum ich dir deine Funktion schlüsselfertig 
frei Haus liefern soll. Die ist nicht schwer. Und wenn du die originalen 
Textfunktionen selbst geschrieben hast UND auch noch den neuen Font 
erstellt hast, dann müsstest du ja eigentlich wissen, wie das 
organisiert ist und was du daher zu tun hast bzw. (Hinweis!) wie du dir 
mit einer anderen Organisation deiner Fontdaten das Leben leichter 
machen kannst.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.