Kommt es mir nur so vor, oder sind die Datenblatter von neueren AVRs nur eine Kopie von alten Datenblättern, in denen die Hälfte vergessen wurde umzuschreiben ? Hier ein Beispiel: mega48, Seite 175 USART Initialisierung. Versucht mir Copy&Paste alles in AVR Studio zu bringen. Geht nicht das Datenblatt ist Kopiergeschützt. Also alles abgetippt: ldi temp, 25 out UBRR0L, temp ldi temp, 0 out UBRR0H, temp ldi temp, (1<<TXEN0) out UCSR0B, temp Nur leider läuft der Code so nicht: Building project... AVRASM: AVR macro assembler 2.0.28 (build 121 Jan 11 2005 10:28:51) Copyright (C) 1995-2005 ATMEL Corporation C:\8051\AVR\motiondet\motiondet.asm(1): Including file 'C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc' C:\8051\AVR\motiondet\motiondet.asm(63): error: Operand 1 out of range: 0xc4 C:\8051\AVR\motiondet\motiondet.asm(66): error: Operand 1 out of range: 0xc5 C:\8051\AVR\motiondet\motiondet.asm(69): error: Operand 1 out of range: 0xc1 Assembly failed, 3 errors, 0 warnings
"das Datenblatt ist Kopiergeschützt." Ghostscript/Gsview verwenden. "Operand 1 out of range: 0xc4" Mit den IN/OUT-Befehlen sind die nicht adressierbar. LDS/STS verwenden. Etwas dusselig von Atmel, das ist wahr.
Wie hast Du denn temp definiert? Bei mir geht das so. Grüße Andreas
Bis zu welchen Adressen funktioniert denn in/out ? In der Hilfe vom AVRStudio steht nichts darüber. Mit STS geht es bei mir, aber trotzdem ist das von Atmel ein großer Fehler, sowas abzudrucken. Und das ist nicht der einzigste. Wenn es die erste Version eines Datenblatts wäre, dann könnte man das ja noch verstehen, aber den ATmega48 gibt es jetzt schon seit über einem Jahr. @Andreas .def temp =r16 Geht das bei dir wirklich ? Seltsam.
Ja, bei den neuen Megas stimmt absolut nichts mehr, die IO-Adresen wurden total durcheinander gewürfelt. Fast alles wurde nun in den Memory-Bereich verlegt, (Timer, UART, Interrupts usw.), dafür ist im IO-Bereich gähnende Leere (nur noch die Portpins). Statt IN/OUT ist nur noch LDS/STS benutzbar (Mehr Zyklen, mehr Words benötigt, kein Bit setzen/testen möglich). Die Änderungen sind jedenfalls völlig sinnfrei und ausschließlich dazu geeignet, den Übergang von älteren AVRs drastisch zu erschweren. Warscheinlich ist da ein neuer Entwicklungschef am Werk, der unbedingt seine Duftmarken hinterlassen mußte (Wie das Straßen umbennen bei neuen Politikern). Achtung ! Es sind auch einige Bits in völlig andere Register gewandert !!! Z.B. INT0 von GICR (Bit 6) nach EIMSK (Bit 0). Peter
Hallo, in Kapitel 4 "About Code Examples" des Datenblattes des Mega88 wird darauf hingewiesen, daß es sein kann, daß der Anwender eventuell die Code-Schnipsel an dieser Stelle noch anpassen muß. Das ist also nicht unbedingt ein Fehler im Datenblatt (auch wenn es natürlich besser wäre, wenn der richtige Code im Datenblatt zu finden wäre). Gruß Schmidle
"Warscheinlich ist da ein neuer Entwicklungschef am Werk, der unbedingt seine Duftmarken hinterlassen mußte" Mir scheint es eher eine Vereinheitlichung zu werden. Bisher hatten die AVRs am oberen Rand (Mega128) das Problem, einige Ports nicht mehr bitweise adressieren zu können während es beim USART/SPI/ADC Data Register möglich aber komplett sinnlos war. Manche Entwcklungen schleppen historischen Mist halt ewig mit sich rum, manche trennen sich beizeiten davon.
Hi Niemand ist vollkommen. Trotzdem sind die Datenblätter der AVRs von Atmel die informativsten die ich kenne. Vergleicht das mal mit denen anderer Hersteller. MfG HG
Wenn man STS verwendet, muss man doch zu jeder Adresse 0x20 hinzuaddieren, oder ? Das Beispiel wäre also so korrekt ? ldi temp, 25 sts UBRR0L+0x20, temp ldi temp, 0 sts UBRR0H+0x20, temp ldi temp, (1<<TXEN0) sts UCSR0B+0x20, temp
Andersrum. Bei IN/OUT muss man 0x20 für die Codierung abziehen. Glücklicherweise übernimmt das bereits der Assembler.
Sorry, falsche Perspektive. 2mal rumgedreht und immer noch verkehrt herum. Aus Sicht der RAM-Adressierung zieht man für IO 0x20 ab, aus Sicht der IO-Adressierung kommt beim Speicheradressierung 0x20 drauf.
Ich hab's ja nicht glauben wollen, aber Atmel hat hier das wohl dümmstmögliche vollbracht. Es hängt von der Register-Adresse ab. Ist das Register mit IN/OUT adressierbar, stimmt es bei LDS/STS nicht und benötigt einen Offset. Ist es hingegen mit IN/OUT nicht adressierbar, dann stimmt es bei LDS/STS ohne Offset. Das jedenfalls geht aus den Werten im Include-File hervor. Man kann also nicht einfach ins Blaune hinein STS verwenden. Folglich muss man erst einmal rausfinden, welcher Prozessor es ist. Dann in der Doku nachsehen wo das Teil liegt, und kann erst adressieren. Und beispielsweise grad die UART indirekt zu adressieren, ist arg fehlerträchtig, weil die beim Mega128 in verschiedenen Bereichen liegen. Beim Mega2560 aber nicht. Empfehlung also: unbedingt Makros für die I/O verwenden, und den Makro die Entscheidung zwischen IN/OUT und LDS/STS treffen lassen. Nur so wird das erträglich.
>Empfehlung also: unbedingt Makros für die I/O verwenden, und den Makro
die Entscheidung zwischen IN/OUT und LDS/STS treffen lassen. Nur so
wird das erträglich.
Sehr inetressant, da ich mir gerade einen Mega48-20 bestellt (und auch
bekommen) habe. Trifft das da auch zu? Sicher...
Da mein schnullibasic den sicher noch nicht kennt, werde ich wohl in
ASM rann müssen. Mir wäre sowieso nichts übrig geblieben, da es rel
Zeitkritisch ist, was ich da machen muss.
eigentliche Frage:
Wie sieht so ein Makro aus, welches selbst erkennt, ob die IO Adresse
mit STS oder mit IN/OUT angesprochen werden kann?
Danke
Axel
naheliegend: die Adressen der IO-Namen sind in der jeweiligen *.inc definiert. Im Macro wird nachgesehen, ob dieser Wert innerhalb oder ausserhalb der üblichen Grenzen des IO Bereichs liegt und entsprechend verfahren. Ich hatte befürchtet, man muss jeden AVR Typ angeben und entsprechend verzweigen. So ist es aber beherrschbar und einleuchtend. Danke für den Tip mit der Appnote avr001! Beispiel daraus:
1 | ;********************************************************* |
2 | ;* Byte access anywhere in IO or lower $FF of data space |
3 | ;* STORE - Store register in IO or data space |
4 | ;* LOAD - Load register from IO or data space |
5 | ;********************************************************* |
6 | |
7 | .MACRO STORE ;Arguments: Address, Register |
8 | .if @0>0x3F |
9 | sts @0, @1 |
10 | .else |
11 | out @0, @1 |
12 | .endif |
13 | .ENDMACRO |
14 | |
15 | .MACRO LOAD ;Arguments: Register, Address |
16 | .if @1>0x3F |
17 | lds @0, @1 |
18 | .else |
19 | in @0, @1 |
20 | .endif |
21 | .ENDMACRO |
Viele Grüße AxelR.
wenn wir schon dabei sind: ATmega88, Seite 297 "Write Program Memory Page" Statt "000a aaaa bbxx xxxx" ist "0000 aaaa bbbx xxxx" richtig. Gruß, JPR
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.