Forum: Compiler & IDEs Problem mit pgmreadbyte


von MarcusM (Gast)


Lesenswert?

wie liest man hier die bytes aus???

Font6x8[0]=0x00

0x00=00000000

ich brauche als ergebnis 00000000

oder 0x06=00000110

geht sowas mit

uint8_t data
data = pgm_read_byte(Font6x8[0]);(0x00)
data = pgm_read_byte(Font6x8[8]);(0x06)


welchen wert hat data???





static uint8_t _attribute_ ((progmem)) Font6x8[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "(space)"
  0x00, 0x00, 0x06, 0x5F, 0x06, 0x00, // "!"
  0x00, 0x07, 0x03, 0x00, 0x07, 0x03, // """
  0x00, 0x24, 0x7E, 0x24, 0x7E, 0x24, // "#"
  0x00, 0x24, 0x2B, 0x6A, 0x12, 0x00, // "$"
  0x00, 0x63, 0x13, 0x08, 0x64, 0x63, // "%"
  0x00, 0x36, 0x49, 0x56, 0x20, 0x50, // "&"
  0x00, 0x00, 0x07, 0x03, 0x00, 0x00, // "'"
  0x00, 0x00, 0x3E, 0x41, 0x00, 0x00, // "("
  0x00, 0x00, 0x41, 0x3E, 0x00, 0x00, // ")"
  0x00, 0x08, 0x3E, 0x1C, 0x3E, 0x08, // "*"
  0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // "+"
  0x00, 0x00, 0xE0, 0x60, 0x00, 0x00, // ","
  0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // "-"
  0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // "."
  0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // "/"
  0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // "0"
  0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // "1"
  0x00, 0x62, 0x51, 0x49, 0x49, 0x46, // "2"
  0x00, 0x22, 0x49, 0x49, 0x49, 0x36, // "3"
  0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // "4"
  0x00, 0x2F, 0x49, 0x49, 0x49, 0x31, // "5"
  0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // "6"
  0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // "7"
  0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // "8"
  0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // "9"
  0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00, // ":"
  0x00, 0x00, 0xEC, 0x6C, 0x00, 0x00, // ";"
  0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // "<"
  0x00, 0x24, 0x24, 0x24, 0x24, 0x24, // "="
  0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // ">"
  0x00, 0x02, 0x01, 0x59, 0x09, 0x06, // "?"
  0x00, 0x3E, 0x41, 0x5D, 0x55, 0x1E, // "@"
  0x00, 0x7E, 0x09, 0x09, 0x09, 0x7E, // "A"
  0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // "B"
  0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // "C"
  0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, // "D"
  0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // "E"
  0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // "F"
  0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // "G"
  0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // "H"
  0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // "I"
  0x00, 0x30, 0x40, 0x40, 0x40, 0x3F, // "J"
  0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // "K"
  0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // "L"
  0x00, 0x7F, 0x02, 0x04, 0x02, 0x7F, // "M"
  0x00, 0x7F, 0x02, 0x04, 0x08, 0x7F, // "N"
  0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // "O"
  0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // "P"
  0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // "Q"
  0x00, 0x7F, 0x09, 0x09, 0x19, 0x66, // "R"
  0x00, 0x26, 0x49, 0x49, 0x49, 0x32, // "S"
  0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // "T"
  0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // "U"
  0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // "V"
  0x00, 0x3F, 0x40, 0x3C, 0x40, 0x3F, // "W"
  0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // "X"
  0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // "Y"
  0x00, 0x71, 0x49, 0x45, 0x43, 0x00, // "Z"
  0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // "["
  0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // "\"
  0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // "]"
  0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // "^"
  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // "_"
  0x00, 0x00, 0x03, 0x07, 0x00, 0x00, // "`"
  0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // "a"
  0x00, 0x7F, 0x44, 0x44, 0x44, 0x38, // "b"
  0x00, 0x38, 0x44, 0x44, 0x44, 0x28, // "c"
  0x00, 0x38, 0x44, 0x44, 0x44, 0x7F, // "d"
  0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // "e"
  0x00, 0x08, 0x7E, 0x09, 0x09, 0x00, // "f"
  0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // "g"
  0x00, 0x7F, 0x04, 0x04, 0x78, 0x00, // "h"
  0x00, 0x00, 0x00, 0x7D, 0x00, 0x00, // "i"
  0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // "j"
  0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // "k"
  0x00, 0x00, 0x00, 0x7F, 0x40, 0x00, // "l"
  0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // "m"
  0x00, 0x7C, 0x04, 0x04, 0x78, 0x00, // "n"
  0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // "o"
  0x00, 0xFC, 0x44, 0x44, 0x44, 0x38, // "p"
  0x00, 0x38, 0x44, 0x44, 0x44, 0xFC, // "q"
  0x00, 0x44, 0x78, 0x44, 0x04, 0x08, // "r"
  0x00, 0x08, 0x54, 0x54, 0x54, 0x20, // "s"
  0x00, 0x04, 0x3E, 0x44, 0x24, 0x00, // "t"
  0x00, 0x3C, 0x40, 0x20, 0x7C, 0x00, // "u"
  0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // "v"
  0x00, 0x3C, 0x60, 0x30, 0x60, 0x3C, // "w"
  0x00, 0x6C, 0x10, 0x10, 0x6C, 0x00, // "x"
  0x00, 0x9C, 0xA0, 0x60, 0x3C, 0x00, // "y"
  0x00, 0x64, 0x54, 0x54, 0x4C, 0x00, // "z"
  0x00, 0x08, 0x3E, 0x41, 0x41, 0x00, // "{"
  0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, // "|"
  0x00, 0x00, 0x41, 0x41, 0x3E, 0x08, // "}"
  0x00, 0x02, 0x01, 0x02, 0x01, 0x00, // "~"
  0x00, 0x3C, 0x26, 0x23, 0x26, 0x3C  // "ein Haus? :)"
};

von Stefan (Gast)


Lesenswert?


von MarcusM (Gast)


Lesenswert?

Ja aber ich benötige die Werte von data.

bei mir kommt nur müll nicht nachvollziebar.

von Karl H. (kbuchegg)


Lesenswert?

Hat dir der Compiler das so abgenommen?

data = pgm_read_byte( & Font6x8[0] );

                      ^
                      |
                      | Du willst pgm_read_byte
                        eine Adresse übergeben.
                        Nicht den Wert von Font6x8[0]

von Stefan (Gast)


Lesenswert?

Das ist kein Wunder. Bei

data = pgm_read_byte(Font6x8[0]);

ist der Typ des Makroarguments falsch. Dort gehört eine Adresse. Hier
wäre es eine near (16-Bit d.h. innerhalb des 64 KB Adressraums)
Adresse. Siehe auch
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

data = pgm_read_byte(&Font6x8[0]);

Der ATmega128 hat ein 128 KB Flash und wenn du nicht garantieren kannst
innerhalb 64 KB zu bleiben, kannst du auch statt pgm_read_byte
pgm_read_byte_far benutzen.

Wie schaffst du das Programm auf den ATmega128, mit einem Bootloader?
Es gibt da per Lockbits Restriktionen bzgl. der (E)LPM
Assemblerbefehle, die vom pgm_read_byte Makro benutzt werden.

Du solltest auch schreiben, mit welcher GCC Version du arbeitest (s.
Problemberichte im oben erwähnten Tutorial).

von Stefan (Gast)


Lesenswert?

@ Karl Heinz

Ja der GCC Compiler (hier 3.4.5) nimmt das tatsächlich ohne Warnung.
Wohl weil pgm_read_byte() ein Makro (s. avr/pgmspace.h) ist und auf
inline Assembler expandiert wird.

von MarcusM (Gast)


Lesenswert?

Also ich programmiere miz Programmers Notepüad und WINAVR.

habe mal ein Beispiel importiert geht aber auch nicht

nt drawchar(char c)
{


   uint16_t index;
  uint8_t i, j, w, data, skipped=1, startY=yCoord;

  sendCMD(MEM_ACCESS_CTRL);
  memAccessCtrl |= (0x01 << VERT_WRITE);
  sendData(memAccessCtrl);

  if(c == '\n')
    n6100NewLine();
  if(c < 32)
    return 0;

  c -= 32;
  index = c*f.width*(f.height/8);

  for(w=0; w<f.width; w++) {
    for(i=0; i<f.height/8; i++) {
      data = pgm_read_byte(f.charData+index++);
      send_UART(data);
      for(j=0; j<8; j++) {
        if(data & 0x01) {
          if(skipped) {
            n6100GotoXY(xCoord, yCoord);
            sendCMD(MEM_WRITE);
            n6100DrawPixel();

            skipped=0;
          }
          n6100DrawPixel();
          yCoord++;
        } else {
          skipped=1;
          n6100GotoXY(xCoord, ++yCoord);
        }
        data >>= 1;
      }
    }
    n6100GotoXY(++xCoord, startY);
  }

  sendCMD(MEM_ACCESS_CTRL);
  memAccessCtrl &= ~(0x01 << VERT_WRITE);
  sendData(memAccessCtrl);

  return 0;
}

von Stefan (Gast)


Lesenswert?

Mir wäre das als Beispiel zum Entwanzen schon zu kompliziert.

Ich würde mir ein funktionierendes UART-Grundprogramm nehmen z.B. aus
dem AVR GCC Tutorial. Dort dann Code einfügen, um einen "Hello World"
Text oder wenn es sein muss ein Array ins Flash abzulegen. Und mir
diesen Text oder die Arraydaten dann über die serielle Schnittstelle
senden lassen. Damit würde ich sehen, ob das Ablegen und Auslesen
grundsätzlich klappt. Dannach würde ich mich um Fonttabellen und
Displayroutinen kümmern... Keep it simple!

von Stefan (Gast)


Lesenswert?

Ja aber welche GCC Version?

Achte auf die Versionsnummer in dem Ausgabefenster vom Programmers
Notepad 2 wenn du Make All machst...

von Stefan (Gast)


Lesenswert?

Ach so die Versionsnummer der avr-libc ist auch interessant...

von MarcusM (Gast)


Lesenswert?

Version:
avr-gcc (GCC) 3.4.6


Code

int drawchar(char c)
{


   uint16_t index;
  uint8_t i, j, w, data, skipped=1, startY=yCoord;
  c -= 32;
  index = c*f.width*(f.height/8);

  for(w=0; w<f.width; w++) {

    for(i=0; i<f.height/8; i++) {
      data = pgm_read_byte(&Font6x8[index++]);
      for(j=0; j<8; j++) {
        send_UART(data);


        data >>= 1;
      }
    }

  }


  return 0;
}


INIT UART

void init_rs232(unsigned int baud0,unsigned int baud1)
{
  UBRR0H= (unsigned char)(baud0>>8);
  UBRR0L = (unsigned char) baud0;
  UCSR0A = (1 << RXC1);
  UCSR0B=(1<<RXEN)| (1<<RXCIE) ;
  UCSR0C = (1 << UCSZ10) | (1 << UCSZ11);



  UBRR1H= (unsigned char)(baud1>>8);
  UBRR1L = (unsigned char) baud1;
  UCSR1A = (1 << RXC1) | (1<<TXC1);
  UCSR1B=(1<<RXEN) | (1<<TXEN);
  UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
 sei();

  }

void send_UART(unsigned char data)
{
UDR1=data;



}

Das Kommt über die RS232
  ?    ~?~~              ?~ 
      ?~?~~             
?~        ?~?~~         
      ?~~~           
?~?~~            ?~  ~~     
        ?~?               
~~    ~~            ?    ?~? 
        ~  ~    ~??       
  ?    ?~~          ~  ~ 
  ~??      ?    ?~~         
~  ~?      ~??      ?    ~~~ 
          ~  ~?  ~?      ? 
~~~          ~  ~?  ~~   
  ?    ~~~              ? 
~?  ~~      ?  ~  ~~     
        ?    ~?~~      ? 
~  ~?            ?    ~?~~ 
        ?  ~  ~?           
?    ~?~~          ?  ~ 
~?          ?    ~?~~       
  ~  ~  ~?            ? 
~?          ~  ~    ~?     
?    ?~?      


Da sollte ja was andreses stehen
oder muß man die Daten erts wandeln ???

von Stefan (Gast)


Lesenswert?

"Da sollte ja was andreses stehen
oder muß man die Daten erts wandeln ???"

Da steht die Ascii-Repräsentation von irgendwelchen Binärdaten. Dass
das nicht sinnvoll aussieht, ist kein Wunder.

Du solltest entweder die Daten in Hex-Zeichen umwandeln (Binärdaten
0x12 => String "0x12") z.B. mit itoa() und dann die einzelnen
Ascii-Zeichen senden - oder ein Terminalprogramm verwenden, das die die
empfangenen Zeichen als Hexcode anzeigt. Das Bray-Terminal wäre so ein
Terminalprogramm oder auch das Programm von Tobi
http://www.mikrocontroller.net/forum/read-8-155472.html#new

Bevor du das machst, teste deine Senderoutine auf dem ATmega128 mit
einer Funktion, die bekannte Daten (z.B. "Hello world") sendet.

void testUART(void)
{
  char *testdata = "hello world\r\n";

  while (*testdata)
    send_UART(*testdata++);
}

Damit stellst du sicher, dass die Datenübertragung seitens Baudrate,
Frameformat, Handshake... funktioniert. Wenn das nicht sicher ist,
suchst du dir beim eigentlichen Problem den Wolf.

von MarcusM (Gast)


Lesenswert?

Werde es heute abend probieren.

Vielen Dank jetzt ist mir einiges klar.

Bin erst neuling im AVR gebiet.

Habe vorher in C# entwickelt für I386.

von Otto Richter (Gast)


Lesenswert?

Hi MarcusM,

hatte das gleich Problem: Strings für die serielle Schnittstelle (z.B.
zum Debuggen) sollten im Flash gespeichert sein um RAM zu sparen. Da
hat mir jemand aus dem Forum sehr gur geholfen. Ich gebe Dir einfach
den Code weiter:


//Falls der Formatstring in PROGMEM stehen soll

printf_P(PSTR("Hallo aus dem Progmem %d mal.\n"), 73);

//Falls ein String-Parameter im PROGMEM steht

printf_P(" %S %d %S\n", PSTR("Hallo aus dem Progmem\n"), 73,
PSTR("mal"));

//Beachte  "%S" statt "%s" im Format!!!

Du musst natürlich <avr/pgmspace.h> includen und zwar das neuste !

möge es helfen !

Otto

von MarcusM (Gast)


Lesenswert?

mit dem obeigen Code commt nichts sauber raus.

das Hello WOrld geht super.



auch so nicht

char data
for (i=0;i<6;i++)
{
data=Font6x8[i+6];
send_UART(data);
waitms(1000);

}

hier zeigt das Terminal immer 0x00..0x00 6 mal.


bei diesen Code siehts gut aus
Terminal=
00 00 06 5F 06 00 = Zeichen "!"

Code:
send_UART(Font6x8[6]);
    waitms(1000);

  send_UART(Font6x8[7]);
  waitms(1000);

  send_UART(Font6x8[8]);
  waitms(1000);

  send_UART(Font6x8[9]);
  waitms(1000);

  send_UART(Font6x8[10]);


  waitms(1000);
  send_UART(Font6x8[11]);


warum dieses????

von MarcusM (Gast)


Lesenswert?

Habe mal den Tip mit PSTR aus dem Tutorial probiert nun bin ich soweit
das ich nur noch wissen muß wie man die bits auswerten kann.

hier der neue Code

int drawchar(char c)
{

// es wird das Font6x8 Array ab position 6 eingelesen 6 stellen lang
das Zeichen ist "!":
 uint8_t myByte;


   uint16_t index;
  int i;
    int u;
  for (i=0;i<6;i++)
{    myByte=eeprom_read_byte(&Font6x8[i+6]);
  send_UART(myByte);
  for (u=0;u<8;u++)
  {


//Wie kann ich jetzt hier die bits ermitteln 0 oder 1 von MyByte????

}

}



  return 0;
}


Im Terminal kommt folgendes

00 00 06 5F 06 00 ergibt=="!" ist korreckt.

nun muß ich die einzelnen werte bitweise auslesen und prüfen ob =1 oder
=0.

zb

0x00= kein pixel 8x
0x06 =00000110
übersetzt bit 8=kein pixel
übersetzt bit 7=kein pixel
übersetzt bit 6=kein pixel
übersetzt bit 5=kein pixel
übersetzt bit 4=kein pixel
übersetzt bit 3= pixel setzten
übersetzt bit 2= pixel setzten
übersetzt bit 1=kein pixel

dieses muß ich in einer schleife prüfen..

von Stefan (Gast)


Lesenswert?

Was du gemacht hast, verstehe ich aus deiner Beschreibung nicht.

Mit

char data
for (i=0;i<6;i++)
{
   data=Font6x8[i+6];
   ...

greifst du auf ein Array im RAM des ATmega128 zu. Und zwar auf das 0+6.
bis 5+6. Element. Die bisher gezeigte Deklaration des Arrays mit

static uint8_t _attribute_ ((progmem)) Font6x8[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // "(space)"
  0x00, 0x00, 0x06, 0x5F, 0x06, 0x00, // "!"  0+6. bis 5+6. Element
  ...

legt KEIN Array im RAM an. Um ein Array im RAM anzulegen müsste das
_attribute_ ((progmem)) weg.

Warum dein Beispiel #1 nicht läuft bzw. #2 und #3 doch, kann ich ohne
lauffähigen Code nicht beurteilen. Allein die einsam, syntaktisch
falsch rumstehende Zeile "char data" macht mich schon skeptisch. Und
wieso du jetzt in Beispiel #3 auf eeprom_read_byte() wechselst,
verstehe ich auch nicht.

Egal - Zu der Bittesterei und Bitschieberei sollte dir dieser
Codeabschnitt bekannt vorkommen ;-)
1
      for(j=0; j<8; j++) {
2
        if(data & 0x01) {     // <==== !!!!
3
          if(skipped) {
4
            n6100GotoXY(xCoord, yCoord);
5
            sendCMD(MEM_WRITE);
6
            n6100DrawPixel();
7
          
8
            skipped=0;
9
          }
10
          n6100DrawPixel();
11
          yCoord++;
12
        } else {
13
          skipped=1;
14
          n6100GotoXY(xCoord, ++yCoord);
15
        }
16
        data >>= 1;           // <==== !!!!
17
      }

von MarcusM (Gast)


Lesenswert?

Hallo

habe es geschaftt nun muß ich den code flexible machen

geht mit fest eingestellten werten für font 6x8 und 12x 16.

Hier der Code

nt drawchar(char c)
{
sendCMD(MEM_ACCESS_CTRL);
  memAccessCtrl |= (0x01 << VERT_WRITE);
  sendData(memAccessCtrl);

   uint16_t index;
 uint8_t myByte;
 c -= 32;
  index = c*24*(8/8);

window(2,17,2,13); /Display Speicher definieren für das Zeichen
char* zahl;
  int i;
    int u;
  for (i=0;i<24;i++)
{    myByte=eeprom_read_byte(&Font12x16[index++]);

  for (u=0;u<8;u++)
{

if(myByte & 0x01)
{
sendData(RED);
}
else
{
sendData(WHITE);

}
myByte >>= 1;
}


}

  //}


  return 0;
}


ich übergeb ein A an die Funktion

Besten Dank für eure Hilfe und eure guten Tips ohne diese hätte ich
graue Haare.

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.