Forum: Mikrocontroller und Digitale Elektronik PROGMEM uint64_t auslesen


von Matze (Gast)


Lesenswert?

Hallo,
ich möchte eine Bitkette die ich vorher mit PROGMEM geschrieben habe 
wieder auslesen...

nur wie mache ich das? mit pgm_read_word geht es ja nicht...

const uint64_t charbytetable[] PROGMEM =
{
    0b11111100001001000100100010011111110, //A
    0b11111111001001100100110010010110110, //B
    0b01111101000001100000110000010100010, //C
    0b11111111000001100000110000010111110, //D
};

von Hmm (Gast)


Lesenswert?

>nur wie mache ich das? mit pgm_read_word geht es ja nicht...

Warum sollte das nicht gehen? Liegts am Schnee oder was?

von katastrophenheinz (Gast)


Lesenswert?

Wie verspeist man einen Elefanten? - Genau, in kleinen Stücken.
also: Warum nicht in Stücken einlesen und zusammenbasteln.
Notfalls baust du dir die Funktion pgm_read_qword halt selbst ...

von Matze (Gast)


Lesenswert?

ok dann noch mal Komplett:

const uint8_t chartable[] PROGMEM =
{
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z',
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9'
};

const uint64_t charbytetable[] PROGMEM =
{
    0b11111100001001000100100010011111110, //A
    0b11111111001001100100110010010110110, //B
    0b01111101000001100000110000010100010, //C
    0b11111111000001100000110000010111110, //D
    0b11111111001001100100110010011000001, //E
    0b11111110001001000100100010010000001, //F
    0b01111101000001100100110010011111010, //G
    0b11111110001000000100000010001111111, //H
    0b10000001000001111111110000011000000, //I
    0b01000001000001100000110000010111111, //J
    0b11111110001000001010001000101000001, //K
    0b11111111000000100000010000001000000, //L
    0b11111110000001000111000000011111111, //M
    0b11111110000100000100000100001111111, //N
    0b01111101000001100000110000010111110, //O
    0b11111110001001000100100010010000110, //P
    0b01111101000001101000101000011011110, //Q
    0b11111110001001001100101010011000110, //R
    0b01001101001001100100110010010110010, //S
    0b00000010000001111111100000010000001, //T
    0b01111111000000100000010000000111111, //U
    0b00111110100000100000001000000011111, //V
    0b10000010100010001110001000101000001, //X
    0b00001110001000111000000010000000111, //Y
    0b11000011010001100100110001011000011, //Z
    0b01111101000001100000110000010111110, //0
    0b10000101000010111111110000001000000, //1
    0b10000101100001101000110010011000110, //2
    0b01000101000001100100110010010110110, //3
    0b00100000011000001010000100101111111, //4
    0b01011111001001100100110010010110001, //5
    0b01111101001001100100110010010110010, //6
    0b00000011110001000100100001010000011, //7
    0b01101101001001100100110010010110110, //8
    0b01001101001001100100110010010111110  //9
};

uint8_t get_charbytes (uint8_t character, uint8_t line) //line = Zeile 
1-5 vom Buchstaben
{
    for (uint8_t i = 0; i < 36; i++)
    {
        if (pgm_read_byte (&chartable[i]) == character)
        {
            switch (line)
            {
                case 1:
                    return (pgm_read_word (& charbytetable[i])) & 
0x7F0000000;

                case 2:
                    return (pgm_read_word (& charbytetable[i])) & 
0xFE00000;

                case 3:
                    return (pgm_read_word (& charbytetable[i])) & 
0x1FC000;

                case 4:
                    return (pgm_read_word (& charbytetable[i])) & 
0x3F80;

                case 5:
                    return (pgm_read_word (& charbytetable[i])) & 0x7F;

                default:
                    return 0;
            }
        }
    }
    return 0;
}

ich bekomme bei
get_charbytes('A', 1); den Dezimalwert 0
get_charbytes('A', 2); den Dezimalwert 0
get_charbytes('A', 3); den Dezimalwert 0

get_charbytes('A', 4); den Dezimalwert 128
get_charbytes('A', 5); den Dezimalwert 126

warum bitte?

Kann mich bitte wer aufklären?

Bin schon am verzweifeln...

von katastrophenheinz (Gast)


Lesenswert?

hast du die Arrays mal ganz normal ins ram gepackt und damit getestet ?
Funktionierte das?

von Hmm (Gast)


Lesenswert?

Der "Ingenieurweg" ist der, das Du Dir Gedanken machst was das Programm 
machen soll und auf welche Weise es das tun soll. Das ergibt zwei 
Beschreibungen, meinem persönlichen Geschmack nach, vorzugsweise mit 
Bildern.

Falls etwas nicht klappt, und das ist garnicht so selten und auch nicht 
irgendwie negativ, dann vergleichst Du das was tatsächlich geschieht mit 
deiner Vorstellung von dem was geschehen soll.

Das ergibt wieder eine Beschreibung.

Diese drei Beschreibungen postest Du bitte hier.

Danke für die Beachtung aller Sicherheitsmaßnahmen :-)

von Peter D. (peda)


Lesenswert?

Matze schrieb:
> warum bitte?

Weil uint8_t eben nur mal 8 Bits groß ist.
In Case 1 - 3 sind die untersten 8 Bits eben 0.
In Case 4 wird nur Bit 7 geliefert.
Nur Case 5 liefert Bit 0 .. 6.

Es ist nicht gerade schlau für 35 Bits immer 64 Bits zu verschwenden.

Auch werden Displays oft Byte-Weise angesteuert. Daher werden die 
ASCI-Bitmasken üblicher Weise als 5 Byte Array (5*8) abgelegt und man 
spart sich aufwendige Schiebereien.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ziemlich sicher willst du nicht wirklich 64-Bit Werte verwenden.

Falls doch, geht das Auslesen als 64-Bit Wert aus dem Flash erst ab 
avr-gcc 4.7:
 
1
#include <stdint.h>
2
3
const __flash uint64_t val64[] = 
4
{
5
    0, 1, 2
6
};
7
8
uint64_t read_val (uint8_t i)
9
{
10
    return val64[i];
11
}
 
In älteren Versionen muss der Wert aus mehreren pgm_read_xxx 
zusammengebastelt werden. 

Weiters gibt es ab 4.8 die Möglichkeit, 64-Bit Register in 
Inline-Assembler zu verwenden:
 
1
#include <stdint.h>
2
3
static __inline__ __attribute__((always_inline))
4
uint64_t pgm_read_ull (const uint64_t* addr)
5
{
6
#if !defined __AVR_HAVE_LPMX__
7
#error Need "LPM Rn, Z+" instruction
8
#endif /* Have LPMX */
9
10
    uint64_t x;
11
12
    __asm__ ("$ lpm %r0+0, %a1+"
13
             "$ lpm %r0+1, %a1+"
14
             "$ lpm %r0+2, %a1+"
15
             "$ lpm %r0+3, %a1+"
16
             "$ lpm %r0+4, %a1+"
17
             "$ lpm %r0+5, %a1+"
18
             "$ lpm %r0+6, %a1+"
19
             "$ lpm %r0+7, %a1+"
20
             : "=r" (x), "+z" (addr));
21
    return x;
22
}
 

von Simon K. (simon) Benutzerseite


Lesenswert?

Hmm, es gibt ja gar kein pgm_read_block? Aber eeprom_read_block gibts.

von Falk B. (falk)


Lesenswert?

@Simon K. (simon) Benutzerseite

>Hmm, es gibt ja gar kein pgm_read_block? Aber eeprom_read_block gibts.

Nein, nur byte, word, dword. Reicht aber.

von Simon K. (simon) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> @Simon K. (simon) Benutzerseite
>
>>Hmm, es gibt ja gar kein pgm_read_block? Aber eeprom_read_block gibts.
>
> Nein, nur byte, word, dword. Reicht aber.

In wie fern? ;-) pgm_read_block fände ich schon praktisch. Zumindest 
fande ich eeprom_read_block bisher sehr praktisch.

Reichen tuts, klar. Aber man muss sich ja nicht mit allem zufrieden 
geben ;-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Simon K. schrieb:

Aber man muss sich ja nicht mit allem zufrieden geben.

Naja, du gibt dich ja auch mit einer alten Compiler-Version zufrieden 
;-)
Nimm ne aktuelle Version und du brauchst überhaupt kein pgm-Zeugs mehr.

von Simon K. (simon) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Simon K. schrieb:
>
> Aber man muss sich ja nicht mit allem zufrieden geben.
>
> Naja, du gibt dich ja auch mit einer alten Compiler-Version zufrieden
> ;-)
;-) Ja, ich finde die Einführung von dem flash-Keyword auch sehr 
praktisch. Mache zur Zeit aber nichts mehr mit AVRs und deswegen konnte 
ich es noch nicht ausprobieren. Mein Verständnis war bisher, dass das 
noch eher im "Beta-Stadium" ist. Ausprobiert habe ich es noch nicht.
Ich bin zur Zeit eher im Anfangsstadium im STM32 Segment unterwegs.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Simon K. schrieb:
> ich finde die Einführung von dem flash-Keyword auch sehr praktisch.
> Mein Verständnis war bisher, dass das noch eher im "Beta-Stadium" ist.

Was meinst du mit "beta"?

Im avr-gcc 4.7 gibt es keine offenen Bugs.

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.