ATMega644 - wahlfreies Schreiben auf Register

Gast #1206140
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
Gast
>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.
Moderator Persönliche Seite
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...
Gast
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)
Gast
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. ;-)

...
Moderator Persönliche Seite
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.
Gast
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.