Hallo Forum, ich habe ein kleines Problem: Ich programmiere zur Zeit eine AVR ATMEGE 8535 und weis nicht wehr weiter. Ich möchte eine 16-Bit-Zähler realisieren. Wenn ich folgendes UP benutze funktioniert alles rc5_zeit_messung: lds tmp2,rc5_dauer_low inc tmp2 sts rc5_dauer_low,tmp2 breq zeitg_0_ueberlauf1 zeitg_0_ueberlauf2: ret zeitg_0_ueberlauf1: lds tmp2,rc5_dauer_high inc tmp2 sts rc5_dauer_high,tmp2 rjmp zeitg_0_ueberlauf2 Benutze ich dagegen diese UP, funktioniert fast gar nichts mehr rc5_zeit_messung: lds tmp2,rc5_dauer_low inc tmp2 sts rc5_dauer_low,tmp2 brne zeitg_0_ueberlauf2 lds tmp2,rc5_dauer_high inc tmp2 sts rc5_dauer_high,tmp2 zeitg_0_ueberlauf2: ret Der einzige Unterschied ist, einmal nehme ich breq und das andere mal brne. Kann mir jemand helfen und mir sagen warum es einmal funktioniert und das andere mal nicht?
Hallo, die Befehle "breq" -> Springe bei gleich "brne" -> Springe bei ungleich werden nach einem test auf 0 "tst" oder nach einem Vergleich "cp..." geschrieben. In deinem Prog sehe ich solche codezeilen nicht !!! gruss Marc
Die beiden Varianten habe die gleiche Funktion, aber unterschiedliches Zeitverhalten. Vielleicht liegt da der Hund begraben.
Hallo, Marc B. schrieb: > Hallo, > > die Befehle "breq" -> Springe bei gleich > "brne" -> Springe bei ungleich > > werden nach einem test auf 0 "tst" oder nach einem Vergleich "cp..." > geschrieben. Auch, ja... > > In deinem Prog sehe ich solche codezeilen nicht !!! dafür gibt es inc und das beeinflußt Z ebenfalls und ein paar andere befehle auch... Ach ja: wenn Du da platz hast vielleicht auch über lds XH,rc5_dauer_high lds XL,rc5_dauer_low adiw X,1 sts rc5_dauer_high,XH sts rc5_dauer_high,XL hätte da dann immer die gleiche Laufzeit. Geht auch mit anderen Registerpaaren, siehe ASM-Befehle. Gruß aus Berlin Michael
Bis auf die beiden Taktzyklen des RJMP sollte der Code gleich sein. Geht das?
1 | rc5_zeit_messung: |
2 | lds tmp2,rc5_dauer_low |
3 | inc tmp2 |
4 | sts rc5_dauer_low,tmp2 |
5 | brne zeitg_0_ueberlauf2 |
6 | lds tmp2,rc5_dauer_high |
7 | inc tmp2 |
8 | sts rc5_dauer_high,tmp2 |
9 | NOP |
10 | NOP |
11 | zeitg_0_ueberlauf2: |
12 | ret |
Marc B. schrieb: > die Befehle "breq" -> Springe bei gleich > "brne" -> Springe bei ungleich > > werden nach einem test auf 0 "tst" oder nach einem Vergleich "cp..." > geschrieben. > > In deinem Prog sehe ich solche codezeilen nicht !!! Das ist auch gar nicht nötig: brne und breq beziehen sich einfach auf den letzten Operator, der das Z-Flag verändert, in diesem Fall den inc. Ein tst oder cp muss nicht vorangegangen sein.
Die unterschiedliche Ausführungszeit für BRQE/BRNE für den zutreffenden Fall/nicht zutreffenden Fall könnte man auch noch berücksichtigen. Kann mein Beispiel oben leider nicht mehr editieren.
Ihr seit ja super schnell, hier noch eine Kleinigkeit. Ich löse alle 100 uS einen Timer1-Int aus, zähle dann mit vier Zählern, jeweils bis 10, so habe kann ich dann ms-, 10ms-, 100ms- und s-weise zählen. Das ist das Einzige was in der Routine erledigt wird. Im HP springe ich dann immer zu folgende Auswertroutine:
1 | ;------------------------------------------------------- |
2 | |
3 | interruptabfrage: |
4 | lds tmp1,interruptflag1 |
5 | |
6 | ;--------------------------------------------- |
7 | bst tmp1,0 |
8 | brtc interruptabfrage20 |
9 | |
10 | ;10000/sek------------------------------------ |
11 | |
12 | ;--------------------------------------------- |
13 | clt |
14 | bld tmp1,0 |
15 | |
16 | interruptabfrage20: |
17 | bst tmp1,1 |
18 | brtc interruptabfrage30 |
19 | clt |
20 | bld tmp1,1 |
21 | |
22 | ;1000/sek------------------------------------- |
23 | rcall displaydatenst |
24 | rcall displayhwsteuerung |
25 | rcall rc5_zeit_messung |
26 | |
27 | ;--------------------------------------------- |
28 | interruptabfrage30: |
29 | bst tmp1,2 |
30 | brtc interruptabfrage40 |
31 | clt |
32 | bld tmp1,2 |
33 | ;100/sek-------------------------------------- |
34 | ;rcall zaehleranzeigen |
35 | ;--------------------------------------------- |
36 | |
37 | interruptabfrage40: |
38 | bst tmp1,3 |
39 | brtc interruptabfrage50 |
40 | clt |
41 | bld tmp1,3 |
42 | ;10/sek--------------------------------------- |
43 | |
44 | ;--------------------------------------------- |
45 | |
46 | |
47 | interruptabfrage50: |
48 | bst tmp1,4 |
49 | brtc interruptabfrage60 |
50 | clt |
51 | bld tmp1,4 |
52 | ;1 sek---------------------------------------- |
53 | rcall test150 |
54 | rcall uhrzeit |
55 | rcall uhranzeigen |
56 | ;--------------------------------------------- |
57 | |
58 | interruptabfrage60: |
59 | sts interruptflag1,tmp1 |
60 | ret |
61 | ;------------------------------------------------------- |
Wenn ich jetzt den 16-Bit-Zähler mit brne realisiere funktioniert die ganze Geschichte nicht. Mit breq dagegen super.
Hi >Wenn ich jetzt den 16-Bit-Zähler mit brne realisiere funktioniert die >ganze Geschichte nicht. Mit breq dagegen super. Und wie sieht die Interruptroutine aus? MfG Spess
Und hier die Int-Routine
1 | ;--------------------------------------------- |
2 | ;Hier wird bei jedem Zeitgeberueberlauf eine |
3 | ;250 in das Register zurueckgeladen, damit |
4 | ;wird eine Frequenz von 10000 Hertz erzeugt. |
5 | |
6 | ;--------------------------------------------- |
7 | ;Einsprungprozedur |
8 | ;Retten der tmporaeren Register tmp1, tmp2 |
9 | ;und SREG |
10 | zeitgeber_up: |
11 | push tmp1 |
12 | |
13 | ;--------------------------------------------- |
14 | ;Zaehler mit 230 laden |
15 | ldi tmp1,230 |
16 | out TCNT0,tmp1 |
17 | push tmp2 |
18 | in tmp1,SREG |
19 | push tmp1 |
20 | lds tmp2,interruptflag1 |
21 | set |
22 | ;--------------------------------------------- |
23 | ;10000 mal in der Sekunde |
24 | bld tmp2,0 |
25 | lds tmp1,zeitz4 |
26 | inc tmp1 |
27 | sts zeitz4,tmp1 |
28 | cpi tmp1,10 |
29 | brlo zeitgeber_0_ueberlauf_ende |
30 | clr tmp1 |
31 | sts zeitz4,tmp1 |
32 | |
33 | ;--------------------------------------------- |
34 | ;1000 mal in der Sekunde |
35 | bld tmp2,1 |
36 | lds tmp1,zeitz3 |
37 | inc tmp1 |
38 | sts zeitz3,tmp1 |
39 | cpi tmp1,10 |
40 | brlo zeitgeber_0_ueberlauf_ende |
41 | clr tmp1 |
42 | sts zeitz3,tmp1 |
43 | |
44 | ;--------------------------------------------- |
45 | ;100 mal in der Sekunde |
46 | bld tmp2,2 |
47 | lds tmp1,zeitz2 |
48 | inc tmp1 |
49 | sts zeitz2,tmp1 |
50 | cpi tmp1,10 |
51 | brlo zeitgeber_0_ueberlauf_ende |
52 | clr tmp1 |
53 | sts zeitz2,tmp1 |
54 | ;--------------------------------------------- |
55 | ;10 mal in der Sekunde |
56 | bld tmp2,3 |
57 | lds tmp1,zeitz1 |
58 | inc tmp1 |
59 | sts zeitz1,tmp1 |
60 | cpi tmp1,10 |
61 | brlo zeitgeber_0_ueberlauf_ende |
62 | clr tmp1 |
63 | sts zeitz1,tmp1 |
64 | rcall test160 |
65 | ;--------------------------------------------- |
66 | ;1 mal in der Sekunde |
67 | bld tmp2,4 |
68 | |
69 | zeitgeber_0_ueberlauf_ende: |
70 | ;--------------------------------------------- |
71 | ;Zurueckspeichern der tmporaeren Register SREG,tmp1 und tmp2 |
72 | sts interruptflag1,tmp2 |
73 | pop tmp1 |
74 | out SREG,tmp1 |
75 | pop tmp2 |
76 | pop tmp1 |
77 | reti |
Hi! >Wenn ich jetzt den 16-Bit-Zähler mit brne realisiere funktioniert die >ganze Geschichte nicht. Mit breq dagegen super. Ist ja auch normal. inc lowbyte setzt bei 0(Überlauf) das Z-Flag->breq wird ausgelöst also wird lowbyte bis 255 gezählt und dann highbyte +1 Wenn du brne benutzt wird bei jedem inc das Highbyte mit erhöht. Viel Erfolg, Uwe
Bei brne und breq mache ich ja verschiedene Programmschritt (siehe oben). Kann es sein, daß meine AVR-Version veraltet ist?
linuxdxs schrieb: > Bei brne und breq mache ich ja verschiedene Programmschritt (siehe > oben). Kann es sein, daß meine AVR-Version veraltet ist? Unwahrscheinlich, dass sich das so auswirkt. Bist du dem unterschiedlichen Zeitverhalten schon nachgegangen?
In diesem Falle sollte das Zeitverhalten, so denke ich, doch gar nichts ausmachen. Der AVR rennt mit 16 MHz. Im Datenblatt steht für beide Befehle 1/2 Clocks. Wie soll ich das unterschieliche Zeitverhalten verstehen. Gehe ich richtig in der Annahme, daß bei einer Frequenz von 16 MHz, der AVR 16000000 1-Clock Befehle in der Sekunde durchführt?
Hi >Gehe ich richtig in der Annahme, daß bei einer Frequenz von >16 MHz, der AVR 16000000 1-Clock Befehle in der Sekunde durchführt? Ja. MfG Spess
Vielleicht hab ich Tomaten auf den Augen. Aber in den beiden zuletzt geposteten Codestpücken kommt kein einziger breq, brne vor!
Ja, einmal habe ich dir Rotine gesendet, von der, der Zähler aufgerufen wird. Der Zweitecodeteil ist dafür verantwortlich, wird durch Int angesprungen, daß das Bit gesetzt wird, welches dafür sorgt, dem zuvor erwähnten Programm mitzuteilen, das es soweit ist den Zähler anzuspringen.
Karl heinz Buchegger schrieb: > Vielleicht hab ich Tomaten auf den Augen. > Aber in den beiden zuletzt geposteten Codestpücken kommt kein einziger > breq, brne vor! Naja, wie soll man denn sonst auf ne hohe Anzahl von Antworten kommen? Wenn er sich mal aufgerafft hätte, nen kompletten, realen, getesteten, compilierbaren Code als Dateianhang zu posten, wäre die Sache bestimmt schon längst gegessen. Peter
Hallo hier bin ich wieder. Also das ganze bis jetzt geschriebene Programm. Tut mir leid, habe gedacht, daß es vielleicht ein ganz einfaher Fehler wäre, nach dem Motto, hei da war doch was. Ich sende morgen in einem Anhang das Programm, wenn es denn noch jemanden interessiert.
Hallo ich habe es geschafft. Im Anhang eine lauffähige Version meines Programmes. Im unteren Teil sieht man folgende auskommendierten Zeilen ;brne zeitgeber_0_ueberlauf1 ;lds tmp2,rc5_dauer_high ;inc tmp2 ;sts rc5_dauer_high,tmp2 wieder einkommendiert. Funktioniert die ganze Sache nicht mehr ganz richtig. Ich muß noch dazu sagen, daß die UP test150 und test160 im Sekundentakt( oder zumindest gleichmäßig) angesprungen werden müssen, und wenn man die Änderung gemacht hat funktioniert das eben zumindest mit test150 nicht mehr.
Also ich seh da überhaupt nicht durch, das ist ja ne wilde Hin- und Herspringerei. Mach mal nen großen Strich, darüber alles im Main-Kontext und darunter alles im Interrupt. Was willst Du außerdem mit der ewigen SREG-Pusherei? Nimm Dir ein Register, z.B. R2, und darin wird SREG einmal zu Interruptanfang gesichert und vor dem RETI wieder geladen, aus, fertig. Peter
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.