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

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.