Forum: Mikrocontroller und Digitale Elektronik ATtiny26 Wie Systemtakt weiter herunterteilen ?


von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo zusammen,

ist es beim ATtiny26 gar nicht möglich den Sytemtakt durch einen
Vorteiler herunter zu teilen ?

Beim ATtiny13 geht das ja über das Register CLKPR – Clock Prescale
Register.

Kann ich beim Calibrated Internal RC Oscillator als kleinsten Systemtakt
nur 1Mhz einstellen oder gibt es da doch noch einen Vorteiler, der sich
nur anders nennt ?

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Weiß das hier wirklich niemand ?


Bernd_Stein

von Floh (Gast)


Lesenswert?

Sinnfrage, wozu willst du den Takt runterstellen?
:-)

von MWS (Gast)


Lesenswert?

Bernd Stein schrieb:
> Weiß das hier wirklich niemand ?

Doch, das wissen hier sicher viele - nachdem sie in's Datenblatt 
geschaut haben. Was hindert Dich daran, da selbst mal 'nen Blick 
reinzuwerfen ?

von spess53 (Gast)


Lesenswert?

Hi

>Weiß das hier wirklich niemand ?

Doch, das Datenblatt. Und das sagt nein. Wenn du das wirklch brauchst 
solltest du auf einen Nachfolger des ATTiny26 ausweichen: 
ATTiny261/461/861.

MfG Spess

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Floh schrieb:
> Sinnfrage, wozu willst du den Takt runterstellen?
> :-)
>
Um z.B. eine Zeitspanne von acht Stunden mit wenig Programmieraufwand 
erfassen zu können. Außerdem dachte ich, das so etwas bei ATMEL Standard 
ist, weil dadurch ja auch die Leistungsaufnahme vom µC gesenkt werden 
kann.

Bernd_Stein

von spess53 (Gast)


Lesenswert?

Hi

>Außerdem dachte ich, das so etwas bei ATMEL Standard ist, weil dadurch ja
>auch die Leistungsaufnahme vom µC gesenkt werden kann.

Bei neueren stimmt das. Aber der ATTiny26 ist nicht mehr ganz taufrisch.

MfG Spess

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Weiß das hier wirklich niemand ?
>
> Doch, das Datenblatt. Und das sagt nein. Wenn du das wirklch brauchst
> solltest du auf einen Nachfolger des ATTiny26 ausweichen:
> ATTiny261/461/861.
>
> MfG Spess
>
Danke,

dann habe ich doch nichts übersehen bzw. alles in Bezug darauf richtig 
verstanden. Mal sehen wie ich das mit den acht Stunden hinbekomme,
bei einem Systemtakt von einem Megahertz.

Bernd_Stein

von spess53 (Gast)


Lesenswert?

Hi

>Mal sehen wie ich das mit den acht Stunden hinbekomme,
>bei einem Systemtakt von einem Megahertz.

Das ist doch nun kein Hexenwerk einen Softwarezähler zu implementieren.

MfG Spess

von Cyblord -. (cyblord)


Lesenswert?

OMG ein riesen Problem und fast unmöglich ohne den Systemtakt 
runterzustellen....

Du nimmst einen Timer (der tiny26 hat halt leider nur 8 bit timer) und 
stellst ihn auf den höchsten Prescaler (clk/1024) ein. Dann machst du 
einen Overflow-Interrupt, welcher den Controller gleich noch aus einem 
Energiesparmodus aufweckt (wenn dir Stromverbrauch wichtig ist) und 
zählst bei jedem dieser Wakeups eine Variable hoch. Wenn du eine 
uint64_t nimmst kannst du mit einer einzigen Variabeln so bis zum st. 
nimmerlein tag zählen.

von Hannes L. (hannes)


Lesenswert?

cyblord ---- schrieb:
> Dann machst du einen Overflow-Interrupt, welcher den Controller gleich
> noch aus einem Energiesparmodus aufweckt

Im (richtigen) Energiesparmodus läuft kein Timer mehr...

Bernd Stein schrieb:
> Mal sehen wie ich das mit den acht Stunden hinbekomme,
> bei einem Systemtakt von einem Megahertz.

Na (wie bereits gesagt) mit einem Software-Zähler, der Deine 8 Stunden 
in Einheiten des Timer-Intervalls herunterzählt.

...

von Cyblord -. (cyblord)


Lesenswert?

Hannes Lux schrieb:
> cyblord ---- schrieb:
>> Dann machst du einen Overflow-Interrupt, welcher den Controller gleich
>> noch aus einem Energiesparmodus aufweckt
>
> Im (richtigen) Energiesparmodus läuft kein Timer mehr...

Ich sprach nicht von DEM Energiesparmodus sondern von EINEM. Er muss 
halt im Datenblatt nach einem Sleep Mode gucken wo der Timer noch läuft.

von Hannes L. (hannes)


Lesenswert?

cyblord ---- schrieb:
> Er muss
> halt im Datenblatt nach einem Sleep Mode gucken wo der Timer noch läuft.

Das ist der Idle-Mode, der bringt aber kaum Energieeisparung...

...

von Cyblord -. (cyblord)


Lesenswert?

Hannes Lux schrieb:
> cyblord ---- schrieb:
>> Er muss
>> halt im Datenblatt nach einem Sleep Mode gucken wo der Timer noch läuft.
>
> Das ist der Idle-Mode, der bringt aber kaum Energieeisparung...
>
> ...

Ja mei dann wird halt keine Energie gespart...

Hab mal aus Interesse geguckt wie lang man damit zählen kann:

Also mal gerechnet, bei einem 8 Bit Timer, 1MHz clk und clk/1024 
Prescaler kommt man auf einem Timer Overflow Interrupt alle 0,262144 
Sekunden.
Eine uint64_t Variable kann von 0 bis 18446744073709551615 zählen. Dann 
solten das
 oder ca. 153339145055 Jahre sein.

Ganz schön lange.

von Paul Baumann (Gast)


Lesenswert?

cyblord schrob:
>...oder ca. 153339145055 Jahre sein.

Du hast wohl einen Taschenrechner mit anreihbarem Display?

;-)

MfG Paul

von Hannes L. (hannes)


Lesenswert?

cyblord ---- schrieb:
> Eine uint64_t Variable

Bernd werkelt in Assembler...

;-)))

...

von spess53 (Gast)


Lesenswert?

Hi

>cyblord ---- schrieb:
>> Eine uint64_t Variable

>Bernd werkelt in Assembler...

Dann geht es auch problemlos grösser.

MfG Spess

von Hannes L. (hannes)


Lesenswert?

spess53 schrieb:
> Dann geht es auch problemlos grösser.

Und auch effizient kleiner, z.B. 3 Bytes oder 5 Bytes...

Man hat halt mehr Freiheiten, muss sich nicht auf vordefinierte Dinge 
beschränken, muss dafür aber mehr aufpassen...

;-)))

...

von Achim M. (minifloat)


Lesenswert?

Hannes Lux schrieb:
> Man hat halt mehr Freiheiten, muss sich nicht auf vordefinierte Dinge
> beschränken, muss dafür aber mehr aufpassen...

Rechnen im 7er-System... mfg mf

von Hannes L. (hannes)


Lesenswert?

Mini Float schrieb:
> Rechnen im 7er-System... mfg mf

Oder 6-Bit-System wie das Mega8-Board von MyAVR. ;-))

...

von Peter D. (peda)


Lesenswert?

Bernd Stein schrieb:
> Um z.B. eine Zeitspanne von acht Stunden mit wenig Programmieraufwand
> erfassen zu können.

Du hast noch nie programmiert, stimmts?

Das Zählen einer Variablen ist für niemanden ein Aufwand, selbst 
Anfänger lernen das ohne Probleme.


Peter

von Cyblord -. (cyblord)


Lesenswert?

Hannes Lux schrieb:

> Man hat halt mehr Freiheiten, muss sich nicht auf vordefinierte Dinge
> beschränken, muss dafür aber mehr aufpassen...

Ja natürlich. Jemand der nicht in der Lage ist, eine Variable 
hochzuzählen, der braucht natürlich unbedingt die Freiheiten von ASM und 
kann sich nicht auf eine so beschränkte Sprache wie C einlassen....

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Peter Dannegger schrieb:
> Bernd Stein schrieb:
>> Um z.B. eine Zeitspanne von acht Stunden mit wenig Programmieraufwand
>> erfassen zu können.
>
> Du hast noch nie programmiert, stimmts?
>
Doch aber sehr schlecht.
So schlecht, das ich noch kein Programm wirklich nach meinen 
Vorstellungen verwirklicht habe.
>
> Das Zählen einer Variablen ist für niemanden ein Aufwand, selbst
> Anfänger lernen das ohne Probleme.
>
>
> Peter
>
Das ist jetzt einfach mal kopiert :

" Also mal gerechnet, bei einem 8 Bit Timer, 1MHz clk und clk/1024
Prescaler kommt man auf einem Timer Overflow Interrupt alle 0,262144
Sekunden. "

So nun meine Überlegungen.
Wie H.Lux bzw. Fuchs erkannt hat, kann ich nur Assembler.

Acht Stunden gleich 8 x 3600 Sekunden => 28800 Sekunden.

28800 Sekunden geteilt durch 0,262144 Sekunden gleich
109863,28125 Interuppts.

Mit einem Byte kann ich bis 256 zählen.
Mit zweien bis 256 x 256 = 65536.
Mit dreien 256 x 256 x 256 = 16777216.
Ok, ich brauche also drei Arbeitsregister ( GPR ) oder halt drei Bytes.

Die ersten beiden Bytes initialisiere ich mit Null und das dritte Byte 
mit 2 und lass das ganze innerhalb der Timerinterupptseviceroutine 
abwärts bis auf Null zählen. Komme dann auf 34360 Sekunden, das sind 
dann ungefähr 9,5h aber das ist auch egal.

Aber ehrlich gesagt denke ich das es doch genauer geht. Muß dann aber 
wohl eher irgendwie mit einer drei Byte Variablen arbeiten - denke ich.

Bernd_Stein

von spess53 (Gast)


Lesenswert?

Hi

Hast du mit dem Timer1 etwas besonderes vor? Wenn nicht, nimm den. Im 
Gegensatz zu anderen AVRs hat der einen maximalen Prescaler von 16384. 
Damit kommst du bei 1MHz auf über 1000s für einen Overflow. Dann reicht 
dir ein Byte.

MfG Spess

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

spess53 schrieb:
> Hi
>
> Hast du mit dem Timer1 etwas besonderes vor? Wenn nicht, nimm den. Im
> Gegensatz zu anderen AVRs hat der einen maximalen Prescaler von 16384.
> Damit kommst du bei 1MHz auf über 1000s für einen Overflow. Dann reicht
> dir ein Byte.
>
> MfG Spess
>
Danke,

das wird wohl das " Besondere " werden, da es so auf jeden Fall 
einfacher wird.

Bernd_Stein

von Thomas E. (thomase)


Lesenswert?

spess53 schrieb:
> Damit kommst du bei 1MHz auf über 1000s für einen Overflow.
Das ist aber nur ein 8-Bit Timer. Also ~4s.

mfg.

von spess53 (Gast)


Lesenswert?

HI

>Das ist aber nur ein 8-Bit Timer. Also ~4s.

Stimmt. Man sollte halt nicht der Gewohnheit folgen.

MfG Spess

von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> Wie H.Lux bzw. Fuchs erkannt hat,

Ich weiß nicht, wo Du den Fuchs hernimmst, aber egal...

> kann ich nur Assembler.

Naja, du kennst die Befehlsliste, also das Alphabet.
Schau Dir mal die Befehle ADD und ADC, sowie SUB und SBC an. Und dann 
überleg' mal, was hier passiert:

 clr r0
 ldi r16,1
;---
 add r17,r16
 adc r18,r0
 adc r19,r0

Oder:

 clr r0
 ldi r16,1
;---
 sub r17,r16
 sbc r18,r0
 sbc r19,r0
 brne weiter
 rjmp bingo
weiter:

Oder Du machst es wie bei der Uhr, zählst Sekunden, Minuten, Stunden, 
Tage, Monate, usw. in separaten Byte-Variablen herunter/herauf und 
vergleichst sie mit der vereinbarten Zeit. Die nächste Übung wird dann 
sein, die laufende Zeit anzuzeigen und die gewünschte Dauer einstellbar 
zu machen. Solte incl. LCD-Routinen alles in den Tiny26 reinpassen, in 
den Tiny2313 passt es jedenfalls.

...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

>>...
>> Bernd Stein schrieb:
>>
>>Ich kann nur Assembler.
>
>Hannes Lux schrieb:
>
> Naja, du kennst die Befehlsliste, also das Alphabet.
>
Du hast es mal wieder erkannt, deshalb das schlaue, listige Fabeltier 
das sich auf deinen Namen reimt :-))
>
> Schau Dir mal die Befehle ADD und ADC, sowie SUB und SBC an. Und dann
> überleg' mal, was hier passiert:
>
>  clr r0
>  ldi r16,1
> ;---
>  add r17,r16
>  adc r18,r0
>  adc r19,r0
>
Da hast Du wieder mal ins schwarze getroffen => Carry-Flag - Wie war das 
nochmal genau - Überlauf, Unterlauf ?

Nee richtiger Weise Übertrag bzw. borgen.

Alsoooo, Der Inhalt von r17 wird um eins erhöht bzw. zum Inhalt von r17 
wird eins hinzu addiert. Wenn der Wertebereich ( 255 ) überschritten ist 
wird das Zero-Flag und das Carry-Flag gesetzt und der Inhalt von r17 ist 
Null.
Nun wird der Inhalt von r18 um eins erhöht bzw. zum Inhalt von r18 wird 
das Carry-Flag hinzu addiert. Jedesmal wenn der Wertebereich von r17 
überschritten ist, wird zum Inhalt von r18 das Carry-Flag bzw. eins 
hinzu addiert.
Wenn der Wertebereich von r18 überschritten ist, wird dessen Inhalt 
selbst Null und zum Inhalt von r19 das Carry-Flag bzw. eins hinzu 
addiert usw. usw.
>
> Oder:
>
>  clr r0
>  ldi r16,1
> ;---
>  sub r17,r16
>  sbc r18,r0
>  sbc r19,r0
>  brne weiter
>  rjmp bingo
> weiter:
>
Wie oben, jedoch das Carry-Flag wird abgezogen bzw. eins wird 
subtrahiert.

Wenn ich nun r17 und r18 auf 255 setze und r19 auf 2 dann habe ich 
ungefähr meine 9,5h bei dem 1Mhz Takt.

Damit hast Du mich jetzt ungefähr zwei Stunden beschäftigt ;-)

Aber wie komme ich nun genauer an die acht Stunden heran ?

Bernd_Stein

von Karl H. (kbuchegg)


Lesenswert?

Bernd Stein schrieb:


> Wenn ich nun r17 und r18 auf 255 setze und r19 auf 2 dann habe ich
> ungefähr meine 9,5h bei dem 1Mhz Takt.
>
> Damit hast Du mich jetzt ungefähr zwei Stunden beschäftigt ;-)
>
> Aber wie komme ich nun genauer an die acht Stunden heran ?

Wer sagt dann, dss dein Countdown bei

 > r17 und r18 auf 255 setze und r19 auf 2

starten muss?

Richtig niemand. Insbesondere muss nicht r18 bei 255 starten und auch 
r17 nicht.

Schreib deine benötigte Anzahl an Interrupts als Hex.Zahl auf

109863  = hex 1AD27

und du hast den Wert, von dem du loszählen musst um die 8 Stunden zu 
ereichen.
In R17 kommt 27
In R18 kommt AD
und in R19 kommt 1

und wenn du von dieser 3Byte Zahl alle 0,262144 Sekunden im Interupt 1 
abziehst, denn nichts anders macht diese Sequenz
  subi r17,1
  sbci r18,0
  sbci r19,0
dann dauert es 8 Stunden, bis 0 erreicht wird.

Und da die Leute bei Atmel die Behandlung des Zero Flags beim SBCI 
vernünftig gemacht haben, ist der Test auf 0 ein einfacher BREQ (oder 
BRNE je nachdem wie es dann weiter gehen soll)

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Karl Heinz Buchegger schrieb:
>
> Schreib deine benötigte Anzahl an Interrupts als Hex.Zahl auf
>
> 109863  = hex 1AD27
>
> und du hast den Wert, von dem du loszählen musst um die 8 Stunden zu
> ereichen.
> In R17 kommt 27
> In R18 kommt AD
> und in R19 kommt 1
>
Ah, das ist der Trick !!!
>
> und wenn du von dieser 3Byte Zahl alle 0,262144 Sekunden im Interupt 1
> abziehst, denn nichts anders macht diese Sequenz
>   subi r17,1
>   sbci r18,0
>   sbci r19,0
> dann dauert es 8 Stunden, bis 0 erreicht wird.
>
Hm, genau wie oben funktiontiert es doch wohl nicht - oder ?

Ich meine, wenn r17 beim ersten mal mit $27 startet und dann von
$00 auf $FF springt, wird r18 um eins verringert.
Alle weitere male muß doch r17 immer seinen kompletten Wertebereich
( $00 bis $FF ) durchlaufen, um r18 um eins zu verringern.

Zum anderen, wenn r18 von $AD beginnend auf $FF gezählt hat, wird doch 
das Carry-Flag gesetz und somit r19 sofort mit um eins verringert.

Sehe ich da was falsch, oder ist das unerheblich ?

Bernd_Stein

von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> Alle weitere male muß doch r17 immer seinen kompletten Wertebereich
> ( $00 bis $FF ) durchlaufen, um r18 um eins zu verringern.

Wenn Du (dezimal) von 125 in Einerschritten herunterzählst, dann werden 
die Einer doch (außer in der ersten Runde) auch im vollen Wertebereich 
(0..9) heruntergezählt, oder?

Betrachte die Register doch einfach mal als 3 Stellen einer Zahl, von 
denen jede den Wertebereich 0..255 hat. Ansonsten ist alles genauso wie 
dezimal, binär oder hex, nur der Wertebereich einer Stelle ist halt 
anders.

...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hannes Lux schrieb:
> Bernd Stein schrieb:
>> Alle weitere male muß doch r17 immer seinen kompletten Wertebereich
>> ( $00 bis $FF ) durchlaufen, um r18 um eins zu verringern.
>
> Wenn Du (dezimal) von 125 in Einerschritten herunterzählst, dann werden
> die Einer doch (außer in der ersten Runde) auch im vollen Wertebereich
> (0..9) heruntergezählt, oder?
>
> Betrachte die Register doch einfach mal als 3 Stellen einer Zahl, von
> denen jede den Wertebereich 0..255 hat. Ansonsten ist alles genauso wie
> dezimal, binär oder hex, nur der Wertebereich einer Stelle ist halt
> anders.
>
Ich denke jetzt hast Du es geschafft, das meine Rädchen im Gehirn 
richtig laufen.

109863 Interuppts  =>  1AD27 Hex

       ...
       ldi r17,$27 ;Drei Byte Zähler...
       ldi r18,$AD ;...mit Startwert...
       ldi r19,$01 ;...initialisieren
       ...
*******************************************************
* Timer-Interuppt-Service-Routine
*******************************************************
       ...
       subi r17,1  ;Drei Byte Zähler...
       sbci r18,0  ;...in einer Schritten...
       sbci r19,0  ;...herunter zählen.
       brcs bingo  ;Wenn das Carry-Flag gesetzt ist fertig...
       reti        ;...ansonsten Rücksprung aus der ISR
bingo: ...         ;!!! Die 8 Std. sind abgelaufen !!!
       reti        ;Rücksprung aus der ISR


Bernd_Stein

von Karl H. (kbuchegg)


Lesenswert?

Bernd Stein schrieb:


>        subi r17,1  ;Drei Byte Zähler...
>        sbci r18,0  ;...in einer Schritten...
>        sbci r19,0  ;...herunter zählen.
>        brcs bingo  ;Wenn das Carry-Flag gesetzt ist fertig...

Nimm das Zero-Flag.
Dann sagst du expliziter: Wenn 0

Und mach es dir zur Gewohnheit in einer ISR das Status-Register SREG zu 
sichern. Immer? Immer!
Denn eines Tages machst du im Hauptprogramm eine Erweiterung und dann 
spuckt dir das nicht gesicherte SREG in der ISR in die Suppe.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Bernd Stein schrieb:
>
>
>>        subi r17,1  ;Drei Byte Zähler...
>>        sbci r18,0  ;...in einer Schritten...
>>        sbci r19,0  ;...herunter zählen.
>>        brcs bingo  ;Wenn das Carry-Flag gesetzt ist fertig...
>
> Nimm das Zero-Flag.
> Dann sagst du expliziter: Wenn 0
>
Ich denke immer noch das Zeitgleich mit dem Sprung von r18 von $AD
über $00 auf $FF das Carry-Flag gesetzt wird und somit r19 sofort
mit um eins dekrementiert wird und somit zeitgleich Null ist.
Aber r17 und r18 müssen doch noch einmal komplett durchlaufen,
um r19 = 1 zu realisieren - oder ?
>
> Und mach es dir zur Gewohnheit in einer ISR das Status-Register SREG zu
> sichern. Immer? Immer!
> Denn eines Tages machst du im Hauptprogramm eine Erweiterung und dann
> spuckt dir das nicht gesicherte SREG in der ISR in die Suppe.
>
Ja, danke an die Erinnerung. Dies sind schwer zu findene Fehler.

Bernd_Stein

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn die XTAL Pins (PB4 und PB5)  noch frei sind, kannst du den Tiny 
auch mit einem Uhrenquarz ( 32,768 Khz ) oder was ähnlichem takten. Das 
hat den Vorteil, das es sehr genau ist und auch noch Energie spart.

von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> Ich denke jetzt hast Du es geschafft, das meine Rädchen im Gehirn
> richtig laufen.

Naja, Du denkst oftmals zu kompliziert und stehst Dir dabei selbst im 
Wege. Ist zumindest meine Einschätzung aus Deinen anderen Threads. Aber 
es freut mich, wenn ich hin und wieder mal einen der Knoten in Deinen 
Gedanken lösen kann.

Übrigens: Was machen die beiden 18650-Lader? Laufen sie schon?

...

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hannes Lux schrieb:
> Bernd Stein schrieb:
>> Ich denke jetzt hast Du es geschafft, das meine Rädchen im Gehirn
>> richtig laufen.
>
> Naja, Du denkst oftmals zu kompliziert und stehst Dir dabei selbst im
> Wege. Ist zumindest meine Einschätzung aus Deinen anderen Threads. Aber
> es freut mich, wenn ich hin und wieder mal einen der Knoten in Deinen
> Gedanken lösen kann.
>
Der KHB ( Moderator ), verunsichert mich noch ein wenig.
Weiß jetzt immer noch nicht, ob das Zero-Flag oder das Carry-Flag nun 
das richtige ist. Und wenn es das Zero-Flag ist, verstehe ich es nicht.
>
> Übrigens: Was machen die beiden 18650-Lader? Laufen sie schon?
>
Wo denkst Du hin ? Überleg mal wie lange ich nun an diesem acht Stunden 
Softwarezähler dran bin und immer noch nicht ganz durchblicke.
Für heute genug mit diesem Thema.

Bernd_Stein

von Karl H. (kbuchegg)


Lesenswert?

Bernd Stein schrieb:

> Der KHB ( Moderator ), verunsichert mich noch ein wenig.
> Weiß jetzt immer noch nicht, ob das Zero-Flag oder das Carry-Flag nun
> das richtige ist. Und wenn es das Zero-Flag ist, verstehe ich es nicht.

Du willst doch eine Zahl runterzählen bis sie 0 ist, oder nicht?

Dann teste auch, ob das Ergebnis nachdem du 1 abgezogen hast, 0 ist!
Ist doch ganz einfach.
Du stehst dir wirklich selber im Weg.

Mit dem Carry würdest du testen, ob du einen Unterlauf hattest, salopp 
gesprocjen ob du -1 erreicht hast. Gut, ist jetzt beo 0.2 Sekunden nicht 
die Welt, aber wenn du Goldbarren zählen sollst, macht es einen 
Unterschied ob deine SChaltung 20 oder 21 Goldbarren auf den Laster 
laden lässt, wenn der Kunde 20 gekauft hat.

von Karl H. (kbuchegg)


Lesenswert?

> Ich denke immer noch das Zeitgleich mit dem Sprung von r18
> von $AD über $00 auf $FF das Carry-Flag gesetzt wird

soweit richtig

> und somit r19 sofort
> mit um eins dekrementiert wird

auch das ist richtig

> und somit zeitgleich Null ist.
auch das ist richtig

Aber: deswegen ist das Zero Flag nicht gesetzt worden!


Schau dir die Befehlssatzbeschreibung an. Die Atmel Ingenieure haben 
schon mitgedacht und dem SBCI Befehl eine Spezialbehandlung des Zero und 
des Carry Flags mitgegeben, die es leicht macht viele derartige Befehl 
zu einer n-Byte Arithmetik zu kaskadieren und trotzdem ist hinten nach 
das Zero Flag nur dann gesetzt, wenn ALLE beteiligten Register (bei dir 
R17, R18 und R19) den Wert 0 aufweisen.



       subi r17,1  ;Drei Byte Zähler...
       sbci r18,0  ;...in einer Schritten...
       sbci r19,0  ;...herunter zählen.
       breq bingo  ; Auf 0 heruntergezählt? -> bingo


Der breq wird genommen, wenn sowohl R17, als auch R18, als auch R19 0 
sind! Die ganze Kette, bestehend aus dem ersten SUB und nachfolgenden 
SBC muss überall 0 ergeben. Nur dann ist danach das Zero-Flag gesetzt.

von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> Weiß jetzt immer noch nicht, ob das Zero-Flag oder das Carry-Flag nun
> das richtige ist.

Das Zero-Flag sagt Dir, dass bei dieser Kombi-Operation (über mehrere 
Register mit "Flagmitnahme" der Voroperationen) Null ereicht wurde.

Das Carry-Flag signalisiert Unterlauf (bzw. Überlauf bei Addition).

Die Kombi-Operation (mir fällt momentan kein besserer Name ein) über 
mehrere Register (erste Operation normal, weitere Operationen mit 
Flagmitnahme, durch "c" am Ende erkennbar) nehmen nicht nur das 
Carry-Flag mit. Schau doch einfac mal in die Hilfe des AVR-Studios zu 
den jeweiligen Befehlen, da steht für jedes beeinflusste Flag die Formel 
der Beeinflussung drin.

...

von Hannes L. (hannes)


Lesenswert?

Karl-Heinz hat's besser beschrieben, danke...

...

von Karl H. (kbuchegg)


Lesenswert?

Dafür hast du ihm vor 23 Stunden schon die Lösung gegeben und den Rat, 
sich doch bitte die Befehle in der Befehlsliste durchzusehen. Du hast 
das ja nicht aus Jux und Tollerei gemacht.
Beitrag "Re: ATtiny26 Wie Systemtakt weiter herunterteilen ?"

@Bernd
Du musst viel sorgfältiger arbeiten wenn du lernen willt. Hannes hat 
nicht umsonst gesagt, du musst bei deiner Analyse seines Codestückes dir 
unbedingt die 4 von ihm angegebenen Befehle ansehen. Dazu gehört auch, 
dass man studiert, wie jeder Befehl die Flags beeinflusst. beachten von 
Details ist in jeder Programmiersprache wichtig. Aber nirgends sind die 
kleinen Details so wichtig wie in Assembler.

von Hannes L. (hannes)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Du hast
> das ja nicht aus Jux und Tollerei gemacht.

Nein, einige seiner Missverständnisse (nicht nur in diesem Thread) hatte 
ich vor einiger Zeit selbst (bin ja auch kein studierter Informatiker 
oder E-Techniker), hatte aber Niemanden, den ich fragen konnte und 
musste sie daher selbst lösen. Das hat mich aber nicht dümmer gemacht. 
Auch deshalb beschränkt sich meine Hilfe meist auch auf Hilfe zur 
Selbsthilfe. Ich gebe gern einen Tip, wo es weitere Infos gibt, löse 
auch gern mal einen Knoten im Kopf (Missverständnis beseitigen), aber 
das komplette Projekt werde ich nicht erstellen. Auch einen kompletten 
Lehrgang in AVR-ASM kann und will ich nicht halten.

...

von Karl H. (kbuchegg)


Lesenswert?

Hannes Lux schrieb:
> Karl Heinz Buchegger schrieb:
>> Du hast
>> das ja nicht aus Jux und Tollerei gemacht.
>
> Nein, einige seiner Missverständnisse (nicht nur in diesem Thread) hatte
> ich vor einiger Zeit selbst (bin ja auch kein studierter Informatiker
> oder E-Techniker), hatte aber Niemanden, den ich fragen konnte und
> musste sie daher selbst lösen.

Muss zugeben: Ich musste auch mit der Nase drauf gestossen werden. Zu 
meiner Rechtfertigung kann ich nur vorbringen, dass eine derartige Flag 
Behandlung vor 30 Jahren auf den mir zugänglichen Prozessoren nicht 
üblich war und ich daher von da verdorben war :-)

Hilft aber nix: Er programmiert AVR und er programmiert Assembler. Neben 
dem Datenblatt ist die Instruction Set Beschreibung die 2.te Bibel deren 
Studium (und bei dem dann jeder Satz, jedes Wort) unabdingbar ist. Mit 
heutigen IDE ist das ohnehin leicht. Beim Z80 hatten wir (Kumpel und 
ich) einen Rodney Zacks und sonst nichts. Gar nichts. Dementsprechend 
abgegriffen und zerfleddert war der auch nach einem halben Jahr.



Aber warten wir jetzt erst mal ab, ob wenigstens dieses 'Projekt' in 
absehbarer Zeit fertig wird.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Beim Z80 hatten wir (Kumpel und
> ich) einen Rodney Zacks und sonst nichts.

Dafür war der Zaks aber einfach ein Hammer und hat dem Z80 wirklich die 
Hosen komplett ausgezogen. Der Zacks und das Intel Mikrocontroller 
Handbook sind die zerfleddertsten Bücher hier im Schrank.

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Dafür hast du ihm vor 23 Stunden schon die Lösung gegeben und den Rat,
> sich doch bitte die Befehle in der Befehlsliste durchzusehen. Du hast
> das ja nicht aus Jux und Tollerei gemacht.
> Beitrag "Re: ATtiny26 Wie Systemtakt weiter herunterteilen ?"
>
> @Bernd
> Du musst viel sorgfältiger arbeiten wenn du lernen willt. Hannes hat
> nicht umsonst gesagt, du musst bei deiner Analyse seines Codestückes dir
> unbedingt die 4 von ihm angegebenen Befehle ansehen. Dazu gehört auch,
> dass man studiert, wie jeder Befehl die Flags beeinflusst. beachten von
> Details ist in jeder Programmiersprache wichtig. Aber nirgends sind die
> kleinen Details so wichtig wie in Assembler.
>
Nun ja,
ich komme von der Motorola-Schiene bzw. kannte vorher nur den MC68HC11.
Und diesen auch nicht besonders gut. Das heißt mit ihm habe ich damals 
in den 90iger Jahren angefangen mich mit Mikrocontrollern zu befassen.

Bis heute war also für mich klar, das das Zero-Flag nur gesetzt wird, 
wenn ein das Z-Flag beeinflussender Befehl als Ergebnis Null hatte.
Habe also geguckt ob evtl. einer der von Hannes genannten Befehle
ADD, ADC bzw. SUB, SBC gar nicht das Carry,- oder Zero-Flag beeinflusst.

Da Ihr mich aber darauf aufmerksam gemacht habt, das es so etwas wie
" Flagmitnahme " der Voroperationen gibt, habe ich bei SBC bzw. SBCI
das Z am Ende der Formel     Z:   /R7•/R6•/R5•/R4•/R3•/R2•/R1•/R0•Z
gesehen.
Der Text allein  würde mir nicht weiter helfen.
Ohne Euch und die Formel hätte ich das nicht verstanden das damit so 
etwas wie eine " Flagmitnahme " gemeint ist.

" Previous value remains unchanged when the result is zero; cleared 
otherwise "

Würde das nämlich so übersetzen :

" Der vorherige Wert bleibt unverändert, falls das Ergebnis Null ist.
Ansonsten wird er gelöscht. "

Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Ich denke immer noch das Zeitgleich mit dem Sprung von r18
>> von $AD über $00 auf $FF das Carry-Flag gesetzt wird
>
> soweit richtig
>
>> und somit r19 sofort
>> mit um eins dekrementiert wird
>
> auch das ist richtig
>
>> und somit zeitgleich Null ist.
> auch das ist richtig
>
> Aber: deswegen ist das Zero Flag nicht gesetzt worden!
>
Da ich ja in die Mikrocontrollermaterie mit dem MC68HC11 vor gut zwei 
Jahrzehnten eingestiegen war, kam ich nicht auf die Idee,
das das setzen des Zero-Flags etwas anderes bedeuten könnte,
als das ein das Z-Flag beeinflussender Befehl als Ergebnis Null hat.

Etwas wie eine " Flagmitnahme der Voroperationen ",
wäre mir nie in den Sinn gekommen.

Habe mir statt dessen die folgenden Befehle so erklärt :

r18 wird ja nicht nur von #$AD bis #$00 herunter gezählt,
sondern einmal mehr.
Da das Carry-Flag ja erst beim Sprung von #$00 auf #$FF gesetzt wird.
Somit könnte ich mir ja r19 sparen, da es ja Zeitgleich mit dem Sprung 
von r18 von #$00 auf #$FF um eins dekrementiert wird und somit Null 
wird.

Mir ist klar das es so nicht funktioniert, da es ja beim Befehl SBCI so 
etwas wie eine " Flagmitnahme der Voroperationen " gibt.

       ...
       ldi r17,$27 ;Drei Byte Zähler...
       ldi r18,$AD ;...mit Startwert...
       ldi r19,$01 ;...initialisieren
       ...

*******************************************************
* Timer-Interuppt-Service-Routine
*******************************************************
       ...
       subi r17,1  ;Drei Byte Zähler in einer Schritten...
       sbci r18,0  ;...herunter zählen...
       brcs bingo  ;Wenn das Carry-Flag gesetzt ist fertig...
       reti        ;...ansonsten Rücksprung aus der ISR
bingo: ...         ;!!! Die 8 Std. sind abgelaufen !!!
       reti        ;Rücksprung aus der ISR

Bernd_Stein

von Hannes L. (hannes)


Lesenswert?

Bernd Stein schrieb:
> reti        ;...ansonsten Rücksprung aus der ISR
> bingo: ...  ;!!! Die 8 Std. sind abgelaufen !!!
> reti        ;Rücksprung aus der ISR

Hmmm, wenn man noch nicht sattelfest ist, sollte man ein paar Regeln 
beachten.

ISRs und Unterprogramme haben nur einen einzigen Rücksprung. Wenn dabei 
bedingt unterschiedlicher Code ausgeführt wird, springen alle Codestücke 
nach getaner Arbeit zu einem Label am Ende der Routine. Es gibt also in 
der ISR nur 1 RETI (im Unterprogramm nur 1 RET).

Warum??
In Unterprogrammen und ISRs braucht man öfters mal Register, die auch im 
Hauptprogramm benutzt werden und deren Inhalt nicht verlorengehen 
sollte. Diese sichert man mit PUSH auf Stack und stellt sie mit POP 
wieder her. Damit der Stackpointer nicht Amok läuft, müssen sich PUSHs 
und POPs aufheben. Dies ist nur bei definiertem Einsiegspunkt und (einem 
einzigen) definiertem Ausstiegspunkt (RET/RETI) möglich, ohne dass man 
(als Einsteiger) die Übersicht verliert und sich verheddert.

Bei ISRs kommt noch hinzu, dass man unbedingt das SREG sichern (und 
wiederherstellen) muss, wenn in der ISR Flags verändert werden (also 
praktisch fast immer) und im Hauptprogramm oder irgendeinem 
Unterprogramm davon mit Flags des SREG gearbeitet wird (also auch fast 
immer). Ansonsten ballert Dir der Interrupt irgendwann zwischen 
Flagbeeinflussung und Flagauswertung der Mainloop/Unterprogramm 
dazwischen und verändert Dir die Flags unterm Hintern, wodurch die 
Auswertung dann in die Hose geht. Das sind Fehler, die nur sporadisch 
auftreten und nach denen Du Dir dann den Wolf suchst. Hier ist also 
strenge Disziplin angesagt.

Zur Motorola-Erfahrung sage ich erstmal nix, da fehlt mir die Kompetenz.

...

von Peter D. (peda)


Lesenswert?

Letztendlich ist es wurscht, ob Du von n .. 0 zählst oder von n-1 .. -1.

Beim 8051 konnte man auch den Befehl DJNZ kaskadiert aufrufen.
Allerdings ist dann die Berechnung des Startwertes etwas komplexer, ließ 
sich aber bequem in ein Macro packen:
1
mdelay  macro value, rx, ry  ;cycle, used registers (r0..r7 allowed)
2
    if( value < 5 )
3
            if( value > 3 )
4
              nop
5
            endif
6
      if( value > 2 )
7
              nop
8
            endif
9
      if( value > 1 )
10
              nop
11
            endif
12
      if( value > 0 )
13
              nop
14
            endif
15
    else
16
            if( value < 515 )
17
        mov rx, #low((value-1)/2)
18
        djnz rx, $
19
        if((value and 1) = 0)
20
          nop
21
        endif
22
      else
23
        mov rx, #high(value/2+253)
24
        mov ry, #low(value/2-2)
25
        djnz ry, $
26
        djnz rx, $ - 2
27
        if(value and 1)
28
                nop
29
              endif
30
            endif
31
    endif
32
  endm
33
34
35
mdelay 0, r0, r1
36
37
mdelay 1, r0, r1
38
39
mdelay 2, r0, r1
40
41
mdelay 3, r0, r1
42
43
mdelay 4, r0, r1
44
45
mdelay 5, r0, r1
46
47
mdelay 6, r0, r1
48
49
mdelay 100, r0, r1
50
51
mdelay 10000, r0, r1
52
53
mdelay 65535, r6, r7
54
55
end


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.