PROGMEM uint64_t auslesen

Gast #2890117
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
};
Gast #2890160
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 ...
Gast #2890172
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...
Gast #2890184
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 :-)
#2890195
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
Persönliche Seite #2890281
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
}
 
Persönliche Seite #2890419
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 ;-)
Persönliche Seite #2890450
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.

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