Hi! Vorab einmal, ja ich habe die Suche benutzt und auch etwas gefunden. Nur leider verstehe ich das noch nicht so ganz mit Progmem. http://www.mikrocontroller.net/forum/read-2-94515.html#new Diesen Thread habe ich mir mal zu Hilfe genommen. Vielleicht würde ich ja damit ein Programm zum laufen bringen, allerdings ist es das alleine nicht, ich möchte auch begreifen, wesshalb das so gemacht werden muss. Wesshalb kann ich zum Beispiel nicht einfach schreiben: >const char SHOW0[] PROGMEM = "BRAUCHWASSER"; >lcd_puts(SHOW0); Ich meine, wesshalb wird da noch so etwas wie strcpy_P (buf, SHOW[0]); Verwendet? Für meine Anwendung möchte ich vorerst nur einmal einen String als Progmem speichern und diesen über den Uart ausgeben. Die Funktion für den uart habe ich bereits und die funktioniert auch. Unter anderem habe ich eine Funktion, die nur ein einzelnes Byte sendet. Die möchte ich in der art wie z.B. UART_SendByte(daten[20]); verwenden, um nur ein einzelnes byte zu senden. Nun aber, wie bringe ich das nun hin, dass der string "daten" eben ein als progmem definierter String ist und was muss ich eventuell noch beachten? Sorry für die Anfängerfragen, aber bis jetzt habe ich für etwa 4 Jahre nur in Basic / Visual Basic programmiert, da ist der Umstieg zu C schon nicht gerade einfach. :-( mfg Nik
Ok, ich habs nun hinbekommen, die als progmem zu definieren und auch auszulesen. Nur die bytes sind die falschen. Nun habe ich in einem anderen Thread etwas über pointer gelesen... Aber wie mache ich das mit diesem Pointer nun genau, wenn der progem string bei mir so ausschaut: PROGMEM char MUSIK[] = { 0xFF,0xE3,0x18,.....} ??
Mittlerweilen habe ich einiges schon selbst herausgefunden-ich hab mir jetzt eine eigene Funktion gemacht die eigentlich mit Hilfe eines Pointers die Werte auslesen sollte: void send_prg(uint16 count, uint16 *zeiger) { while (count--) { UART_SendByte(*zeiger); *zeiger++; } } Aufrufen tue ich das ganze zum Beispiel mit send_prg(5, MUSIK); wobei MUSIK der String vom obigen thread ist. Nun kriege ich trotz dem Pointer aber immer noch falsche Werte, an was liegt denn das nun? mfg Nik
Die Dereferenzierung des Pointers 'zeiger' in dieser Zeile UART_SendByte(*zeiger); weiss nicht, daß das ein progmem-Pointer ist; Du wirst hier eine der Zugriffsfunktionen auf den Flash-Speicher verwenden müssen. UART_SendByte(pgm_read_byte(zeiger));
"undefined reference to 'pgm_read_byte'" Und das, obwohl ich pgmspace.h included habe. aber dennoch danke-gibts evtl noch eine andere Möglichkeit das mit einem alten gcc(3.3.3) zu lösen? Denn ich kann kaum den ganzen Rest des Programms ändern...
Ich habe das vor einiger Zeit auch mal gemacht: Nimm unten die Zeile mal als Basis. PGM_P Pointer = (PGM_P)pgm_read_word((int)datensaetze +Index* sizeof(PGM_P)); datensaetze ist als PGM_P datensaetze[15] PROGMEM {ersterstring, 2ter, usw...}initialisiert. ersterstring usw sind als "const prog_char" abgelegt. In Pointer steht dann das Zeichen das du ausgelesen hast.
. "undefined reference to 'pgm_read_byte'" Und das, obwohl ich pgmspace.h included habe. Tja, was soll man da machen? Was steht denn in Deiner Version von pgmspace.h drin? Und was hat das mit der Version von gcc zu tun, das ist doch die avr-library, zu der pgmspace.h gehört ...
>Tja, was soll man da machen?
Tja, das frage ich mich eben auch, pgmspace.h included progmem.h
Doch in progmem finde ich die funktion pgm_read_byte auch nicht
ansatzweise, heisst denn der befehl bei einer früheren libc version
anders?
hey, danke, so scheints schon zu funktionieren, naja, jedenfalls fast :) Beim compilieren krieg ich nun keine fehlermeldung mehr, allerdings kriege ich immernoch wirre Zeichen... Meine Funktion sieht nun so aus: void send_ascii(uint16 count, unsigned char *zeiger) { while (count--) { UART_SendByte(PRG_RDB(*zeiger++)); } } dann habe ich eine Variabel: PROGMEM char test[] = "hallo"; Und das ganze rufe ich dann so auf: send_ascii(5,test); Ich empfange aber blos Datensalat, allerdings ist das Problem reproduzierbar, auch nach einem Reset des uc erhalte ich genau dieselben bytes. Ein Problem mit dem Uart ist es aber nicht, denn wenn ich mit UART_SendByte(); direkt ein Byte sende, kommt dieses korrekt an...
Kein Wunder, daß das nicht funktioniert: UART_SendByte(PRG_RDB(*zeiger++)); Du lässt immer noch den Compiler den Pointer dereferenzieren, und das geht in die Hose. PRG_RDB will aber -ebenso wie das neuere pgm_read_byte- einen Pointer als Argument übergeben bekommen. Lass' in der Zeile mal den '*' weg und sieh' Dir das Macro PRG_RDB genau an, ob es sich mit dem ++-Operator verträgt. Bei Unklarheiten solltest Du das sicherheitshalber so schreiben: UART_SendByte(PRG_RDB(zeiger)); zeiger++; Wird's klarer?
oho, schon viel besser :P Nur ein Problem habe ich noch: Originaldaten: 0xFF,0xE3,0x18,0xC0,0x00,0x00,0x00,0x03,0x48,0x01,0x80,0x00,0x00,0xFF,0x 0C,0x5E... empfangene Daten: 0xFF 0x18 0x00 0x00 0x48 0x80 0x00 0x0C 0x02 0x00 0x00 0x54 0xFC 0x10 0x60 0x30 es scheint, als ob der pointer irgendwie immer um 2 inkrementiert wird, ich bekomme einfach nur immer jedes zweite byte-doch wesshalb? >UART_SendByte(PRG_RDB(zeiger)); > zeiger++; >Wird's klarer? Ja allerdings, nur verstehe ich noch nicht ganz wesshalb man den stern dann auch weglassen muss-?
Den Stern musst Du weglassen, weil der der Operator zur Pointerdereferenzierung ist. Und genau die kann der Compiler mit ROM-Pointern nicht durchführen. Du weißt nicht, was eine Pointerdereferenzierung ist? ->K&R lesen. Das mit dem "zwei Bytes weiterspringen" wird wohl an der 16 Bit breiten Organisation des Flash liegen; hier kann ich nur auf die Dokumentation der avr-libc verweisen und Dir außerdem ein Update auf die aktuelle Version nahelegen; mich wundert, daß das noch kein anderer getan hat.
>16 Bit
breiten Organisation des Flash liegen
DANKE :D es war zwar nicht dies, aber ich war zu blöd den Pointer 16
bit breit anzulegen...
zuerst hatte ich (uint16 *zeiger)
so funktionierts aber:
void send_hex(uint16 count, uint8 *zeiger)
{
..
}
ich verstehe allerdings nicht wirklich wesshalb, die adresse wird ja
wohl höher sein als nur 8bit also höher als 0xff.
Naja, wenigstens funktioniert es einmal :)
Vielen Dank Rufus-ich werd dann mal versuchen das
ganze über spi statt den uart zu senden-und zwar an einen vs1001k...
mfg Nik
. "zuerst hatte ich (uint16 *zeiger) so funktionierts aber: (uint8 *zeiger) ich verstehe allerdings nicht wirklich wesshalb, die adresse wird ja wohl höher sein als nur 8bit also höher als 0xff." Das ist Grundlagenwissen in C. Ein Pointer, der auf einen bestimmten Datentyp verweist, wird beim Inkrementieren mit ++ um die Anzahl an Bytes erhöht, die ein Objekt des Datentyps im Speicher belegt. Also: sizeof (uint16) == 2, ++ erhöht den Pointer um zwei. sizeof (uint8) == 1, ++ erhöht den Pointer um eins. sizeof (uint32) == 4, ++ erhöht den Pointer um vier. Die Pointer selbst sind alle gleich groß, egal, auf was für Datentypen sie verweisen. Literaturhinweis: K&R, Programmieren in C, zweite Auflage, Hanser Verlag.
>Also: >sizeof (uint16) == 2, ++ erhöht den Pointer um zwei. >sizeof (uint8) == 1, ++ erhöht den Pointer um eins. >sizeof (uint32) == 4, ++ erhöht den Pointer um vier. vielen dank, ich denke ich hab das mit den pointern endlich begriffen lol Wenn das alles in dem Buch steht, ist das sicherlich eine Anschaffung Wert:P Tja, ich muss sagen, ich krieg langsam Freude an C, das erste mini mp3 file (5sekunden) mit progmem läuft :D Jetzt fehlt "nur" noch ata und fat...hmpf Das ganze soll am Schluss so werden wie yampp, nur möchte ich dabei das Programm auch verstehen und ein bisschen mehr machen, als harware zusammenlöten und fertig ists... Falls ich das alles mal geschafft habe möchte ich auch noch mit einem iim7000a eine netzwerkanbindung machen-aber das ist wohl noch ein langer weg ;-)
mist, ich habe mal nach dem buch gesucht, allerdings auch im internet nicht allzuviel gefunden, hättest du vielleicht die isbn nummer gerade zur hand? :)
Einmal bei amazon.de nach 'Programmieren in C' gesucht und gleich gefunden: http://www.amazon.de/exec/obidos/ASIN/3446154973/qid=1118835571/sr=8-1/ref=pd_ka_1/302-0941719-1791258 Volkmar
http://www.lob.de/cgi-bin/work/outputexpert?id=42b01783102b3&frame=yes&flag=new&menupic=yes&mode=viewone&titnr=707552&linkcol=005c21&stich=+kernighan+&katalog=255 Vorteil von Lehmanns: Lieferung in Deutschland ohne Versandkosten.
hehe danke, ich habs nun auch gefunden(bei www.books.ch) da ich aus CH bin würde ich allerdings dennoch versandkosten haben bei Lehmanns. Naja dann hol ichs eben im Laden, dann hab ich auch keine Versandkosten ;-)
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.