Hi Leute. Ich versuche gerade folgendes schneller zu machen.
Es ist in einer Interrupt Routine und soll folgendes Bewirken:
Sagen wir es gibt den CNT_PORT. Ein Port, wo an den untersten 4 Bits
ein 4/16 Decoder hängt(74HCT154). Ich möchte jetzt den Zähler immer von
0-15 durchzählen ohne den Rest vom Port zu verändern.
Folgendes habe ich mir dabei ausgedacht:
1
cli
2
3
intemp1,CNT_PORT//Aktuellen Counterport in temp1
4
movtemp2,temp1//Sicherungskopie nach temp2
5
6
inctemp1//Um 1 erhöhen
7
anditemp1,0b00001111//untersten 4 Bits bleiben über
8
9
anditemp2,0b11110000//untersten 4 Bits löschen
10
ortemp2,temp1//Die untersten 4 Bits aus temp1
11
12
outCNT_PORTtemp1//Alles wieder ausgeben
13
14
sei
Ausgenommen der Register-Sicherungsroutinen.
Habt ihr nen Vorschlag wie ich das beschleunigen könnte?
Lass cli und sei weg, das macht der AVR selbst.
Den Rest kriege ich momentan auch nicht optimaler...
SREG-Sicherung und Registersicherung hast du aber sicherlich drin.
...
Wenn Du die oberen vier Bits verwenden würdest, dann könntest Du Dir die
ganze "Verunderei" sparen:
in temp1,CNT_PORT
addi temp1,0x10
out CNT_PORT,temp1
Nicht schlecht die Idee. So habe ich einen Hardwaremäßigen Overflow.
Aber das is nix, da ich alles schon verdrahtet habe.
@Hannes: Ah, war mir nicht sicher wegen cli und sei. Ist ja
aufjedenfall nötig. Nicht dass ein anderer Interrupt den PORT
zwischendurch noch ändert, während ich da am rumoperieren bin.
Ja sicherung habe ich drin
Du könntest den Wert in CNT_PORT in zwei separaten Registern speichern.
Eines der Register ist der Zähler bis 15 und das andere enthält die
obersten 4 Bits.
exor r31, r30
inc r30
andi r30, 0x0F
or r31, r30
out CNT_PORT, r31
In r30 der Zähler, in r31 die obersten 4 Bits, macht 2 Taktzyklen
weniger, dafür 2 Register mehr verbraucht.
oder
inc r30
brsh @1
subi r30, 0x10
@@1:
out CNT_PORT, r30
Hier wird in r30 beides gespeichert, sowohl der Zähler und die obersten
4 Bits. Sollte nun der Zähler bei 16=0x10 überlaufen so wird das
Half-Carry-Flag gesetzt und wir müssen einfach 0x10 abziehen.
Macht dann 4 Taktzyklen und 1 Register.
Gruß hagen
Macht 5 Takte. 1Register Hihi.
Frage: Ist
subi temp1, -0x10
das equivalent zu
addi temp1, 0x10
Ich meine das so in Erinnerung zu haben. Man subtrahiert ja mit einem
negativen Wert, um zu addieren, oder?
Hi!
Guten Morgen Simon!
Den Code den Du da Reingestellt hast zählt meiner Meinung nach
Rückwärts!
Ich progge momentan auf 8051 Derivate und hab mal ein Equivalent dazu
geschrieben (siehe Anhang).
Gruß xyz
Hallo xyz:
Das Problem ist, dass der AVR kein Befehl hat, um ein Immediate zu
addieren (Oder ich habe ihn schlicht übersehen). Man kann nur 2
Register addieren.
meinermeinungnach sollte aber zum Beispiel
ADDI reg, 0x01
das gleiche sein wie
SUBI reg, -0x01
bsp:
0b00000000 steht im Register
0b11111111 soll abgezogen werden (entspricht -0x01)
0b00000000 Registerwert
0b00000000 Komplement von -0x01
---------- addieren
0b00000001 Kein Overflow, 1 addieren
So seh ich das.
Hi
Für vorzeichenlose 8-Bit Zahlen
enspricht subi reg,-1 "addi" reg,1.
Wenn du ein Doppelregister frei hast kannst du auch adiw/sbiw
benutzen und nur das Low-Byte verwenden.Geht aber nur bis max.
+/-63.
Mfg HG