ich hab ein Problem mit den uCs, ich bin mir nicht sicher, ob ich es
richtig kapiert habe:
Atmega 88-20-PU
Hab ich das richtig verstanden - das Bauteil hat 32 "Register" von 0-31
- also 32 8bit-große Variablen, die ich zum Speichern von Sachen hab,
z.B. Messergebnisse von ADC-Messungen oder als Speicher für
Statusregister für die I/O-Zustände der Beinchen etc.?
aber wie ist das mit dem Programm? Wenn ich ein Programm schreibe, dann
muss das auch irgendwo gespeichert werden. Passiert dass dann an anderer
Stelle, die Nichtregisterstellen sind?
Bastelecke schrieb:> Passiert dass dann an anderer> Stelle, die Nichtregisterstellen sind?
Ja, und zwar im sogenannten Flash-Speicher, auch Programm-Speicher
genannt.
Es gibt einen Flash-Speicher, sowas ähnliches wie SD-Karte oder
USB-Stick im Mikrocontroller, auf den wird das Programm geschrieben.
Außerdem hast du noch einen EEPROM, das ist auch ein nichtflüchtiger
Speicher, z. B. für Einstellungen. Etwas RAM hat der Controller
natürlich auch.
Die Speicher von 0 .. 31 sind Register.
Diese dienen zum Rechnen, vergleichen u.s.w.
Zusätzlich gibts noch Programmspeicher, RAM als Datenspeicher und EERAM
als nicht flüchtiger Datenspeicher.
Das ist ne ganze Menge.
Joe
ich habe mir ein avr-ISPMK2 gekauft und ein paar Micocontroller atmega
88-20PU, wenn ich jetzt rumprobiere, dann brauche ich mir wegen des
Abspeicherns von dem Programm keine Gedanken machen ???, sondern muss
nur ggf. aufpassen, dass ich die Datenregister 0-31 nicht ggf. doppelt
von der einen oder der anderen Routine verwende, damit die nicht
ausversehen überschrieben werden?
das mit den Registern steht so explizit nicht in dem Tutorial drinnen,
zumindest hab ich es daraus nicht erlesen, darum fragte ich
vorsichtshalber nach, bevor da was kaputt geht.
Hi
>das mit den Registern steht so explizit nicht in dem Tutorial drinnen,>zumindest hab ich es daraus nicht erlesen, darum fragte ich>vorsichtshalber nach, bevor da was kaputt geht.
Kaputt kann da nichts gehen. Aber kläre uns mal über deine bevorzugte
Programmiersprache auf.
MfG Spess
Ich lagere Register-Inhalte Werte gerne im SRAM aus um die Register auch
anderweitig verwenden zu können.
.DSEG ;Reserve jeweils 1 Byte / Variable im SRAM
Steuerbyte1: .byte 1
Steuerbyte2: .byte 1
Ergebnis1: .byte 1
Ergebnis2: .byte 1
Im Programm dann
sts Steuerbyte1, temp ;speichere Registerinhalt von temp im
SRAM(Reservierte Stelle)
;temp kann nun im Programm für andere Sachen
benutzt werden
lds temp, Steuerbyte1 ;Lade SRAM Inhalt Steuerbyte1 ins Register temp
ich habe mal bei dem AVR-Studio etwas gefunden - das nennt sich io-view.
Sind das dadrinnen die gesamten Register, die der jeweilige uC hat?
Ich hab mir in dem AVR-Tutorial verschiedene Assemblerprogramme
angeschaut.
ldi r16, 109 ; Dividend
ldi r17, 9 ; Divisor
; Division r16 : r17
ldi r18, 8 ; 8 Bit Division
clr r19 ; Register für die Zwischenergebnisse / Rest
clr r20 ; Ergebnis
Die Programme arbeiten immer ab dem Register r16. Was ist mit den
Registern r0 bis r15 - sind die für andere Sachen bestimmt oder könnte
ich die dazu auch verwenden?
Es gibt auch diese Carry-Flags. Gibt es insgesamt nur ein einziges
Carryflag in dem ganzen uC oder für jeden Befehl?
Bastelecke schrieb:> sondern muss> nur ggf. aufpassen, dass ich die Datenregister 0-31 nicht ggf. doppelt> von der einen oder der anderen Routine verwende, damit die nicht> ausversehen überschrieben werden?
Aufpassen muß man immer. Baum Aufruf von Unterprogrammen sichert man am
Anfang des Unterprogramms die Register, die man benutzt und stellt sie
vor dem Verlassen wieder her. Dafür gibt es spezielle Befehle: push und
pop.
Insbesondere bei Interrupt Service Routinen ist das wichtig, da diese
irgendwann aufgerufen werden.
Bastelecke schrieb:> Sind das dadrinnen die gesamten Register, die der jeweilige uC hat?
Das sind die Register, mit denen der Controller konfiguriert wird, z.B.
Timer, AD-Wandler, UART.
Bastelecke schrieb:> Die Programme arbeiten immer ab dem Register r16. Was ist mit den> Registern r0 bis r15 - sind die für andere Sachen bestimmt oder könnte> ich die dazu auch verwenden?
Da bist du völlig frei. Nur die obersten sechs, R26 - R31, haben
spezielle Zusatzfunktionen, X-, Y-, Z-Register.
Bastelecke schrieb:> Es gibt auch diese Carry-Flags. Gibt es insgesamt nur ein einziges> Carryflag in dem ganzen uC oder für jeden Befehl?
Das gibt es nur einmal und steht im Statusregister. Das zeigt den
Überlauf einer Operation an.
mfg.
Ich hab jetzt wie in dem AVR-Turorial mal das Assemblerprogramm nicht
auf den uC übertragen, sondern in dem AVR-Studio simuliert.
Dabei hab ich folgendes Problem - ich habe mir ein kleines Programm
geschrieben:
.include "4433def.inc" ; bzw. 2333def.inc
.def temp1 = R16
ldi R16, 0x10
ldi R17, 0x22
loop:
inc temp1
out PORTB, temp1
rjmp loop
in meinem Bild vorhin hab ich doch die IO-Ports abgebildet. Wenn ich im
Debug-Modus bin und mit F11 Schritt für Schritt durchgehe, dann sehe ich
in dem Fenster "Processor" bei jedem Schleifendurchlauf R16 um eins
erhöt. Aber ich übertrage doch mit out PortB, temp1 den Wert temp1 in
PortB. Jetzt müssten doch eigentlich in dem Fenster IO-Ports unter PORTB
bei jedem Schleifendurchgang welche von den Bits leuchten und andere
nicht, da der Wert ja nicht mehr 0x00 ist, sondern ein anderer. Aber da
leuchtet nix auf und ich weis icht, warum :-(
Bastelecke schrieb:> .include "4433def.inc" ; bzw. 2333def.inc> .def temp1 = R16>> ldi R16, 0x10>> ldi R17, 0x22>> loop:> inc temp1> out PORTB, temp1> rjmp loop
Ich kenne zwar die Eigenheiten des Simuators nicht, aber in jedem Fall
ist der Port nicht als Ausgang gesetzt.
mfg.
7 und 8 bit - Ports
PORTB und PORTD sind 8bit groß,PortC nur 7bit.
Ist der Register für PORTC beim uC in Wahrheit auch 8bit groß, nur er
verwendet blos die 7bits zum Senden eines Pegels später an die durch
PORTC vertretenen Beinchen des uCs?
Thomas Eckmann schrieb:> Ich kenne zwar die Eigenheiten des Simuators nicht, aber in jedem Fall> ist der Port nicht als Ausgang gesetzt.>> mfg.
ich hab den Fehler gefunden. Bei .include stimmte die Bezeichnung des
uCs nicht mit der gewaehlten Bezeichnung des uCs für das Projekt nicht
ueberein.
Bastelecke schrieb:> Ist der Register für PORTC beim uC in Wahrheit auch 8bit groß, nur er> verwendet blos die 7bits zum Senden eines Pegels später an die durch> PORTC vertretenen Beinchen des uCs?
Die Register sind immer 8 Bit.
Bei PORTC ist der fehlende Pin intern auf 0 gelegt.
mfg.
wenn ich mir mit .def einen Alias z.B. für r16 erzeuge oder einen Wert
zuweise, verbraucht dies auch Speicher oder codiert das der Compiler
beim Hexdateimachen später wieder weg?
der Compiler setzt dann z.B. jedes temp wieder auf r16 bzw. dessen
Adresse um. Ist nur ne Erleichterung zum Programmieren, im Hexcodes gibt
es keinen Unterschied.
im Datasheet steht zu dem uC
– 6-channel 10-bit ADC in PDIP Package
Damit müsste der Register für den ADC aber doch 10-bit breit sein und
nihct 8bit, also 10 Kästen müssten doch bei den IO-Ports für den ADC
irgendwo stehen, ist aber nicht der Fall.
Was mache ich in so nem Fall, muss ich dann "theoretisch" gesehen zwei
Register verwenden, z.B. r1 und r2, um 10 Bit darstellen zu koennen und
damit zu rechnen etc. ???
Lies einfach weiter im Datenblatt. Da steht die Antwort auf Deine Frage
und noch mehr.
Ich bin sogar ein bischen gerührt wenn ich lese wie eifrig und naiv Du
fragst. Aber wie soll das jetzt weiter gehen? Du kratzt hier gerade mal
an ein paar Ecken an der Oberfläche. Das Thema ist aber weitaus
umfangreicher.
Mit der Methode hier beschäftigst Du uns über Jahre um Dich das zu
lernen.
Ich würde Dir empfehlen erstmal ein paar Grundlagen zu lesen und die
Tutorials hier durchzuarbeiten. Dann wird Dir manches klarer werden.
es gibt 2 Register in einem werden die oberen 2 Bits also 9 und 8 und im
2tem Register die unteren 7-0 gespeichert. Es gibt das ADLAR Bit dann
landen die oberen Bits 9-2 in einem Register und die unteren 1-0 im 2tem
Register die man einfach nicht beachten muss um ein 8 Bit Ergebniss zu
haben.
Einfach mal im Datenblatt stöbern
ich will eine if-Abfrage machen. Dazu habe ich im Internet folgendes
gefunden:
Quelle:
http://www-ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/seminare/assembler.shtml
"und müssen daher mit Hilfe von gotos ausgedrückt werden:
if (a != 4711)
goto ungleich
gleich: ...
goto weiter:
ungleich: ...
weiter: ...
Im 80x86 Assembler sieht das dann so aus:
cmp eax,4711
jne ungleich
gleich: ...
jmp weiter
ungleich: ...
weiter: ..."
naja, die Befehle cmp, jne gibt es nicht, ähnliche sind wohl cp, cpi...
ich hab das jetzt so verstanden, dass wenn das Ergebnis des Vergleiches
true ist, dann erfolgt der naechste befehl dierekt danach
r16 soll bis zu dem Wert 5 ausgeführt werden. Aber es klappt noch nicht,
wo ist der Fehler??
.include "m88def.inc"
ldi R16, 0x0
loop:
inc r16 ;r16 inkrememtieren
cpi r16, 5; vergleich, ob Inhalt r16 schon 5
rjmp loop ; wenn r16=5, dann rjmp loop, ansonsten nix -
programmende.
Thomas O. schrieb:> es gibt 2 Register in einem werden die oberen 2 Bits also 9 und 8 und im> 2tem Register die unteren 7-0 gespeichert. Es gibt das ADLAR Bit dann> landen die oberen Bits 9-2 in einem Register und die unteren 1-0 im 2tem> Register die man einfach nicht beachten muss um ein 8 Bit Ergebniss zu> haben.>> Einfach mal im Datenblatt stöbern
Ich hab hier nochmal das Bild mit den IO-Ports angefügt. Ist das, was Du
mir geschildert hast, dann unter Analog-Converter zu finden oder unter
Analog-Converter. Bei analogconverter gibt es ein 8bit- und ein
2bit-register (ACSR, DIDR1), bei ADC_Converter gibt es 8bit ADCSRA, die
anderen Register haben alle mehr als zwei Bit. Darum verstehe ich das
nicht.
Guru schrieb:> Ich würde Dir empfehlen erstmal ein paar Grundlagen zu lesen und die> Tutorials hier durchzuarbeiten. Dann wird Dir manches klarer werden.
Die Tutorials arbeite ich doch durch, doch manchmal komm ich einfach
nicht weiter, weil ich nicht weiterweis. mit den Datenblättern hab ich
wegen dem ganzen Englischen riesengroße Probleme, so dass ich die nicht
unbedingt verstehe.