Rechteckgenerator mit ATmega8 "verschluckt sich"

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 27 5 2024  11:02:47      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte

Gehe zu Seite ( 1 | 2 Nächste Seite )      


Autor
Rechteckgenerator mit ATmega8 "verschluckt sich"

    







BID = 509099

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig
 

  


Hallo AVR-Experten!
Heute habe ich auch mal ein kleines Problem. Es ist zwar überhaupt nicht kritisch, aber ich hätte es gern prinzipiell geklärt und möchte auch etwas dabei lernen.

Kleine Vorgeschichte:
Ich habe auf meiner Arbeitsstelle ein kleines Prüfgerät für die Antriebselektronik von Turbomolekularpumpen gebastelt. (Das sind, vereinfacht gesagt, mit 1500 Umdrehungen pro Sekunde laufende Ventilatoren... ) Diese haben zur Rückmeldung ihrer Drehung zwei Hallelemente eingebaut, deren Signale die Elektronik auswertet. Da ich bei der Überprüfung der Steuerteile die angeschlossene Pumpe nur simuliere, muß ich auch diese Hall-Signale nachbilden. Dazu brauche ich einen "Tongenerator", der zwei symmetrische und komplementäre Rechteckfolgen von ~0 bis etwa 4 kHz ausgibt.
Zunächst hatte ich eine Schaltung mit einem 556 gebastelt, die auch prinzipiell funktionierte. Nur war es leider so, daß die Frequenz nach oben hin extrem schnell zunahm. Dabei hätte ich mir schon eine gleichmäßigere Zunahme gewünscht, um im besonders interessierenden Bereich (Signalisierung von Drehzahl > 50 % bzw. Abschaltung der Pumpe bei zu hoher Drehzahl) feinfühliger einstellen zu können.
Da hatte ich die Idee, einen (für diesen Zweck natürlich völlig unterforderten ) ATmega8 zu verwenden.
Die Spannung an einem zwischen Betriebsspannung und Masse geschalteten Poti wird über einen ADU eingelesen (liefert Werte zwischen 0 und 1023) und daraus der Grenzwert für den Timer1 berechnet, der im CTC-Modus läuft. Bei jedem Timerinterrupt werden zwei Ausgänge umgeschaltet, die die gewünschten Rechteckimpulsfolgen liefern.
Hier ist das Programm:


Code :


'*******************************************************************************
'* Frequenzgenerator für TCP120-Tester *
'*******************************************************************************

'-------------------------------------------------------------------------------

' µC Deklarationen
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 1000000 'interner RC-Generator 1 MHz

'-------------------------------------------------------------------------------

' Ein-/Ausgänge
'B0: Ausgang A1
'B1: Ausgang A2
Config Portb = &B00000011
A1 Alias Portb.0
A2 Alias Portb.1
Portb = 0
'C3: Eingang für Frequenzeinstellung
Config Portc = &B00000000

'-------------------------------------------------------------------------------

' ADU
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'-------------------------------------------------------------------------------

' Variablen
Dim F As Word 'ADU-Wert des Potis zur Frequenzeinstellung
Dim Timerwert As Word 'Grenzwert für CTC-Modus
Dim Singlewert As Single

'-------------------------------------------------------------------------------

'Timer-Interrupt
Config Timer1 = Timer , Prescale = 1 'Timer, kein Vorteiler
Ocr1ah = High(timerwert) 'OCR1A setzen
Ocr1al = Low(timerwert)
Tccr1a = 0 'Timer1 im CTC-Modus
Set Tccr1b.3
On Compare1a Timerinterrupt
Enable Compare1a
Enable Interrupts 'Interrupts global freigeben

'-------------------------------------------------------------------------------

'+----------------+
'| Programmbeginn |
'+----------------+

'HAUPTPROGRAMM

Set A1

Do
F = Getadc(3) 'Spannung für Frequenzeinstellung lesen
If F < 4 Then 'keine Werte < 4
F = 4
End If
Singlewert = 125000 / F 'Timerwert berechnen
Singlewert = Round(singlewert)
Timerwert = Singlewert
Ocr1ah = High(timerwert) 'OCR1A setzen
Ocr1al = Low(timerwert)
Loop

End


'INTERRUPT

Timerinterrupt:
Toggle A1
Toggle A2
Return


Dies funktioniert auch ganz gut und für mich eigentlich ausreichend. Ich habe aber etwas festgestellt.
Da ich (mehr als Spielerei...) zur optischen Anzeige sehr kleiner Drehzahlen noch einen Kreis von 10 LEDs, die von einem 4017 angesteuert werden, habe, zeigte sich folgender Effekt: Wenn ich die Frequenz langsam vergrößere und die LEDs dann quasi schon dauernd leuchten, "stockt" die Frequenzausgabe an manchen Punkten für vielleicht 0,1 s, was man daran sieht, daß für einen Moment nur eine LED leuchtet. Das passiert an mehreren Punkten der Skala. Ein angeschlossenes zu prüfendes Gerät "erschrickt" sich dann immer und schaltet ein Relais hin und her. Da hier nur simuliert wird, ist das nicht schlimm, aber ich möchte, wie gesagt, gern dahinter kommen.

Es liegt nicht am Potentiometer; der Fehler tritt auch auf, wenn ich die Frequenz programmiert langsam hochfahren lasse. Ich nehme an, es hat damit zu tun, daß an gewissen Punkten der Timer-Grenzwert eine "magische Grenze" überschreitet, z. B. von &H0FF zu &H100. Das Einspeichern des 16-Bit-Timerwertes habe ich doch aber richtig gemacht: H-Byte zuerst!? (Es ändert sich übrigens auch nichts, wenn ich "absichtlich falsch" zuerst das L-Byte speichere.) Auch das Aus- und Einschalten des Interrupts vor bzw. nach dem Speichern oder das Einfügen einer kleinen Pause ändert nichts.

(An dieser Stelle schon einmal Dankeschön an alle, die beim Lesen dieses Romans bis hierher durchgehalten haben!)
Hat vielleicht jemand eine spontane Idee, wie ich den beschriebenen Effekt vermeiden kann? Das wäre ganz toll. Ich danke schon mal im voraus!


BID = 509121

perl

Ehrenmitglied



Beiträge: 11110,1
Wohnort: Rheinbach

 

  


Zitat :
der zwei symmetrische und komplementäre Rechteckfolgen
Sollten die nicht auch noch um 90° phasenverschoben sein ?
Dann bau einen Oszillator für die vierfache Frequenz, dahinter ein T-FF damit du 50% Tastverhältnis bekommst und mit dessen Q und /Q Ausgängen steuerst du zwei weitere T-FFs an, die die beiden um 90° verstetzten Spannungen liefern.

Natürlich kann man das auch in Software machen.

P.S.:
Zitat :
stockt" die Frequenzausgabe an manchen Punkten für vielleicht 0,1 s,
Ich lese keine fremden Programme, aber: ist evtl der Watchdog aktiviert und macht einen Reset?
Andere Quellen für solche Effekte sind nicht abgeschlossene Programmschleifen oder Timerüberläufe die einen icht bedienten Interrupt erzeugen.




_________________
Haftungsausschluß:



Bei obigem Beitrag handelt es sich um meine private Meinung.



Rechtsansprüche dürfen aus deren Anwendung nicht abgeleitet werden.



Besonders VDE0100; VDE0550/0551; VDE0700; VDE0711; VDE0860 beachten !


[ Diese Nachricht wurde geändert von: perl am 19 Mär 2008 15:12 ]

BID = 509161

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Eine solche Schaltung mit Flip-Flops folgt natürlich noch und erzeugt mir letztlich die nachempfundenen Hall-Signale. Die Ausgangssignale meines Rechteckgenerators sind f1 und f2. Diese werden jeweils geteilt und zwischen direktem und invertiertem Ausgang jedes Flip-Flops nehme ich die simulierte "Hall-Spannung" ab. Das funktioniert ja auch alles.

Über deine Softwaretips muß ich mal nachdenken. Vielen Dank!



BID = 509225

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Hallo,

ich habe das Programm auch nur überflogen, aber ich denke, es liegt in der Arithmetik mit Kommazahlen. Das ist nicht grade resourcenschonend, so für einen Mikrokontroller mit 1MHz Taktfrequenz und keiner Kommaarithmetik zu programmieren. Evtl. schaltet der Basic-Compiler für solche Teile, in der eben mit viel Aufwand gerechnet wird, die Interrupts global ab (cli).
Dadurch wird eine ISR oder mehrere übersprungen, und es kommt zu diesem Effekt.

Nimm mal spaßeshalber die Sachen mit Single-Variablen raus.
Du wirst dich wundern

Edit: Weiterhn ist perls Gedanke mit dem Watchdog nicht verkehrt. Der setzt den µC bei jedem Watchod-Overflow zurück, dadurch können solche Effekte ebenfalls auftauchen. Den Watchdog kann man global abschalten mit dem entspr. Fusebit.

_________________


[ Diese Nachricht wurde geändert von: DonComi am 19 Mär 2008 17:48 ]

BID = 509243

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Irgend etwas hatte mich dazu bewogen, die Single-Variable zu benutzen. Ich glaube, da hatte bei der Simulation des Programms etwas nicht funktioniert. Aber ich probiere es morgen noch einmal aus.
Was ein Watchdog im Prinzip ist, weiß ich. Nur dachte ich bisher, daß ich dies explizit programmieren muß und nicht, daß er "von sich aus" arbeitet. Da habe ich mir also noch nie Gedanken drüber gemacht und muß mal ins Datenblatt schauen.

Vielen Dank für die Tips!

BID = 509302

Jornbyte

Moderator



Beiträge: 7090

Ich habe vor langer Zeit mal einen Generator mit einem 8515 (mega8515) Sinus, Rechteck, Sägezahn und Dreieck aufgebaut. 0 Hz bis 100KHz in 0,1 Schritte einstellbar. Der ist hier im Forum (glaube ich) zu finden. Wobei das alles in ASM geschrieben ist. Mit ein klein wenig Handarbeit für deine Zwecke sollte der anpassbar sein.

_________________
mfg Jornbyte

Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten.

BID = 509365

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Ich habe mir die Sache mit der Single-Variablen noch einmal angesehen. Wenn ich
Timerwert = 125000 \ F
rechne, wobei "Timerwert" und "F" als WORD deklariert sind, wird falsch gerechnet. (Vielleicht, weil 125000 mehr als ein WORD ist?)
Ich habe jetzt LONG statt SINGLE verwendet, die Rechnung stimmt, die Speicherauslastung ist von 16 % auf 7 % zurückgegangen (na gucke mal an!), aber der Fehler ist noch da...

Ich habe mal im Datenblatt nachgelesen, wie der Watchdog-Timer ausgeschaltet wird.
Zunächst einmal ist das entsprechende Fusebit auf "Watchdog kontrolliert durch WDTCR" gesetzt.
Dann steht im Datenblatt, daß folgende Prozedur zum Ausschalten des "Wachhundes" einzuhalten ist:
Die Bits WDCE (Bit 4) und WDE (Bit 3) sind gleichzeitig auf 1 zu setzen. Innerhalb der nächsten 4 Takte muß WDE (Bit 3) auf 0 gesetzt werden. Das habe ich versucht durch
Wdtcr = Wdtcr Or &B00011000
Wdtcr = Wdtcr And &B11110111

Jetzt tritt aber der seltsame Fall ein, daß nur noch ganz am Anfang des Einstellbereichs des Potis die Frequenz sich etwas vergrößert und dann auf den niedrigsten Wert zurückfällt und dort bleibt...

Aber ich glaube, ich denke jetzt erst ab Dienstag wieder über diese Sache nach. Ansonsten funktioniert ja mein Gerätchen ganz gut und hat mir schon beim Finden eines Fehlers in einem Pumpen-Steuergerät geholfen!

Nochmals Danke für die Ratschläge bis hierher!

BID = 509390

bastler16

Schreibmaschine

Beiträge: 2140
Wohnort: Frankreich



Zitat :
Das ist nicht grade resourcenschonend

Scheint zu stimmen.
Hab mal das Hex-File durch den Disassembler gejagt, raus kommt eine ganze Menge Code...


Zitat :
Evtl. schaltet der Basic-Compiler für solche Teile, in der eben mit viel Aufwand gerechnet wird, die Interrupts global ab (cli).

+00000092: 94F8 CLI Global Interrupt Disable
Ob das jetzt der Fehler ist weiss ich nicht, dazu müsste man den Code mal genauer betrachten.


Code :

00000000:   C012        RJMP    PC+0x0013        Relative jump

+00000001: 9518 RETI Interrupt return
+00000002: 9518 RETI Interrupt return
+00000003: 9518 RETI Interrupt return
+00000004: 9518 RETI Interrupt return
+00000005: 9518 RETI Interrupt return
+00000006: C08D RJMP PC+0x008E Relative jump
+00000007: 9518 RETI Interrupt return
+00000008: 9518 RETI Interrupt return
+00000009: 9518 RETI Interrupt return
+0000000A: 9518 RETI Interrupt return
+0000000B: 9518 RETI Interrupt return
+0000000C: 9518 RETI Interrupt return
+0000000D: 9518 RETI Interrupt return
+0000000E: 9518 RETI Interrupt return
+0000000F: 9518 RETI Interrupt return
+00000010: 9518 RETI Interrupt return
+00000011: 9518 RETI Interrupt return
+00000012: 9518 RETI Interrupt return
+00000013: E58F LDI R24,0x5F Load immediate
+00000014: BF8D OUT 0x3D,R24 Out to I/O location
+00000015: E4C0 LDI R28,0x40 Load immediate
+00000016: E3E8 LDI R30,0x38 Load immediate
+00000017: 2E4E MOV R4,R30 Copy register
+00000018: E084 LDI R24,0x04 Load immediate
+00000019: BF8E OUT 0x3E,R24 Out to I/O location
+0000001A: E0D4 LDI R29,0x04 Load immediate
+0000001B: E0F4 LDI R31,0x04 Load immediate
+0000001C: 2E5F MOV R5,R31 Copy register
+0000001D: EFEE LDI R30,0xFE Load immediate
+0000001E: E0F3 LDI R31,0x03 Load immediate
+0000001F: E6A0 LDI R26,0x60 Load immediate
+00000020: E0B0 LDI R27,0x00 Load immediate
+00000021: 2788 CLR R24 Clear Register
+00000022: 938D ST X+,R24 Store indirect and postincrement
+00000023: 9731 SBIW R30,0x01 Subtract immediate from word
+00000024: F7E9 BRNE PC-0x02 Branch if not equal
+00000025: B784 IN R24,0x34 In from I/O location
+00000026: 2E08 MOV R0,R24 Copy register
+00000027: 7F87 ANDI R24,0xF7 Logical AND with immediate
+00000028: BF84 OUT 0x34,R24 Out to I/O location
+00000029: E18F LDI R24,0x1F Load immediate
+0000002A: BD81 OUT 0x21,R24 Out to I/O location
+0000002B: E087 LDI R24,0x07 Load immediate
+0000002C: BD81 OUT 0x21,R24 Out to I/O location
+0000002D: 2466 CLR R6 Clear Register
+0000002E: E083 LDI R24,0x03 Load immediate
+0000002F: BB87 OUT 0x17,R24 Out to I/O location
+00000030: E080 LDI R24,0x00 Load immediate
+00000031: BB88 OUT 0x18,R24 Out to I/O location
+00000032: E080 LDI R24,0x00 Load immediate
+00000033: BB84 OUT 0x14,R24 Out to I/O location
+00000034: E883 LDI R24,0x83 Load immediate
+00000035: B986 OUT 0x06,R24 Out to I/O location
+00000036: E480 LDI R24,0x40 Load immediate
+00000037: B987 OUT 0x07,R24 Out to I/O location
+00000038: 9A37 SBI 0x06,7 Set bit in I/O register
+00000039: E080 LDI R24,0x00 Load immediate
+0000003A: BD8F OUT 0x2F,R24 Out to I/O location
+0000003B: E081 LDI R24,0x01 Load immediate
+0000003C: BD8E OUT 0x2E,R24 Out to I/O location
+0000003D: E6A2 LDI R26,0x62 Load immediate
+0000003E: E0B0 LDI R27,0x00 Load immediate
+0000003F: 9611 ADIW R26,0x01 Add immediate to word
+00000040: 918C LD R24,X Load indirect
+00000041: BD8B OUT 0x2B,R24 Out to I/O location
+00000042: E6A2 LDI R26,0x62 Load immediate
+00000043: E0B0 LDI R27,0x00 Load immediate
+00000044: 918C LD R24,X Load indirect
+00000045: BD8A OUT 0x2A,R24 Out to I/O location
+00000046: E080 LDI R24,0x00 Load immediate
+00000047: BD8F OUT 0x2F,R24 Out to I/O location
+00000048: B58E IN R24,0x2E In from I/O location
+00000049: 6088 ORI R24,0x08 Logical OR with immediate
+0000004A: BD8E OUT 0x2E,R24 Out to I/O location
+0000004B: B789 IN R24,0x39 In from I/O location
+0000004C: 6180 ORI R24,0x10 Logical OR with immediate
+0000004D: BF89 OUT 0x39,R24 Out to I/O location
+0000004E: 9478 SEI Global Interrupt Enable
+0000004F: 9AC0 SBI 0x18,0 Set bit in I/O register
+00000050: B107 IN R16,0x07 In from I/O location
+00000051: 7F00 ANDI R16,0xF0 Logical AND with immediate
+00000052: 6003 ORI R16,0x03 Logical OR with immediate
+00000053: B907 OUT 0x07,R16 Out to I/O location
+00000054: D087 RCALL PC+0x0088 Relative call subroutine
+00000055: E6A0 LDI R26,0x60 Load immediate
+00000056: E0B0 LDI R27,0x00 Load immediate
+00000057: 938D ST X+,R24 Store indirect and postincrement
+00000058: 939C ST X,R25 Store indirect
+00000059: E6A0 LDI R26,0x60 Load immediate
+0000005A: E0B0 LDI R27,0x00 Load immediate
+0000005B: 910D LD R16,X+ Load indirect and postincrement
+0000005C: 911C LD R17,X Load indirect
+0000005D: 3004 CPI R16,0x04 Compare with immediate
+0000005E: E050 LDI R21,0x00 Load immediate
+0000005F: 0715 CPC R17,R21 Compare with carry
+00000060: F008 BRCS PC+0x02 Branch if carry set
+00000061: C006 RJMP PC+0x0007 Relative jump
+00000062: E084 LDI R24,0x04 Load immediate
+00000063: E090 LDI R25,0x00 Load immediate
+00000064: E6A0 LDI R26,0x60 Load immediate
+00000065: E0B0 LDI R27,0x00 Load immediate
+00000066: 938D ST X+,R24 Store indirect and postincrement
+00000067: 939C ST X,R25 Store indirect
+00000068: E6E0 LDI R30,0x60 Load immediate
+00000069: E0F0 LDI R31,0x00 Load immediate
+0000006A: 90D1 LD R13,Z+ Load indirect and postincrement
+0000006B: 80E0 LDD R14,Z+0 Load indirect with displacement
+0000006C: 24FF CLR R15 Clear Register
+0000006D: 2700 CLR R16 Clear Register
+0000006E: D0D8 RCALL PC+0x00D9 Relative call subroutine
+0000006F: D108 RCALL PC+0x0109 Relative call subroutine
+00000070: E6E8 LDI R30,0x68 Load immediate
+00000071: E0F5 LDI R31,0x05 Load immediate
+00000072: D1D1 RCALL PC+0x01D2 Relative call subroutine
+00000073: D11F RCALL PC+0x0120 Relative call subroutine
+00000074: E0ED LDI R30,0x0D Load immediate
+00000075: E0F0 LDI R31,0x00 Load immediate
+00000076: E6A4 LDI R26,0x64 Load immediate
+00000077: E0B0 LDI R27,0x00 Load immediate
+00000078: D1EA RCALL PC+0x01EB Relative call subroutine
+00000079: E6E4 LDI R30,0x64 Load immediate
+0000007A: E0F0 LDI R31,0x00 Load immediate
+0000007B: D22F RCALL PC+0x0230 Relative call subroutine
+0000007C: E0ED LDI R30,0x0D Load immediate
+0000007D: E0F0 LDI R31,0x00 Load immediate
+0000007E: E6A4 LDI R26,0x64 Load immediate
+0000007F: E0B0 LDI R27,0x00 Load immediate
+00000080: D1E2 RCALL PC+0x01E3 Relative call subroutine
+00000081: E6E4 LDI R30,0x64 Load immediate
+00000082: E0F0 LDI R31,0x00 Load immediate
+00000083: D061 RCALL PC+0x0062 Relative call subroutine
+00000084: E6A2 LDI R26,0x62 Load immediate
+00000085: E0B0 LDI R27,0x00 Load immediate
+00000086: 92DD ST X+,R13 Store indirect and postincrement
+00000087: 92EC ST X,R14 Store indirect
+00000088: E6A2 LDI R26,0x62 Load immediate
+00000089: E0B0 LDI R27,0x00 Load immediate
+0000008A: 9611 ADIW R26,0x01 Add immediate to word
+0000008B: 918C LD R24,X Load indirect
+0000008C: BD8B OUT 0x2B,R24 Out to I/O location
+0000008D: E6A2 LDI R26,0x62 Load immediate
+0000008E: E0B0 LDI R27,0x00 Load immediate
+0000008F: 918C LD R24,X Load indirect
+00000090: BD8A OUT 0x2A,R24 Out to I/O location
+00000091: CFBE RJMP PC-0x0041 Relative jump
+00000092: 94F8 CLI Global Interrupt Disable
+00000093: CFFF RJMP PC-0x0000 Relative jump
+00000094: 920F PUSH R0 Push register on stack
+00000095: 921F PUSH R1 Push register on stack
+00000096: 922F PUSH R2 Push register on stack
+00000097: 923F PUSH R3 Push register on stack
+00000098: 924F PUSH R4 Push register on stack
+00000099: 925F PUSH R5 Push register on stack
+0000009A: 927F PUSH R7 Push register on stack
+0000009B: 92AF PUSH R10 Push register on stack
+0000009C: 92BF PUSH R11 Push register on stack
+0000009D: 930F PUSH R16 Push register on stack
+0000009E: 931F PUSH R17 Push register on stack
+0000009F: 932F PUSH R18 Push register on stack
+000000A0: 933F PUSH R19 Push register on stack
+000000A1: 934F PUSH R20 Push register on stack
+000000A2: 935F PUSH R21 Push register on stack
+000000A3: 936F PUSH R22 Push register on stack
+000000A4: 937F PUSH R23 Push register on stack
+000000A5: 938F PUSH R24 Push register on stack
+000000A6: 939F PUSH R25 Push register on stack
+000000A7: 93AF PUSH R26 Push register on stack
+000000A8: 93BF PUSH R27 Push register on stack
+000000A9: 93CF PUSH R28 Push register on stack
+000000AA: 93DF PUSH R29 Push register on stack
+000000AB: 93EF PUSH R30 Push register on stack
+000000AC: 93FF PUSH R31 Push register on stack
+000000AD: B78F IN R24,0x3F In from I/O location
+000000AE: 938F PUSH R24 Push register on stack
+000000AF: B388 IN R24,0x18 In from I/O location
+000000B0: E091 LDI R25,0x01 Load immediate
+000000B1: 2789 EOR R24,R25 Exclusive OR
+000000B2: BB88 OUT 0x18,R24 Out to I/O location
+000000B3: B388 IN R24,0x18 In from I/O location
+000000B4: E092 LDI R25,0x02 Load immediate
+000000B5: 2789 EOR R24,R25 Exclusive OR
+000000B6: BB88 OUT 0x18,R24 Out to I/O location
+000000B7: 918F POP R24 Pop register from stack
+000000B8: BF8F OUT 0x3F,R24 Out to I/O location
+000000B9: 91FF POP R31 Pop register from stack
+000000BA: 91EF POP R30 Pop register from stack
+000000BB: 91DF POP R29 Pop register from stack
+000000BC: 91CF POP R28 Pop register from stack
+000000BD: 91BF POP R27 Pop register from stack
+000000BE: 91AF POP R26 Pop register from stack
+000000BF: 919F POP R25 Pop register from stack
+000000C0: 918F POP R24 Pop register from stack
+000000C1: 917F POP R23 Pop register from stack
+000000C2: 916F POP R22 Pop register from stack
+000000C3: 915F POP R21 Pop register from stack
+000000C4: 914F POP R20 Pop register from stack
+000000C5: 913F POP R19 Pop register from stack
+000000C6: 912F POP R18 Pop register from stack
+000000C7: 911F POP R17 Pop register from stack
+000000C8: 910F POP R16 Pop register from stack
+000000C9: 90BF POP R11 Pop register from stack
+000000CA: 90AF POP R10 Pop register from stack
+000000CB: 907F POP R7 Pop register from stack
+000000CC: 905F POP R5 Pop register from stack
+000000CD: 904F POP R4 Pop register from stack
+000000CE: 903F POP R3 Pop register from stack
+000000CF: 902F POP R2 Pop register from stack
+000000D0: 901F POP R1 Pop register from stack
+000000D1: 900F POP R0 Pop register from stack
+000000D2: 9518 RETI Interrupt return
+000000D3: 9731 SBIW R30,0x01 Subtract immediate from word
+000000D4: F7F1 BRNE PC-0x01 Branch if not equal
+000000D5: 9508 RET Subroutine return
+000000D6: 9468 SET Set T in SREG
+000000D7: F862 BLD R6,2 Bit load from T to register
+000000D8: 9508 RET Subroutine return
+000000D9: 94E8 CLT Clear T in SREG
+000000DA: F862 BLD R6,2 Bit load from T to register
+000000DB: 9508 RET Subroutine return
+000000DC: 9A36 SBI 0x06,6 Set bit in I/O register
+000000DD: 9936 SBIC 0x06,6 Skip if bit in I/O register cleared
+000000DE: CFFE RJMP PC-0x0001 Relative jump
+000000DF: 9A36 SBI 0x06,6 Set bit in I/O register
+000000E0: 9936 SBIC 0x06,6 Skip if bit in I/O register cleared
+000000E1: CFFE RJMP PC-0x0001 Relative jump
+000000E2: B184 IN R24,0x04 In from I/O location
+000000E3: B195 IN R25,0x05 In from I/O location
+000000E4: 9508 RET Subroutine return
+000000E5: D03D RCALL PC+0x003E Relative call subroutine
+000000E6: 2799 CLR R25 Clear Register
+000000E7: 2711 CLR R17 Clear Register
+000000E8: 2D8F MOV R24,R15 Copy register
+000000E9: 0F88 LSL R24 Logical Shift Left
+000000EA: E880 LDI R24,0x80 Load immediate
+000000EB: 2AF8 OR R15,R24 Logical OR
+000000EC: 2F80 MOV R24,R16 Copy register
+000000ED: 1F88 ROL R24 Rotate Left Through Carry
+000000EE: F408 BRCC PC+0x02 Branch if carry cleared
+000000EF: EF1F SER R17 Set Register
+000000F0: F041 BREQ PC+0x09 Branch if equal
+000000F1: 578F SUBI R24,0x7F Subtract immediate
+000000F2: 2F08 MOV R16,R24 Copy register
+000000F3: FD07 SBRC R16,7 Skip if bit in register cleared
+000000F4: C004 RJMP PC+0x0005 Relative jump
+000000F5: 3200 CPI R16,0x20 Compare with immediate
+000000F6: F040 BRCS PC+0x09 Branch if carry set
+000000F7: EF8F SER R24 Set Register
+000000F8: C001 RJMP PC+0x0002 Relative jump
+000000F9: 2788 CLR R24 Clear Register
+000000FA: 2F98 MOV R25,R24 Copy register
+000000FB: 2ED8 MOV R13,R24 Copy register
+000000FC: 2EE8 MOV R14,R24 Copy register
+000000FD: 2EF8 MOV R15,R24 Copy register
+000000FE: C009 RJMP PC+0x000A Relative jump
+000000FF: E18F LDI R24,0x1F Load immediate
+00000100: 1B80 SUB R24,R16 Subtract without carry
+00000101: 2F08 MOV R16,R24 Copy register
+00000102: 94F6 LSR R15 Logical shift right
+00000103: 94E7 ROR R14 Rotate right through carry
+00000104: 94D7 ROR R13 Rotate right through carry
+00000105: 9597 ROR R25 Rotate right through carry
+00000106: 950A DEC R16 Decrement
+00000107: F7D1 BRNE PC-0x05 Branch if not equal
+00000108: 2311 TST R17 Test for Zero or Minus
+00000109: F051 BREQ PC+0x0B Branch if equal
+0000010A: 9590 COM R25 One's complement
+0000010B: 94D0 COM R13 One's complement
+0000010C: 94E0 COM R14 One's complement
+0000010D: 94F0 COM R15 One's complement
+0000010E: E081 LDI R24,0x01 Load immediate
+0000010F: 0F98 ADD R25,R24 Add without carry
+00000110: 2788 CLR R24 Clear Register
+00000111: 1ED8 ADC R13,R24 Add with carry
+00000112: 1EE8 ADC R14,R24 Add with carry
+00000113: 1EF8 ADC R15,R24 Add with carry
+00000114: 2D0F MOV R16,R15 Copy register
+00000115: 2CFE MOV R15,R14 Copy register
+00000116: 2CED MOV R14,R13 Copy register
+00000117: 2ED9 MOV R13,R25 Copy register
+00000118: 9508 RET Subroutine return
+00000119: 94D0 COM R13 One's complement
+0000011A: 94E0 COM R14 One's complement
+0000011B: 94F0 COM R15 One's complement
+0000011C: E091 LDI R25,0x01 Load immediate
+0000011D: 0ED9 ADD R13,R25 Add without carry
+0000011E: 2799 CLR R25 Clear Register
+0000011F: 1EE9 ADC R14,R25 Add with carry
+00000120: 1EF9 ADC R15,R25 Add with carry
+00000121: 9510 COM R17 One's complement
+00000122: 9508 RET Subroutine return
+00000123: 90D1 LD R13,Z+ Load indirect and postincrement
+00000124: 90E1 LD R14,Z+ Load indirect and postincrement
+00000125: 90F1 LD R15,Z+ Load indirect and postincrement
+00000126: 9101 LD R16,Z+ Load indirect and postincrement
+00000127: 9508 RET Subroutine return
+00000128: 9121 LD R18,Z+ Load indirect and postincrement
+00000129: 9131 LD R19,Z+ Load indirect and postincrement
+0000012A: 9141 LD R20,Z+ Load indirect and postincrement
+0000012B: 9151 LD R21,Z+ Load indirect and postincrement
+0000012C: 9508 RET Subroutine return
+0000012D: 2F10 MOV R17,R16 Copy register
+0000012E: E890 LDI R25,0x80 Load immediate
+0000012F: 0CFF LSL R15 Logical Shift Left
+00000130: 1F00 ROL R16 Rotate Left Through Carry
+00000131: 2709 EOR R16,R25 Exclusive OR
+00000132: 0F99 LSL R25 Logical Shift Left
+00000133: 94F7 ROR R15 Rotate right through carry
+00000134: 7810 ANDI R17,0x80 Logical AND with immediate
+00000135: 2F65 MOV R22,R21 Copy register
+00000136: E890 LDI R25,0x80 Load immediate
+00000137: 0F44 LSL R20 Logical Shift Left
+00000138: 1F55 ROL R21 Rotate Left Through Carry
+00000139: 2759 EOR R21,R25 Exclusive OR
+0000013A: 0F99 LSL R25 Logical Shift Left
+0000013B: 9547 ROR R20 Rotate right through carry
+0000013C: 7860 ANDI R22,0x80 Logical AND with immediate
+0000013D: 3800 CPI R16,0x80 Compare with immediate
+0000013E: 9508 RET Subroutine return
+0000013F: 0CFF LSL R15 Logical Shift Left
+00000140: E890 LDI R25,0x80 Load immediate
+00000141: 2790 EOR R25,R16 Exclusive OR
+00000142: 0F11 LSL R17 Logical Shift Left
+00000143: 9597 ROR R25 Rotate right through carry
+00000144: 94F7 ROR R15 Rotate right through carry
+00000145: 2F09 MOV R16,R25 Copy register
+00000146: 9508 RET Subroutine return
+00000147: 2F10 MOV R17,R16 Copy register
+00000148: 2CBD MOV R11,R13 Copy register
+00000149: 2CDE MOV R13,R14 Copy register
+0000014A: 2CEF MOV R14,R15 Copy register
+0000014B: 2EF0 MOV R15,R16 Copy register
+0000014C: 2311 TST R17 Test for Zero or Minus
+0000014D: F44A BRPL PC+0x0A Branch if plus
+0000014E: 94B0 COM R11 One's complement
+0000014F: 94D0 COM R13 One's complement
+00000150: 94E0 COM R14 One's complement
+00000151: 94F0 COM R15 One's complement
+00000152: EF9F SER R25 Set Register
+00000153: 1AB9 SUB R11,R25 Subtract without carry
+00000154: 0AD9 SBC R13,R25 Subtract with carry
+00000155: 0AE9 SBC R14,R25 Subtract with carry
+00000156: 0AF9 SBC R15,R25 Subtract with carry
+00000157: E10E LDI R16,0x1E Load immediate
+00000158: 20FF TST R15 Test for Zero or Minus
+00000159: F439 BRNE PC+0x08 Branch if not equal
+0000015A: 2CFE MOV R15,R14 Copy register
+0000015B: 2CED MOV R14,R13 Copy register
+0000015C: 2CDB MOV R13,R11 Copy register
+0000015D: 24BB CLR R11 Clear Register
+0000015E: 5008 SUBI R16,0x08 Subtract immediate
+0000015F: F7C2 BRPL PC-0x07 Branch if plus
+00000160: C066 RJMP PC+0x0067 Relative jump
+00000161: F032 BRMI PC+0x07 Branch if minus
+00000162: 950A DEC R16 Decrement
+00000163: 0CBB LSL R11 Logical Shift Left
+00000164: 1CDD ROL R13 Rotate Left Through Carry
+00000165: 1CEE ROL R14 Rotate Left Through Carry
+00000166: 1CFF ROL R15 Rotate Left Through Carry
+00000167: CFF9 RJMP PC-0x0006 Relative jump
+00000168: D001 RCALL PC+0x0002 Relative call subroutine
+00000169: CFD5 RJMP PC-0x002A Relative jump
+0000016A: FEB7 SBRS R11,7 Skip if bit in register set
+0000016B: 9508 RET Subroutine return
+0000016C: E890 LDI R25,0x80 Load immediate
+0000016D: 16B9 CP R11,R25 Compare
+0000016E: F411 BRNE PC+0x03 Branch if not equal
+0000016F: FED0 SBRS R13,0 Skip if bit in register set
+00000170: 9508 RET Subroutine return
+00000171: EF9F SER R25 Set Register
+00000172: 1AD9 SUB R13,R25 Subtract without carry
+00000173: 0AE9 SBC R14,R25 Subtract with carry
+00000174: 0AF9 SBC R15,R25 Subtract with carry
+00000175: F409 BRNE PC+0x02 Branch if not equal
+00000176: 9503 INC R16 Increment
+00000177: 9508 RET Subroutine return
+00000178: 2F50 MOV R21,R16 Copy register
+00000179: 2D2D MOV R18,R13 Copy register
+0000017A: 2D3E MOV R19,R14 Copy register
+0000017B: 2D4F MOV R20,R15 Copy register
+0000017C: 2F61 MOV R22,R17 Copy register
+0000017D: 9508 RET Subroutine return
+0000017E: EC2D LDI R18,0xCD Load immediate
+0000017F: EC3C LDI R19,0xCC Load immediate
+00000180: EC4C LDI R20,0xCC Load immediate
+00000181: E35D LDI R21,0x3D Load immediate
+00000182: 2766 CLR R22 Clear Register
+00000183: C00F RJMP PC+0x0010 Relative jump
+00000184: DF9E RCALL PC-0x0061 Relative call subroutine
+00000185: DFF2 RCALL PC-0x000D Relative call subroutine
+00000186: 24DD CLR R13 Clear Register
+00000187: 24EE CLR R14 Clear Register
+00000188: E890 LDI R25,0x80 Load immediate
+00000189: 2EF9 MOV R15,R25 Copy register
+0000018A: E30F LDI R16,0x3F Load immediate
+0000018B: C007 RJMP PC+0x0008 Relative jump
+0000018C: DF9B RCALL PC-0x0064 Relative call subroutine
+0000018D: C005 RJMP PC+0x0006 Relative jump
+0000018E: 2722 CLR R18 Clear Register
+0000018F: 2733 CLR R19 Clear Register
+00000190: E240 LDI R20,0x20 Load immediate
+00000191: E451 LDI R21,0x41 Load immediate
+00000192: 2766 CLR R22 Clear Register
+00000193: 2355 TST R21 Test for Zero or Minus
+00000194: F151 BREQ PC+0x2B Branch if equal
+00000195: 2300 TST R16 Test for Zero or Minus
+00000196: F181 BREQ PC+0x31 Branch if equal
+00000197: DF95 RCALL PC-0x006A Relative call subroutine
+00000198: F171 BREQ PC+0x2F Branch if equal
+00000199: 2716 EOR R17,R22 Exclusive OR
+0000019A: 5800 SUBI R16,0x80 Subtract immediate
+0000019B: 5850 SUBI R21,0x80 Subtract immediate
+0000019C: 9408 SEC Set Carry
+0000019D: 0B05 SBC R16,R21 Subtract with carry
+0000019E: F418 BRCC PC+0x04 Branch if carry cleared
+0000019F: FD07 SBRC R16,7 Skip if bit in register cleared
+000001A0: C003 RJMP PC+0x0004 Relative jump
+000001A1: C025 RJMP PC+0x0026 Relative jump
+000001A2: FD07 SBRC R16,7 Skip if bit in register cleared
+000001A3: C023 RJMP PC+0x0024 Relative jump
+000001A4: 9546 LSR R20 Logical shift right
+000001A5: 9537 ROR R19 Rotate right through carry
+000001A6: 9527 ROR R18 Rotate right through carry
+000001A7: 94F6 LSR R15 Logical shift right
+000001A8: 94E7 ROR R14 Rotate right through carry
+000001A9: 94D7 ROR R13 Rotate right through carry
+000001AA: D022 RCALL PC+0x0023 Relative call subroutine
+000001AB: 20FF TST R15 Test for Zero or Minus
+000001AC: F02A BRMI PC+0x06 Branch if minus
+000001AD: 0CDD LSL R13 Logical Shift Left
+000001AE: 1CEE ROL R14 Rotate Left Through Carry
+000001AF: 1CFF ROL R15 Rotate Left Through Carry
+000001B0: 5001 SUBI R16,0x01 Subtract immediate
+000001B1: F073 BRVS PC+0x0F Branch if overflow flag is set
+000001B2: 2D9D MOV R25,R13 Copy register
+000001B3: 9596 LSR R25 Logical shift right
+000001B4: F048 BRCS PC+0x0A Branch if carry set
+000001B5: 20DD TST R13 Test for Zero or Minus
+000001B6: F43A BRPL PC+0x08 Branch if plus
+000001B7: 20EE TST R14 Test for Zero or Minus
+000001B8: F42A BRPL PC+0x06 Branch if plus
+000001B9: E091 LDI R25,0x01 Load immediate
+000001BA: 0ED9 ADD R13,R25 Add without carry
+000001BB: 2799 CLR R25 Clear Register
+000001BC: 1EE9 ADC R14,R25 Add with carry
+000001BD: 1EF9 ADC R15,R25 Add with carry
+000001BE: CF80 RJMP PC-0x007F Relative jump
+000001BF: C007 RJMP PC+0x0008 Relative jump
+000001C0: E79F LDI R25,0x7F Load immediate
+000001C1: 2F09 MOV R16,R25 Copy register
+000001C2: 2AF9 OR R15,R25 Logical OR
+000001C3: EF9F SER R25 Set Register
+000001C4: 2ED9 MOV R13,R25 Copy register
+000001C5: 2EE9 MOV R14,R25 Copy register
+000001C6: 9508 RET Subroutine return
+000001C7: 24DD CLR R13 Clear Register
+000001C8: 24EE CLR R14 Clear Register
+000001C9: 24FF CLR R15 Clear Register
+000001CA: 2700 CLR R16 Clear Register
+000001CB: 2711 CLR R17 Clear Register
+000001CC: 9508 RET Subroutine return
+000001CD: 929F PUSH R9 Push register on stack
+000001CE: 2499 CLR R9 Clear Register
+000001CF: 24AA CLR R10 Clear Register
+000001D0: 24BB CLR R11 Clear Register
+000001D1: E188 LDI R24,0x18 Load immediate
+000001D2: 16D2 CP R13,R18 Compare
+000001D3: 06E3 CPC R14,R19 Compare with carry
+000001D4: 06F4 CPC R15,R20 Compare with carry
+000001D5: F028 BRCS PC+0x06 Branch if carry set
+000001D6: 1AD2 SUB R13,R18 Subtract without carry
+000001D7: 0AE3 SBC R14,R19 Subtract with carry
+000001D8: 0AF4 SBC R15,R20 Subtract with carry
+000001D9: 9408 SEC Set Carry
+000001DA: C001 RJMP PC+0x0002 Relative jump
+000001DB: 9488 CLC Clear Carry
+000001DC: 1C99 ROL R9 Rotate Left Through Carry
+000001DD: 1CAA ROL R10 Rotate Left Through Carry
+000001DE: 1CBB ROL R11 Rotate Left Through Carry
+000001DF: 0CDD LSL R13 Logical Shift Left
+000001E0: 1CEE ROL R14 Rotate Left Through Carry
+000001E1: 1CFF ROL R15 Rotate Left Through Carry
+000001E2: 958A DEC R24 Decrement
+000001E3: F771 BRNE PC-0x11 Branch if not equal
+000001E4: 2CD9 MOV R13,R9 Copy register
+000001E5: 2CEA MOV R14,R10 Copy register
+000001E6: 2CFB MOV R15,R11 Copy register
+000001E7: 909F POP R9 Pop register from stack
+000001E8: 9508 RET Subroutine return
+000001E9: F00A BRMI PC+0x02 Branch if minus
+000001EA: D045 RCALL PC+0x0046 Relative call subroutine
+000001EB: CF53 RJMP PC-0x00AC Relative jump
+000001EC: E35F LDI R21,0x3F Load immediate
+000001ED: 2722 CLR R18 Clear Register
+000001EE: 2733 CLR R19 Clear Register
+000001EF: 2744 CLR R20 Clear Register
+000001F0: C001 RJMP PC+0x0002 Relative jump
+000001F1: DF36 RCALL PC-0x00C9 Relative call subroutine
+000001F2: DF3A RCALL PC-0x00C5 Relative call subroutine
+000001F3: 3850 CPI R21,0x80 Compare with immediate
+000001F4: F3B1 BREQ PC-0x09 Branch if equal
+000001F5: 3800 CPI R16,0x80 Compare with immediate
+000001F6: F399 BREQ PC-0x0C Branch if equal
+000001F7: 2F90 MOV R25,R16 Copy register
+000001F8: 1B95 SUB R25,R21 Subtract without carry
+000001F9: F38B BRVS PC-0x0E Branch if overflow flag is set
+000001FA: F412 BRPL PC+0x03 Branch if plus
+000001FB: D034 RCALL PC+0x0035 Relative call subroutine
+000001FC: CFFA RJMP PC-0x0005 Relative jump
+000001FD: 3198 CPI R25,0x18 Compare with immediate
+000001FE: F018 BRCS PC+0x04 Branch if carry set
+000001FF: 2722 CLR R18 Clear Register
+00000200: 2733 CLR R19 Clear Register
+00000201: 2744 CLR R20 Clear Register
+00000202: 3098 CPI R25,0x08 Compare with immediate
+00000203: F028 BRCS PC+0x06 Branch if carry set
+00000204: 2F23 MOV R18,R19 Copy register
+00000205: 2F34 MOV R19,R20 Copy register
+00000206: 2744 CLR R20 Clear Register
+00000207: 5098 SUBI R25,0x08 Subtract immediate
+00000208: CFF9 RJMP PC-0x0006 Relative jump
+00000209: 2399 TST R25 Test for Zero or Minus
+0000020A: F029 BREQ PC+0x06 Branch if equal
+0000020B: 9546 LSR R20 Logical shift right
+0000020C: 9537 ROR R19 Rotate right through carry
+0000020D: 9527 ROR R18 Rotate right through carry
+0000020E: 959A DEC R25 Decrement
+0000020F: F7D9 BRNE PC-0x04 Branch if not equal
+00000210: 2F91 MOV R25,R17 Copy register
+00000211: 2796 EOR R25,R22 Exclusive OR
+00000212: F042 BRMI PC+0x09 Branch if minus
+00000213: D014 RCALL PC+0x0015 Relative call subroutine
+00000214: F6B0 BRCC PC-0x29 Branch if carry cleared
+00000215: 94F7 ROR R15 Rotate right through carry
+00000216: 94E7 ROR R14 Rotate right through carry
+00000217: 94D7 ROR R13 Rotate right through carry
+00000218: 5F0F SUBI R16,0xFF Subtract immediate
+00000219: F68B BRVC PC-0x2E Branch if overflow flag is cleared
+0000021A: CFA5 RJMP PC-0x005A Relative jump
+0000021B: D010 RCALL PC+0x0011 Relative call subroutine
+0000021C: F051 BREQ PC+0x0B Branch if equal
+0000021D: F408 BRCC PC+0x02 Branch if carry cleared
+0000021E: DEFA RCALL PC-0x0105 Relative call subroutine
+0000021F: 20FF TST R15 Test for Zero or Minus
+00000220: F252 BRMI PC-0x35 Branch if minus
+00000221: 0CDD LSL R13 Logical Shift Left
+00000222: 1CEE ROL R14 Rotate Left Through Carry
+00000223: 1CFF ROL R15 Rotate Left Through Carry
+00000224: 5001 SUBI R16,0x01 Subtract immediate
+00000225: F7CB BRVC PC-0x06 Branch if overflow flag is cleared
+00000226: CF99 RJMP PC-0x0066 Relative jump
+00000227: CF9F RJMP PC-0x0060 Relative jump
+00000228: 0ED2 ADD R13,R18 Add without carry
+00000229: 1EE3 ADC R14,R19 Add with carry
+0000022A: 1EF4 ADC R15,R20 Add with carry
+0000022B: 9508 RET Subroutine return
+0000022C: 1AD2 SUB R13,R18 Subtract without carry
+0000022D: 0AE3 SBC R14,R19 Subtract with carry
+0000022E: 0AF4 SBC R15,R20 Subtract with carry
+0000022F: 9508 RET Subroutine return
+00000230: 92DF PUSH R13 Push register on stack
+00000231: 92EF PUSH R14 Push register on stack
+00000232: 92FF PUSH R15 Push register on stack
+00000233: 930F PUSH R16 Push register on stack
+00000234: 931F PUSH R17 Push register on stack
+00000235: 2ED2 MOV R13,R18 Copy register
+00000236: 2EE3 MOV R14,R19 Copy register
+00000237: 2EF4 MOV R15,R20 Copy register
+00000238: 2F05 MOV R16,R21 Copy register
+00000239: 2F16 MOV R17,R22 Copy register
+0000023A: 916F POP R22 Pop register from stack
+0000023B: 915F POP R21 Pop register from stack
+0000023C: 914F POP R20 Pop register from stack
+0000023D: 913F POP R19 Pop register from stack
+0000023E: 912F POP R18 Pop register from stack
+0000023F: 9508 RET Subroutine return
+00000240: 95C8 LPM Load program memory
+00000241: 9631 ADIW R30,0x01 Add immediate to word
+00000242: 2000 TST R0 Test for Zero or Minus
+00000243: 9508 RET Subroutine return
+00000244: DFFB RCALL PC-0x0004 Relative call subroutine
+00000245: 2CD0 MOV R13,R0 Copy register
+00000246: DFF9 RCALL PC-0x0006 Relative call subroutine
+00000247: 2CE0 MOV R14,R0 Copy register
+00000248: DFF7 RCALL PC-0x0008 Relative call subroutine
+00000249: 2CF0 MOV R15,R0 Copy register
+0000024A: DFF5 RCALL PC-0x000A Relative call subroutine
+0000024B: 2D00 MOV R16,R0 Copy register
+0000024C: 9508 RET Subroutine return
+0000024D: FB07 BST R16,7 Bit store from register to T
+0000024E: 6800 ORI R16,0x80 Logical OR with immediate
+0000024F: F40E BRTC PC+0x02 Branch if T flag cleared
+00000250: 770F ANDI R16,0x7F Logical AND with immediate
+00000251: FB57 BST R21,7 Bit store from register to T
+00000252: 6850 ORI R21,0x80 Logical OR with immediate
+00000253: F40E BRTC PC+0x02 Branch if T flag cleared
+00000254: 775F ANDI R21,0x7F Logical AND with immediate
+00000255: FD07 SBRC R16,7 Skip if bit in register cleared
+00000256: C002 RJMP PC+0x0003 Relative jump
+00000257: FF57 SBRS R21,7 Skip if bit in register set
+00000258: C005 RJMP PC+0x0006 Relative jump
+00000259: 16D2 CP R13,R18 Compare
+0000025A: 06E3 CPC R14,R19 Compare with carry
+0000025B: 06F4 CPC R15,R20 Compare with carry
+0000025C: 0705 CPC R16,R21 Compare with carry
+0000025D: 9508 RET Subroutine return
+0000025E: 152D CP R18,R13 Compare
+0000025F: 053E CPC R19,R14 Compare with carry
+00000260: 054F CPC R20,R15 Compare with carry
+00000261: 0750 CPC R21,R16 Compare with carry
+00000262: 9508 RET Subroutine return
+00000263: E094 LDI R25,0x04 Load immediate
+00000264: 9181 LD R24,Z+ Load indirect and postincrement
+00000265: 938D ST X+,R24 Store indirect and postincrement
+00000266: 959A DEC R25 Decrement
+00000267: F7E1 BRNE PC-0x03 Branch if not equal
+00000268: 9508 RET Subroutine return
+00000269: DEB9 RCALL PC-0x0146 Relative call subroutine
+0000026A: E080 LDI R24,0x00 Load immediate
+0000026B: C003 RJMP PC+0x0004 Relative jump
+0000026C: DEB6 RCALL PC-0x0149 Relative call subroutine
+0000026D: 2F80 MOV R24,R16 Copy register
+0000026E: 7880 ANDI R24,0x80 Logical AND with immediate
+0000026F: 2388 TST R24 Test for Zero or Minus
+00000270: F021 BREQ PC+0x05 Branch if equal
+00000271: 92DF PUSH R13 Push register on stack
+00000272: 92EF PUSH R14 Push register on stack
+00000273: 92FF PUSH R15 Push register on stack
+00000274: 930F PUSH R16 Push register on stack
+00000275: 938F PUSH R24 Push register on stack
+00000276: DEB6 RCALL PC-0x0149 Relative call subroutine
+00000277: 2F80 MOV R24,R16 Copy register
+00000278: 9583 INC R24 Increment
+00000279: F412 BRPL PC+0x03 Branch if plus
+0000027A: DF4C RCALL PC-0x00B3 Relative call subroutine
+0000027B: C01B RJMP PC+0x001C Relative jump
+0000027C: 9580 COM R24 One's complement
+0000027D: 958A DEC R24 Decrement
+0000027E: 5E88 SUBI R24,0xE8 Subtract immediate
+0000027F: F40A BRPL PC+0x02 Branch if plus
+00000280: C015 RJMP PC+0x0016 Relative jump
+00000281: 5088 SUBI R24,0x08 Subtract immediate
+00000282: F41A BRPL PC+0x04 Branch if plus
+00000283: D00C RCALL PC+0x000D Relative call subroutine
+00000284: 22D9 AND R13,R25 Logical AND
+00000285: C010 RJMP PC+0x0011 Relative jump
+00000286: 24DD CLR R13 Clear Register
+00000287: 5088 SUBI R24,0x08 Subtract immediate
+00000288: F41A BRPL PC+0x04 Branch if plus
+00000289: D006 RCALL PC+0x0007 Relative call subroutine
+0000028A: 22E9 AND R14,R25 Logical AND
+0000028B: C00A RJMP PC+0x000B Relative jump
+0000028C: 24EE CLR R14 Clear Register
+0000028D: D002 RCALL PC+0x0003 Relative call subroutine
+0000028E: 22F9 AND R15,R25 Logical AND
+0000028F: C006 RJMP PC+0x0007 Relative jump
+00000290: EF9F SER R25 Set Register
+00000291: 7087 ANDI R24,0x07 Logical AND with immediate
+00000292: 0F99 LSL R25 Logical Shift Left
+00000293: 958A DEC R24 Decrement
+00000294: F7EA BRPL PC-0x02 Branch if plus
+00000295: 9508 RET Subroutine return
+00000296: DEA8 RCALL PC-0x0157 Relative call subroutine
+00000297: 918F POP R24 Pop register from stack
+00000298: 2388 TST R24 Test for Zero or Minus
+00000299: F3D9 BREQ PC-0x04 Branch if equal
+0000029A: 915F POP R21 Pop register from stack
+0000029B: 914F POP R20 Pop register from stack
+0000029C: 913F POP R19 Pop register from stack
+0000029D: 912F POP R18 Pop register from stack
+0000029E: 930F PUSH R16 Push register on stack
+0000029F: DFAD RCALL PC-0x0052 Relative call subroutine
+000002A0: 910F POP R16 Pop register from stack
+000002A1: F399 BREQ PC-0x0C Branch if equal
+000002A2: F390 BRCS PC-0x0D Branch if carry set
+000002A3: D002 RCALL PC+0x0003 Relative call subroutine
+000002A4: 6850 ORI R21,0x80 Logical OR with immediate
+000002A5: CF4C RJMP PC-0x00B3 Relative jump
+000002A6: E35F LDI R21,0x3F Load immediate
+000002A7: E840 LDI R20,0x80 Load immediate
+000002A8: 2733 CLR R19 Clear Register
+000002A9: 2722 CLR R18 Clear Register
+000002AA: 9508 RET Subroutine return
+000002AB: DE77 RCALL PC-0x0188 Relative call subroutine
+000002AC: 930F PUSH R16 Push register on stack
+000002AD: 770F ANDI R16,0x7F Logical AND with immediate
+000002AE: DF3D RCALL PC-0x00C2 Relative call subroutine
+000002AF: DFBD RCALL PC-0x0042 Relative call subroutine
+000002B0: 918F POP R24 Pop register from stack
+000002B1: 7880 ANDI R24,0x80 Logical AND with immediate
+000002B2: 2B08 OR R16,R24 Logical OR
+000002B3: 9508 RET Subroutine return
+000002B4: 2400 CLR R0 Clear Register
+000002B5: 47F4 SBCI R31,0x74 Subtract immediate with carry





[ Diese Nachricht wurde geändert von: admin am 20 Mär 2008 12:09 ]

BID = 509403

bastler16

Schreibmaschine

Beiträge: 2140
Wohnort: Frankreich

So, zweiter Versuch...

[EDIT]
Die Round-Anweisung scheint das CLI zu verursachen.
Der Bascom-Code


Code :


$regfile = "m8def.dat"
$crystal = 1000000
Dim Singlewert As Single

Do

Singlewert = Round(singlewert)

Loop

End



erzeugt den ASM-Code:


Code :


+00000000: C012 RJMP PC+0x0013 Relative jump
+00000001: 9518 RETI Interrupt return
+00000002: 9518 RETI Interrupt return
+00000003: 9518 RETI Interrupt return
+00000004: 9518 RETI Interrupt return
+00000005: 9518 RETI Interrupt return
+00000006: 9518 RETI Interrupt return
+00000007: 9518 RETI Interrupt return
+00000008: 9518 RETI Interrupt return
+00000009: 9518 RETI Interrupt return
+0000000A: 9518 RETI Interrupt return
+0000000B: 9518 RETI Interrupt return
+0000000C: 9518 RETI Interrupt return
+0000000D: 9518 RETI Interrupt return
+0000000E: 9518 RETI Interrupt return
+0000000F: 9518 RETI Interrupt return
+00000010: 9518 RETI Interrupt return
+00000011: 9518 RETI Interrupt return
+00000012: 9518 RETI Interrupt return
+00000013: E58F LDI R24,0x5F Load immediate
+00000014: BF8D OUT 0x3D,R24 Out to I/O location
+00000015: E4C0 LDI R28,0x40 Load immediate
+00000016: E3E8 LDI R30,0x38 Load immediate
+00000017: 2E4E MOV R4,R30 Copy register
+00000018: E084 LDI R24,0x04 Load immediate
+00000019: BF8E OUT 0x3E,R24 Out to I/O location
+0000001A: E0D4 LDI R29,0x04 Load immediate
+0000001B: E0F4 LDI R31,0x04 Load immediate
+0000001C: 2E5F MOV R5,R31 Copy register
+0000001D: EFEE LDI R30,0xFE Load immediate
+0000001E: E0F3 LDI R31,0x03 Load immediate
+0000001F: E6A0 LDI R26,0x60 Load immediate
+00000020: E0B0 LDI R27,0x00 Load immediate
+00000021: 2788 CLR R24 Clear Register
+00000022: 938D ST X+,R24 Store indirect and postincrement
+00000023: 9731 SBIW R30,0x01 Subtract immediate from word
+00000024: F7E9 BRNE PC-0x02 Branch if not equal
+00000025: B784 IN R24,0x34 In from I/O location
+00000026: 2E08 MOV R0,R24 Copy register
+00000027: 7F87 ANDI R24,0xF7 Logical AND with immediate
+00000028: BF84 OUT 0x34,R24 Out to I/O location
+00000029: E18F LDI R24,0x1F Load immediate
+0000002A: BD81 OUT 0x21,R24 Out to I/O location
+0000002B: E087 LDI R24,0x07 Load immediate
+0000002C: BD81 OUT 0x21,R24 Out to I/O location
+0000002D: 2466 CLR R6 Clear Register
+0000002E: E6E0 LDI R30,0x60 Load immediate
+0000002F: E0F0 LDI R31,0x00 Load immediate
+00000030: D101 RCALL PC+0x0102 Relative call subroutine
+00000031: E0ED LDI R30,0x0D Load immediate
+00000032: E0F0 LDI R31,0x00 Load immediate
+00000033: E6A0 LDI R26,0x60 Load immediate
+00000034: E0B0 LDI R27,0x00 Load immediate
+00000035: D0B4 RCALL PC+0x00B5 Relative call subroutine
+00000036: CFF7 RJMP PC-0x0008 Relative jump
+00000037: 94F8 CLI Global Interrupt Disable
+00000038: CFFF RJMP PC-0x0000 Relative jump
+00000039: 9731 SBIW R30,0x01 Subtract immediate from word
+0000003A: F7F1 BRNE PC-0x01 Branch if not equal
+0000003B: 9508 RET Subroutine return
+0000003C: 9468 SET Set T in SREG
+0000003D: F862 BLD R6,2 Bit load from T to register
+0000003E: 9508 RET Subroutine return
+0000003F: 94E8 CLT Clear T in SREG
+00000040: F862 BLD R6,2 Bit load from T to register
+00000041: 9508 RET Subroutine return
+00000042: 94D0 COM R13 One's complement
+00000043: 94E0 COM R14 One's complement
+00000044: 94F0 COM R15 One's complement
+00000045: E091 LDI R25,0x01 Load immediate
+00000046: 0ED9 ADD R13,R25 Add without carry
+00000047: 2799 CLR R25 Clear Register
+00000048: 1EE9 ADC R14,R25 Add with carry
+00000049: 1EF9 ADC R15,R25 Add with carry
+0000004A: 9510 COM R17 One's complement
+0000004B: 9508 RET Subroutine return
+0000004C: 90D1 LD R13,Z+ Load indirect and postincrement
+0000004D: 90E1 LD R14,Z+ Load indirect and postincrement
+0000004E: 90F1 LD R15,Z+ Load indirect and postincrement
+0000004F: 9101 LD R16,Z+ Load indirect and postincrement
+00000050: 9508 RET Subroutine return
+00000051: 9121 LD R18,Z+ Load indirect and postincrement
+00000052: 9131 LD R19,Z+ Load indirect and postincrement
+00000053: 9141 LD R20,Z+ Load indirect and postincrement
+00000054: 9151 LD R21,Z+ Load indirect and postincrement
+00000055: 9508 RET Subroutine return
+00000056: 2F10 MOV R17,R16 Copy register
+00000057: E890 LDI R25,0x80 Load immediate
+00000058: 0CFF LSL R15 Logical Shift Left
+00000059: 1F00 ROL R16 Rotate Left Through Carry
+0000005A: 2709 EOR R16,R25 Exclusive OR
+0000005B: 0F99 LSL R25 Logical Shift Left
+0000005C: 94F7 ROR R15 Rotate right through carry
+0000005D: 7810 ANDI R17,0x80 Logical AND with immediate
+0000005E: 2F65 MOV R22,R21 Copy register
+0000005F: E890 LDI R25,0x80 Load immediate
+00000060: 0F44 LSL R20 Logical Shift Left
+00000061: 1F55 ROL R21 Rotate Left Through Carry
+00000062: 2759 EOR R21,R25 Exclusive OR
+00000063: 0F99 LSL R25 Logical Shift Left
+00000064: 9547 ROR R20 Rotate right through carry
+00000065: 7860 ANDI R22,0x80 Logical AND with immediate
+00000066: 3800 CPI R16,0x80 Compare with immediate
+00000067: 9508 RET Subroutine return
+00000068: 0CFF LSL R15 Logical Shift Left
+00000069: E890 LDI R25,0x80 Load immediate
+0000006A: 2790 EOR R25,R16 Exclusive OR
+0000006B: 0F11 LSL R17 Logical Shift Left
+0000006C: 9597 ROR R25 Rotate right through carry
+0000006D: 94F7 ROR R15 Rotate right through carry
+0000006E: 2F09 MOV R16,R25 Copy register
+0000006F: 9508 RET Subroutine return
+00000070: E79F LDI R25,0x7F Load immediate
+00000071: 2F09 MOV R16,R25 Copy register
+00000072: 2AF9 OR R15,R25 Logical OR
+00000073: EF9F SER R25 Set Register
+00000074: 2ED9 MOV R13,R25 Copy register
+00000075: 2EE9 MOV R14,R25 Copy register
+00000076: 9508 RET Subroutine return
+00000077: 24DD CLR R13 Clear Register
+00000078: 24EE CLR R14 Clear Register
+00000079: 24FF CLR R15 Clear Register
+0000007A: 2700 CLR R16 Clear Register
+0000007B: 2711 CLR R17 Clear Register
+0000007C: 9508 RET Subroutine return
+0000007D: F00A BRMI PC+0x02 Branch if minus
+0000007E: D045 RCALL PC+0x0046 Relative call subroutine
+0000007F: CFE8 RJMP PC-0x0017 Relative jump
+00000080: E35F LDI R21,0x3F Load immediate
+00000081: 2722 CLR R18 Clear Register
+00000082: 2733 CLR R19 Clear Register
+00000083: 2744 CLR R20 Clear Register
+00000084: C001 RJMP PC+0x0002 Relative jump
+00000085: DFCB RCALL PC-0x0034 Relative call subroutine
+00000086: DFCF RCALL PC-0x0030 Relative call subroutine
+00000087: 3850 CPI R21,0x80 Compare with immediate
+00000088: F3B1 BREQ PC-0x09 Branch if equal
+00000089: 3800 CPI R16,0x80 Compare with immediate
+0000008A: F399 BREQ PC-0x0C Branch if equal
+0000008B: 2F90 MOV R25,R16 Copy register
+0000008C: 1B95 SUB R25,R21 Subtract without carry
+0000008D: F38B BRVS PC-0x0E Branch if overflow flag is set
+0000008E: F412 BRPL PC+0x03 Branch if plus
+0000008F: D034 RCALL PC+0x0035 Relative call subroutine
+00000090: CFFA RJMP PC-0x0005 Relative jump
+00000091: 3198 CPI R25,0x18 Compare with immediate
+00000092: F018 BRCS PC+0x04 Branch if carry set
+00000093: 2722 CLR R18 Clear Register
+00000094: 2733 CLR R19 Clear Register
+00000095: 2744 CLR R20 Clear Register
+00000096: 3098 CPI R25,0x08 Compare with immediate
+00000097: F028 BRCS PC+0x06 Branch if carry set
+00000098: 2F23 MOV R18,R19 Copy register
+00000099: 2F34 MOV R19,R20 Copy register
+0000009A: 2744 CLR R20 Clear Register
+0000009B: 5098 SUBI R25,0x08 Subtract immediate
+0000009C: CFF9 RJMP PC-0x0006 Relative jump
+0000009D: 2399 TST R25 Test for Zero or Minus
+0000009E: F029 BREQ PC+0x06 Branch if equal
+0000009F: 9546 LSR R20 Logical shift right
+000000A0: 9537 ROR R19 Rotate right through carry
+000000A1: 9527 ROR R18 Rotate right through carry
+000000A2: 959A DEC R25 Decrement
+000000A3: F7D9 BRNE PC-0x04 Branch if not equal
+000000A4: 2F91 MOV R25,R17 Copy register
+000000A5: 2796 EOR R25,R22 Exclusive OR
+000000A6: F042 BRMI PC+0x09 Branch if minus
+000000A7: D014 RCALL PC+0x0015 Relative call subroutine
+000000A8: F6B0 BRCC PC-0x29 Branch if carry cleared
+000000A9: 94F7 ROR R15 Rotate right through carry
+000000AA: 94E7 ROR R14 Rotate right through carry
+000000AB: 94D7 ROR R13 Rotate right through carry
+000000AC: 5F0F SUBI R16,0xFF Subtract immediate
+000000AD: F68B BRVC PC-0x2E Branch if overflow flag is cleared
+000000AE: CFC1 RJMP PC-0x003E Relative jump
+000000AF: D010 RCALL PC+0x0011 Relative call subroutine
+000000B0: F051 BREQ PC+0x0B Branch if equal
+000000B1: F408 BRCC PC+0x02 Branch if carry cleared
+000000B2: DF8F RCALL PC-0x0070 Relative call subroutine
+000000B3: 20FF TST R15 Test for Zero or Minus
+000000B4: F252 BRMI PC-0x35 Branch if minus
+000000B5: 0CDD LSL R13 Logical Shift Left
+000000B6: 1CEE ROL R14 Rotate Left Through Carry
+000000B7: 1CFF ROL R15 Rotate Left Through Carry
+000000B8: 5001 SUBI R16,0x01 Subtract immediate
+000000B9: F7CB BRVC PC-0x06 Branch if overflow flag is cleared
+000000BA: CFB5 RJMP PC-0x004A Relative jump
+000000BB: CFBB RJMP PC-0x0044 Relative jump
+000000BC: 0ED2 ADD R13,R18 Add without carry
+000000BD: 1EE3 ADC R14,R19 Add with carry
+000000BE: 1EF4 ADC R15,R20 Add with carry
+000000BF: 9508 RET Subroutine return
+000000C0: 1AD2 SUB R13,R18 Subtract without carry
+000000C1: 0AE3 SBC R14,R19 Subtract with carry
+000000C2: 0AF4 SBC R15,R20 Subtract with carry
+000000C3: 9508 RET Subroutine return
+000000C4: 92DF PUSH R13 Push register on stack
+000000C5: 92EF PUSH R14 Push register on stack
+000000C6: 92FF PUSH R15 Push register on stack
+000000C7: 930F PUSH R16 Push register on stack
+000000C8: 931F PUSH R17 Push register on stack
+000000C9: 2ED2 MOV R13,R18 Copy register
+000000CA: 2EE3 MOV R14,R19 Copy register
+000000CB: 2EF4 MOV R15,R20 Copy register
+000000CC: 2F05 MOV R16,R21 Copy register
+000000CD: 2F16 MOV R17,R22 Copy register
+000000CE: 916F POP R22 Pop register from stack
+000000CF: 915F POP R21 Pop register from stack
+000000D0: 914F POP R20 Pop register from stack
+000000D1: 913F POP R19 Pop register from stack
+000000D2: 912F POP R18 Pop register from stack
+000000D3: 9508 RET Subroutine return
+000000D4: FB07 BST R16,7 Bit store from register to T
+000000D5: 6800 ORI R16,0x80 Logical OR with immediate
+000000D6: F40E BRTC PC+0x02 Branch if T flag cleared
+000000D7: 770F ANDI R16,0x7F Logical AND with immediate
+000000D8: FB57 BST R21,7 Bit store from register to T
+000000D9: 6850 ORI R21,0x80 Logical OR with immediate
+000000DA: F40E BRTC PC+0x02 Branch if T flag cleared
+000000DB: 775F ANDI R21,0x7F Logical AND with immediate
+000000DC: FD07 SBRC R16,7 Skip if bit in register cleared
+000000DD: C002 RJMP PC+0x0003 Relative jump
+000000DE: FF57 SBRS R21,7 Skip if bit in register set
+000000DF: C005 RJMP PC+0x0006 Relative jump
+000000E0: 16D2 CP R13,R18 Compare
+000000E1: 06E3 CPC R14,R19 Compare with carry
+000000E2: 06F4 CPC R15,R20 Compare with carry
+000000E3: 0705 CPC R16,R21 Compare with carry
+000000E4: 9508 RET Subroutine return
+000000E5: 152D CP R18,R13 Compare
+000000E6: 053E CPC R19,R14 Compare with carry
+000000E7: 054F CPC R20,R15 Compare with carry
+000000E8: 0750 CPC R21,R16 Compare with carry
+000000E9: 9508 RET Subroutine return
+000000EA: E094 LDI R25,0x04 Load immediate
+000000EB: 9181 LD R24,Z+ Load indirect and postincrement
+000000EC: 938D ST X+,R24 Store indirect and postincrement
+000000ED: 959A DEC R25 Decrement
+000000EE: F7E1 BRNE PC-0x03 Branch if not equal
+000000EF: 9508 RET Subroutine return
+000000F0: DF5B RCALL PC-0x00A4 Relative call subroutine
+000000F1: E080 LDI R24,0x00 Load immediate
+000000F2: C003 RJMP PC+0x0004 Relative jump
+000000F3: DF58 RCALL PC-0x00A7 Relative call subroutine
+000000F4: 2F80 MOV R24,R16 Copy register
+000000F5: 7880 ANDI R24,0x80 Logical AND with immediate
+000000F6: 2388 TST R24 Test for Zero or Minus
+000000F7: F021 BREQ PC+0x05 Branch if equal
+000000F8: 92DF PUSH R13 Push register on stack
+000000F9: 92EF PUSH R14 Push register on stack
+000000FA: 92FF PUSH R15 Push register on stack
+000000FB: 930F PUSH R16 Push register on stack
+000000FC: 938F PUSH R24 Push register on stack
+000000FD: DF58 RCALL PC-0x00A7 Relative call subroutine
+000000FE: 2F80 MOV R24,R16 Copy register
+000000FF: 9583 INC R24 Increment
+00000100: F412 BRPL PC+0x03 Branch if plus
+00000101: DF75 RCALL PC-0x008A Relative call subroutine
+00000102: C01B RJMP PC+0x001C Relative jump
+00000103: 9580 COM R24 One's complement
+00000104: 958A DEC R24 Decrement
+00000105: 5E88 SUBI R24,0xE8 Subtract immediate
+00000106: F40A BRPL PC+0x02 Branch if plus
+00000107: C015 RJMP PC+0x0016 Relative jump
+00000108: 5088 SUBI R24,0x08 Subtract immediate
+00000109: F41A BRPL PC+0x04 Branch if plus
+0000010A: D00C RCALL PC+0x000D Relative call subroutine
+0000010B: 22D9 AND R13,R25 Logical AND
+0000010C: C010 RJMP PC+0x0011 Relative jump
+0000010D: 24DD CLR R13 Clear Register
+0000010E: 5088 SUBI R24,0x08 Subtract immediate
+0000010F: F41A BRPL PC+0x04 Branch if plus
+00000110: D006 RCALL PC+0x0007 Relative call subroutine
+00000111: 22E9 AND R14,R25 Logical AND
+00000112: C00A RJMP PC+0x000B Relative jump
+00000113: 24EE CLR R14 Clear Register
+00000114: D002 RCALL PC+0x0003 Relative call subroutine
+00000115: 22F9 AND R15,R25 Logical AND
+00000116: C006 RJMP PC+0x0007 Relative jump
+00000117: EF9F SER R25 Set Register
+00000118: 7087 ANDI R24,0x07 Logical AND with immediate
+00000119: 0F99 LSL R25 Logical Shift Left
+0000011A: 958A DEC R24 Decrement
+0000011B: F7EA BRPL PC-0x02 Branch if plus
+0000011C: 9508 RET Subroutine return
+0000011D: DF4A RCALL PC-0x00B5 Relative call subroutine
+0000011E: 918F POP R24 Pop register from stack
+0000011F: 2388 TST R24 Test for Zero or Minus
+00000120: F3D9 BREQ PC-0x04 Branch if equal
+00000121: 915F POP R21 Pop register from stack
+00000122: 914F POP R20 Pop register from stack
+00000123: 913F POP R19 Pop register from stack
+00000124: 912F POP R18 Pop register from stack
+00000125: 930F PUSH R16 Push register on stack
+00000126: DFAD RCALL PC-0x0052 Relative call subroutine
+00000127: 910F POP R16 Pop register from stack
+00000128: F399 BREQ PC-0x0C Branch if equal
+00000129: F390 BRCS PC-0x0D Branch if carry set
+0000012A: D002 RCALL PC+0x0003 Relative call subroutine
+0000012B: 6850 ORI R21,0x80 Logical OR with immediate
+0000012C: CF59 RJMP PC-0x00A6 Relative jump
+0000012D: E35F LDI R21,0x3F Load immediate
+0000012E: E840 LDI R20,0x80 Load immediate
+0000012F: 2733 CLR R19 Clear Register
+00000130: 2722 CLR R18 Clear Register
+00000131: 9508 RET Subroutine return
+00000132: DF19 RCALL PC-0x00E6 Relative call subroutine
+00000133: 930F PUSH R16 Push register on stack
+00000134: 770F ANDI R16,0x7F Logical AND with immediate
+00000135: DF4A RCALL PC-0x00B5 Relative call subroutine
+00000136: DFBD RCALL PC-0x0042 Relative call subroutine
+00000137: 918F POP R24 Pop register from stack
+00000138: 7880 ANDI R24,0x80 Logical AND with immediate
+00000139: 2B08 OR R16,R24 Logical OR
+0000013A: 9508 RET Subroutine return


(CLI an 0x37)

BID = 509477

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Interessant.

Solche Sachen sollte man einen µC nur rechnen lassen, wenn die Zeit keine Rolle spielt. Hier sollte man versuchen, anders vorzugehen, z.b. mit Hilfe von Tabellen (die wäre hier 2kB groß für jeden Wert des ADUs).
Edit: natürlich nicht 2kB pro Wert, sondern insgesamt.

Der Wert des ADUs wird als Offset auf die Tabellenbasis hinzugerechnet, an dem Bereich steht dann der Wert für das OC-Register.

Ist zwar nicht sehr Speichereffizient, aber hundsschnell.

Allerdings kann ich dir nicht sagen, wie man das mit dem Basic-compiler hinbekommt.

In C linkt man einfach eine Binärdatei oder ein Assemblercode hinzu, in der die entsprechenden Symbole und Tabellen definiert sind. In Basic? - Keine Ahnung. Array ist eine schlechte Idee, da zu wenig SRAM vorhanden (und noch ineffizienter...) .

Was mir noch auffällt:
Bei 1024 Quantisierungsstufen des Potis kann ich mir ehrlich gesagt nicht vorstellen, dass es da in den Bits 0-2 nicht "rauscht".
Ich würde daher mit 10Bit quantisieren, und die letzen beiden LSBs verwerfen. Dann bleibt effektiv zwar "nur noch" 8 Bit Auflösung über, aber es rauscht nicht mehr, und die Tabellen können kleiner werden.

Denn ein Standard-Poti in 1024 Stufen zu digitalisieren ist etwas overkill hierfür.
Oder die Frequenzeinstellung anders vornehmen.



_________________


[ Diese Nachricht wurde geändert von: DonComi am 20 Mär 2008 17:44 ]

BID = 509489

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Na klar, ich kann ja für den ADU von vorn herein auch 8 Bit Auflösung einstellen und ich habe auch nicht den Ehrgeiz, wirklich 1024 Stufen einstellen zu können. Ich dachte aber nicht, daß es Probleme macht.

Sicher wird das Poti auch "rauschen", aber man beachte, daß der Fehler auch aufgetreten ist, als ich probehalber das Programm so geändert habe, daß der Timergrenzwert von 0 bis 1023 durchgezählt wird und nach jedem Schritt habe ich die laaange Zeit von 10 ms gewartet! Es kann also auch kein Problem des Rauschens bzw. der analog-digital-Umsetzung sein.

Die Rechnerei habe ich ja nun schon von Single auf Long geändert, wodurch wesentlich weniger Speicher verbraucht wird, also auch viel weniger Programmschritte auszuführen sind. Natürlich ist eine Wertetabelle möglich, aber der Prozessor hat sich doch sonst um nichts zu kümmern, so sehr im Streß kann er doch gar nicht sein, auch nicht mit nur 1 MHz Taktfrequenz, blitzbombenelementnochmal!

Ich bin ja immer noch der Meinung, daß dieser Fehler bei ganz bestimmten "exponierten" Timerwerten auftritt. Nur kriege ich das mit Drehen per Hand am Poti nicht raus. Ich muß mal sehen, daß ich die oben erwähnte "Automatisierung" noch mal programmiere und mir irgendwie anzeigen lasse, bei welchem "Poti-Wert" bzw. bei welchem Timerwert das Programm gerade ist. Mal sehen, ob es vielleicht wirklich mit solchen "Quantensprüngen" á la &H0FF/&H100 zu tun hat. (Wenn ja, weiß ich aber auch noch nicht, wo genau denn nun der Hase im Pfeffer liegt...)

Das verschiebe ich aber wirklich auf den nächsten Arbeitstag!


Ich muß hier noch einmal sagen, daß ich mit diesem kleinen Fehler wirklich leben kann, dadurch am zu prüfenden Gerät auch nichts beschädigt wird und ich schaltungsmäßig nichts mehr ändern will.
Die Ratgeber mögen jetzt aber bitte nicht denken, daß sie sich umsonst Gedanken machen bzw. gemacht haben, denn ich möchte wirklich gern hinter diese Sache kommen und strenge ja meine grauen Zellen auch ein bißchen an. Und zwar umso mehr, als ein ATmega8 und bei einer Weiterentwicklung ein ATmega32 mich schon einmal geärgert haben, indem in einem ansonsten reibungslos funktionierenden Programm plötzlich die LCD-Anzeige unsinniges Zeug darstellte. (Da gibt es hier auch irgendwo noch eine Anfrage von mir.) "Es gibt mehr Dinge zwischen Plus und Minus, als unsere Schulweisheit sich träumen läßt", wie es im Hamlet heißt (oder so ähnlich...) und ich würde diese kleinen Boshaftigkeiten gern verstehen und damit abstellen können.

Nun aber erst mal allen Helfern meinen Dank, schöne Feiertage und eine frohe Eierei!

BID = 509493

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Ich verstehe auch nicht ganz, warum das OCR immer neugeschrieben wird. Dabei kann es zu solchen Sprüngen kommen!

Mach doch einen Vergleich mit dem alten Wert des ADUs, und nur wenn der sich wirklich geändert hat, dann auch OCR updaten. Sonst ist das murks.

Wenn z.b. der Timer TCNT auf 10 steht, und der neue Wert auf 9 gesetzt wird, dann rattert der bis 0xffff durch. Da entstehen die Fehler.

Zudem würde in solchen Fällen eine Simulation helfen. Du kannst auch durch Basic erzeugte Objektdateien im AVR-Studio laden und simulieren.

Edit2:
Das Highbyte muss zuerst geschrieben werden, ist hier aber auch korrekt gemacht worden.

Ich würde dafür sorgen, z.b. im Compare-Match Interrupt, dass erst nach diesem Interrupt ein neuer Vergleichswert geladen werden darf.

_________________




[ Diese Nachricht wurde ge&auml;ndert von: DonComi am 20 Mär 2008 19:15 ]

[ Diese Nachricht wurde ge&auml;ndert von: DonComi am 20 Mär 2008 19:16 ]

[ Diese Nachricht wurde geändert von: DonComi am 20 Mär 2008 19:17 ]

BID = 509657

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Daran, den Wert nur bei Bedarf, d. h. wenn er sich wirklich geändert hat, neu zu schreiben, hatte ich auch schon gedacht. Nur (ich wiederhole mich, ich weiß!) wundert es mich eben, daß der Fehler auch auftritt, wenn ich den Wert zu Testzwecken programmgesteuert in einer Schleife hochzählen lasse.

Auch dein letzter Tip hört sich vernünftig an. Ich werde also folgendes probieren:

- nur 8 Bit Auflösung
- nur bei Bedarf neuen Wert schreiben
- erst nach erfolgtem Interrupt neuen Wert schreiben

Ich bin gespannt!

BID = 509732

BjörnB

Stammposter

Beiträge: 242
Wohnort: Dortmund

Hallo,

eigentlich sollte der Wert für den Timer im Timerinterrupt und nicht im Hauptprogramm neu geschrieben werden. Damit ist sichergestellt, dass die einzelnen PWM-Durchläufe immer sauber beendet werden. Im Hauptprogramm wird dazu am besten eine globale Variable beschrieben, aus der man sich im Timerinterrupt den jeweils aktuellen Wert herausgreift.

Schöne Grüße,
Björn

BID = 509738

PhyMaLehrer

Schriftsteller



Beiträge: 908
Wohnort: Leipzig

Die Sache hat mir doch keine Ruhe gelassen und ich habe meine Experimentierplatine aktiviert und das Programm drauf gespielt. Hier habe ich natürlich den "verspielten" LED-Kreis nicht, sondern habe je eine LED an die zueinander invertierten Ausgänge geklemmt. Au weia, irgendwie sah das hier noch viel schlimmer aus! An vielen Stellen des Bereiches des Einstellwiderstandes ging ein Zucken durch die LEDs, die eigentlich (bis auf ganz am Anfang) quasi dauernd leuchten sollten! In mancher Stellung zuckten sie sogar anhaltend!

Die Beschränkung der Auflösung des ADUs hat's nicht gebracht, auch nicht das Schreiben des Wertes nur bei Bedarf. Aber das Speichern des Timerwertes in der Interruptroutine! DonComi und BjörnB hatten recht! Wenn ich darüber nachdenke, verstehe ich die Erklärung auch.

Der Vollständigkeit halber muß ich sagen, daß bei schnellem Drehen am Einstellwiderstand (was ich so in der Praxis nicht tun werde) an einer Stelle des EInstellbereichs noch ein kleiner Fehler ist, aber auch nur manchmal und eben nur bei (zu) großer Drehgeschwindigkeit. Da scheinen einige ungünstige Umstände zusammenzutreffen.

Ich habe, da die Beschränkung auf 256 Werte keine weitere Verbesserung brachte, jetzt 512 Werte genommen; dann paßt meine Rechnung gerade noch in WORD-Variablen. So sieht das Programm jetzt aus:


Code :

'*******************************************************************************

'* Frequenzgenerator für TCP120-Tester *
'*******************************************************************************

'-------------------------------------------------------------------------------

' µC Deklarationen
$regfile = "m8def.dat" 'ATmega8-Deklarationen
$crystal = 1000000 'interner RC-Generator 1 MHz

'-------------------------------------------------------------------------------

' Ein-/Ausgänge
'B0: Ausgang A1
'B1: Ausgang A2
Config Portb = &B00000011
A1 Alias Portb.0
A2 Alias Portb.1
Portb = 0
'C3: Eingang für Frequenzeinstellung
Config Portc = &B00000000

'-------------------------------------------------------------------------------

' ADU
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'-------------------------------------------------------------------------------

' Variablen
Dim F As Word 'ADU-Wert des Potis zur Frequenzeinstellung
Dim Timerwert As Word 'Grenzwert für CTC-Modus
Dim Timerwert_alt As Word 'alten Wert merken
'-------------------------------------------------------------------------------

'Timer-Interrupt
Config Timer1 = Timer , Prescale = 1 'Timer, kein Vorteiler
Ocr1ah = High(timerwert) 'OCR1A setzen
Ocr1al = Low(timerwert)
Tccr1a = 0 'Timer1 im CTC-Modus
Set Tccr1b.3
On Compare1a Timerinterrupt
Enable Compare1a
Enable Interrupts 'Interrupts global freigeben

'-------------------------------------------------------------------------------

'+----------------+
'| Programmbeginn |
'+----------------+

'HAUPTPROGRAMM

Set A1

Do
F = Getadc(3) 'Spannung für Frequenzeinstellung lesen
Shift F , Right 'F = F / 2
If F < 2 Then 'keine Werte < 2
F = 2
End If
Timerwert = 62500 \ F 'Timerwert berechnen
Loop

End


'INTERRUPT

Timerinterrupt:
Toggle A1
Toggle A2
If Timerwert <> Timerwert_alt Then
Ocr1ah = High(timerwert) 'OCR1A setzen
Ocr1al = Low(timerwert)
Timerwert_alt = Timerwert
End If
Return

Damit halte ich das Problem für gelöst, kann ruhig schlafen und sage nochmals Dankeschön für die guten Tips!


      Nächste Seite
Gehe zu Seite ( 1 | 2 Nächste Seite )
Zurück zur Seite 0 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 15 Beiträge im Durchschnitt pro Tag       heute wurden bisher 9 Beiträge verfasst
© x sparkkelsputz        Besucher : 181360820   Heute : 1684    Gestern : 5828    Online : 719        27.5.2024    11:02
2 Besucher in den letzten 60 Sekunden        alle 30.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.0862400531769