Hallo, ich scheitere als ATMega Anfänger folgende Funktion mit Leben zu füllen. void writeReg(char addr, char data) Die Funktion soll den Schreibzugriff auf alle Register ermöglichen. addr = 0...255 data = 0...255 In C kann ich ja sehr einfach einen Lesefunktion implementieren data = *addr; aber ein Schreibzugriff funktioniert leider nicht *addr = data; Am Inline Assembler bin ich bisher gescheitert, da ich keine Erfahrung im Umgang mit Operanden und Constraints habe. Die Register-Definitionen möchte ich nicht benutzen, da ich einen wahlfreien Zugriff haben möchte. Es wäre prima, wenn mir jemand mit Hinweisen und/oder Code-Beispielen helfen könnte. Danke & Gruß Uwe
Auch wenn ich vor der Antwort irgendwie Angst habe: WARUM?
>aber ein Schreibzugriff funktioniert leider nicht >*addr = data; Was heist "es geht nicht"? Grundsätzlich sollte es gehen. Du musst allerdings die Spezialitäten bei dem Adressmapping von Registern beachten. Ich kenne die Details beim 644 nicht, aber es gibt einige Register die je nach Adresslage einen Offset brauchen, je nachdem welcher Assemblerbefehl verwendet werden soll. Evtl. gibt es auch Register die garnicht gemappt sind und nur per I/O Befehl erreichbar sind (Ohne Gewähr). Ob Dein Compiler das schafft, weiss ich nicht, da meine Glaskugel mir diesen einfach nicht nennen will.
was willst du damit? was spricht gegen REG = data oder besser REG = ((1 << BIT_NAMEa) | (1 << BIT_NAMEb)) ...
Was für "Register" sind das denn? Im Adressbereich 0...31 befinden sich (außer beim Xmega) die CPU-Register, und IO-Register gibt es (je nach AVR) auch noch jenseits der Adresse 0xff, die du maximal mit einem "char" (druckbares Zeichen?) adressieren kannst.
1 | static inline |
2 | uint8_t read_addr(uint16_t addr) |
3 | {
|
4 | return *(volatile uint8_t *)addr; |
5 | }
|
6 | |
7 | static inline |
8 | void write_addr(uint16_t addr, uint8_t data) |
9 | {
|
10 | *(volatile uint8_t *)addr = data; |
11 | }
|
Use at your own risk. Avoid shooting into your foot...
Hallo miteinander, gene beantworte ich die aufgetauchten Fragen. - warum? Ich habe mir ein Monitor-Programm entwickelt, welches zum bring-up bisher gute Dienste geleistet hat. All die üblichen Kommandos funktionieren schon (flash read, eeprom read/write/fill, register read,...). Nur das register write will nicht. - was geht nicht? Der Werte [data] landet nicht in dem gewünschten Register. Wenn ich das Register mit meiner Funktion wieder auslese, steht nicht der Wert drin, bzw. die Ausgänge ändern Ihren Status nicht. Die Lesefunktion ist OK, da ich Port-Pins korrekt einlesen kann, wenn ich z.B. das externe Signal ändere. - welche Register? Eigentlich alle. Die CPU-Register 0x0 - 0x1F sind sicherlich nicht von großem Interesse. Jedoch der restliche Bereich schon. Gerne mache ich auch eine Fallunterscheidung in Abhängigkeit der gewünschten Adresse, wenn man unterschiedliche Registerbereiche unterschiedlich behandeln muss. Im Preliminary data-sheet des 644P (Seite 417, Fußnote 4) steht: When using the I/O specific commands IN and OUT, the I/O addresses $00 - $3F must be used. When addressing I/O registers as data space using LD and ST instructions, $20 must be added to these addresses. The ATmega164P/324P/644P is a complex microcontroller with more peripheral units than can be supported within the 64 location reserved in Opcode for the IN and OUT instructions. For the Extended I/O space from $60 - $FF, only the ST/STS/STD and LD/LDS/LDD instructions can be used. Daraus entnehme ich, dass ich auf alle Register mit dem asm Befehl ST zugreifen kann. Mit in und out nur auf 0x20-0x5F (bzw. 0x0 - 0x3F). Genau an dem Punkt stehe ich nun. Gruß Uwe (dl4sdx)
Mit LDS/STS/LD/ST kannst Du auf alle Register und SRAM zugreifen. Beim Mega644 wären das: 0..31: R0..r31 32..95: I/O-Bereich 96..255: Extended I/O ab 256: SRAM Wie man jetzt dem Compiler sagt, dass er LDS/STS/LD/ST benutzen soll, ist einer der vielen Gründe, warum ich C meide und in ASM werkele. ;-) ...
Hannes Lux wrote: > Wie man jetzt dem Compiler sagt, dass er LDS/STS/LD/ST benutzen soll, > ist einer der vielen Gründe, warum ich C meide und in ASM werkele. ;-) Dafür habe ich die C-Antwort aber auch schon eine Stunde früher fertig gehabt... Scheint den OP ja aber nicht weiter zu interessieren.
Hallo, vielen Dank für eure Antworten. Ich bin nun dazu gekommen die Vorschläge auszuprobieren. Das Beispiel vom Jörg Wunsch funktioniert prima. Danke für eure schnelle und kompetente Hilfe Gruß Uwe
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.