Forum: Mikrocontroller und Digitale Elektronik Unterschied zwischen brne breq


von linuxdxs (Gast)


Lesenswert?

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?

von MarioT (Gast)


Lesenswert?


von Marc B. (belgo)


Lesenswert?

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

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die beiden Varianten habe die gleiche Funktion, aber unterschiedliches
Zeitverhalten. Vielleicht liegt da der Hund begraben.

von Michael U. (amiga)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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

von Hc Z. (mizch)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von linuxdxs (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von linuxdxs (Gast)


Lesenswert?

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

von Uwe (Gast)


Lesenswert?

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

von linuxdxs (Gast)


Lesenswert?

Bei brne und breq mache ich ja verschiedene Programmschritt (siehe 
oben). Kann es sein, daß meine AVR-Version veraltet ist?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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?

von linuxdxs (Gast)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

Vielleicht hab ich Tomaten auf den Augen.
Aber in den beiden zuletzt geposteten Codestpücken kommt kein einziger 
breq, brne vor!

von linuxdxs (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von linuxdxs (Gast)


Lesenswert?

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.

von linuxdxs (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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
Noch kein Account? Hier anmelden.