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? :)" };
Ja aber ich benötige die Werte von data. bei mir kommt nur müll nicht nachvollziebar.
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]
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).
@ 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.
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; }
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!
Ja aber welche GCC Version? Achte auf die Versionsnummer in dem Ausgabefenster vom Programmers Notepad 2 wenn du Make All machst...
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 ???
"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.
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.
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
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????
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..
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.