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.