mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega644 - wahlfreies Schreiben auf Register


Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Εrnst B✶ (ernst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch wenn ich vor der Antwort irgendwie Angst habe:
WARUM?

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: jupp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was willst du damit? was spricht gegen

REG = data

oder besser

REG = ((1 << BIT_NAMEa) | (1 << BIT_NAMEb)) ...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
static inline
uint8_t read_addr(uint16_t addr)
{
  return *(volatile uint8_t *)addr;
}

static inline
void write_addr(uint16_t addr, uint8_t data)
{
  *(volatile uint8_t *)addr = data;
}

Use at your own risk.  Avoid shooting into your foot...

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. ;-)

...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.