Forum: Mikrocontroller und Digitale Elektronik CARRY schnell invertieren Assembler ATmega8 ?


von Bernhard S. (bernhard)


Lesenswert?

Wie kann man schnell Carry invertieren ?

Eine Möglichkeit wäre ein Sprungbefehl z.B:

brcc... und dann SEC
brcs... und dann CLC

Bernhard

von c-hater (Gast)


Lesenswert?

Bernhard S. schrieb:

> Wie kann man schnell Carry invertieren ?

Leider garnicht.

Aaaber: Laß mal was über den Kontext des Problems hören. Oft scheint es 
nur im ersten Anlauf so, als wenn man unbedingt an den Flags direkt 
rummachen müßte. Da bin ich auch schon mehrmals drauf reingefallen und 
habe erst im zweiten oder dritten Anlauf eine Lösung gefunden, mit der 
sich dann nachweislich herausgestellt hat, dass das auch eigentlich 
garnicht nötig war.

von Bernhard S. (bernhard)


Lesenswert?

>Laß mal was über den Kontext des Problems hören.


Es handelt sich um dieses Projekt, ich "fummle" es gerade von einem 
16MHz auf einen 8MHz Takt um, alles ist sehr zeitkritisch:

https://www.mikrocontroller.net/topic/241934


Eine Funktion liest mir ein entsprechendes BIT aus dem SRAM aus,

der Rückgabewert ist Carry,

welches später MATCH-ROM oder SEARCH-ROM oder Scratchpad read 
ermöglicht.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Und warum musst du es bitweise umdrehen? Nach 8 Bits ist einfacher.

von Bernhard S. (bernhard)


Lesenswert?

>Und warum musst du es bitweise umdrehen? Nach 8 Bits ist einfacher.


So einfach ist das nicht:


Weil der MASTER vom 1WIRE Datenbus mur einzelne Bits sendet bzw. 
empfängt,

speziell im Search-Modus,

2 Bits empfangen, danach ein Bit senden und das ganze 64 Mal.

von (prx) A. K. (prx)


Lesenswert?

Ja und? Ob du die Adresse als Original oder dessen Komplement 
verarbeitest ist doch vom 1-Wire Verfahren her schnurz.

Ansonsten zeig mal deinen Code. Den Asm. In dem Links steht zwar Asm 
im Titel aber in den Beträgen finde ich ulkigerweise bloss Basic-Files.

: Bearbeitet durch User
von avr (Gast)


Lesenswert?

Was mir jetzt auf die schnelle einfällt wäre folgendes:
1
ror temp        ; Inhalt egal
2
subi temp, 0x80

Schneller wird es wahrscheinlich nicht gehen.

von (prx) A. K. (prx)


Lesenswert?

Bernhard S. schrieb:
> 2 Bits empfangen, danach ein Bit senden und das ganze 64 Mal.

Bei 1-Wire??? Dann verstehst du unter einem Bit nicht das, was ich 
darunter verstehe.

von H.Joachim S. (crazyhorse)


Lesenswert?

Bernhard S. schrieb:
> ich "fummle" es gerade von einem
> 16MHz auf einen 8MHz Takt um

Warum?

von Einer (Gast)


Lesenswert?

Ich zweifle auch sehr stark am Ansatz.
Trotzdem ... Carry ist ein Bit im status register

invert carry =>  SREG = SREG XOR 0x01

von Bernhard S. (bernhard)


Lesenswert?

> Was mir jetzt auf die schnelle einfällt wäre folgendes:

> ror temp        ; Inhalt egal
> subi temp, 0x80


Dankeschöööön  !!!!

Es funktioniert, ich bin maximal begeistert ^^





>Ansonsten zeig mal deinen Code. Den Asm. In dem Links steht zwar Asm
>im Titel aber in den Beträgen finde ich ulkigerweise bloss Basic-Files.

Im oberen, findest Du z.B. meinen 16MHz-Assembler-Code, für die anderen 
Basic-Files fühle ich mich nicht verantwortlich.


>> ich "fummle" es gerade von einem
>> 16MHz auf einen 8MHz Takt um
> Warum?

Stromspargründe, seine Versorgungsspannung soll über den Datenbus zur 
Verfügung gestellt werden.



>Bei 1-Wire??? Dann verstehst du unter einem Bit nicht das, was ich
>darunter verstehe.

Ich gehe davon aus, dass Du Dich etwas tiefgründiger mit OW beschäftigt 
hast?

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Bernhard S. schrieb:
> Ich gehe davon aus, dass Du Dich etwas tiefgründiger mit OW beschäftigt
> hast?

Ja.

von Bernhard S. (bernhard)


Lesenswert?

>> Ich gehe davon aus, dass Du Dich etwas tiefgründiger mit OW beschäftigt
>> hast?

>Ja.


Wie würdest Du ROM-SEARCH im SLAVE (ATmega + Assembler) realisieren?

: Bearbeitet durch User
von Bernhard S. (bernhard)


Lesenswert?

Wie könnte man so schnell wie möglich feststellen, ob BIT6 und BIT7 in 
einem Register (R16) gleich sind?


Variante:

cpi temp,0b00000000
breq OK
cpi temp,0b11000000
breq OK

von (prx) A. K. (prx)


Lesenswert?

Was c-hater oben schon angesprochen hat: einen völlig anderen Ansatz 
wählen. Es gibt ja nicht viele Möglichkeiten, was im zeitkritischen Teil 
der ISR zu tun wäre. Nämlich (1) den Pin auf out oder auf in setzen und 
sich (2) zum Sample-Punkt den Zustand merken. Die einzige Unbekannte 
darin ist in (1), und das kann man vorbereiten.

Ob im nächsten 1-Wire Zyklus der Zustand nur gelesen werden soll, der 
Zyklus komplett ignorieren werden soll oder eine 1 geschrieben werden 
soll ist der exakt gleiche Ablauf auf dem Bus und muss sich folglich im 
kritischen Teil der ISR nicht unterscheiden.

Wenn also vor dem Aufruf der ISR bereits in einem Register drinsteht, 
was darin sofort ins DDR geschrieben werden muss, dann hat man 
anschliessend in der Delay-Phase genug Zeit, den nächsten Zustand dieses 
Registers vorzubereiten. Sich den Zustand des Pins auch dann zu merken, 
wenn man ihn grad nicht braucht, stört dabei auch nicht.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Weitere erhebliche Zeitersparnis: Da ausser dem Pin-Interrupt sonst 
keiner verwendet wird kann die ISR an der Stelle des Vektors anfangen. 
Ein dortiger Sprung ist dann unnötig.

von avr (Gast)


Lesenswert?

Bernhard S. schrieb:
> Wie könnte man so schnell wie möglich feststellen, ob BIT6 und
> BIT7 in
> einem Register (R16) gleich sind?
1
lsl temp
2
brvc OK

von Bernhard S. (bernhard)


Lesenswert?

> lsl temp
> brvc OK

Es funktioniert... ich bin maximal hochgradig begeistert !!!

Danke

>Weitere erhebliche Zeitersparnis: Da ausser dem Pin-Interrupt sonst
>keiner verwendet wird

Gute Idee !

Es wird z.B. noch ein TIMER-INTERRUPT genutzt für eine interne UHR für 
einen DCF-Empfänger (SAMPLING-Verfahren), ein ext. Interrupt für Impulse 
eines Regenmessers auswerten usw.



>Was c-hater oben schon angesprochen hat: einen völlig anderen Ansatz
>wählen. Es gibt ja nicht viele Möglichkeiten, was im zeitkritischen Teil
>der ISR zu tun wäre....


Danke für die Tipps.

So einfach ist das alles nicht, zumal der MASTER sehr schnell 
hintereinander die Bits abrufen kann.

Ich muss alles in die ISR reinpacken, arbeite schon mit verschachtelten 
Interrupts, nebenbei sollen noch TWI-Sensoren HYT939 bzw. HH10D mit 
Frequenzmessung realisiert werden, oder andere Aufgaben, die mehrere 
100ms Zeit in Anpruch nehmen.

Ziel ist es, einen SLAVE zu konzipieren incl. SLEEP, der mit wenig Strom 
auskommt, momentan bin ich bei 8MHz, von einer 1MHz Variante musste ich 
mich schnell trennen, da ein 0-SLOT nur unsauber generiert werden kann.

Allein die Einsprung-Takte in die ISR dauern für diese Anwendung bei 
1MHz zu lange.

Wenn die 8-MHz Version optimiert ist versuche ich mich an die 4-MHz 
Variante heranzutasten.

Momentan nutze ich dieses TOOL:
Beitrag "TWI I2C USART RS232 - 1WIRE INTERFACE bridge device ATmega8 Assembler"


Daher auch dieser Beitrag:
Beitrag "Innenwiderstand Messung Goldcap Supercap 1F 5V"

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Bernhard S. schrieb:
> So einfach ist das alles nicht, zumal der MASTER sehr schnell
> hintereinander die Bits abrufen kann.

Was ich beschrieb sorgt vor allem dafür, den zeitkritischen Teil der ISR 
zu entlasten. Im verlinkten Code hat an genau dieser Stelle die 
zeitraubende Abfrage einer Statemachine drin. Die kann dort weg.

Ebenso wird die temporäre Aktivierung des Ausgangs am Anfang der ISR 
überflüssig, weil mein OUT DDRx,Ry das an genau dieser Stelle schon 
fertig erledigt, und nicht vor vorläufig. Und sogar noch einen Takt 
schneller ist als dein SBI DDRx,y. Mindestens dieser eine Befehl passt 
bestimmt noch in die Vektorleiste rein, da nur der nächste Interrupt 
dran glauben muss.

Der Trick besteht darin, die Entscheidungen und Bitzustände nicht in der 
kritischen Phase durchzuführen, sondern davor. Also effektiv 
nach/während dem vorherigen Bit, dort wo im bisherigen Code Delays 
sitzen. Das kostet nicht mehr als bisher, sondern weniger, zumal ein Bit 
in einem Register zu ändern (dem für den OUT Befehl) billiger ist als 
eines im DDR.

Aber was du sonst grad geschrieben hast, deutet leider an, dass dieser 
gezeigte in diesem Zusammenhang Code nur eine Nebelkerze ist und mit der 
Sache nichts mehr zu tun hat.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Bernhard S. schrieb:
> Allein die Einsprung-Takte in die ISR dauern für diese Anwendung bei
> 1MHz zu lange.

Ja. Ein 1-Wire Slave ist ohne etwas Hardware-Unterstützung eine arg 
knappe Angelegenheit. Wobei man wohl auch mit einem Timer tricksen 
könnte, wenn einer nebst Ausgang frei ist (*). Den würde man für 0-Bits 
vorher so dressieren, dass er bei einlaufender Flanke das 1-Wire Signal 
runterzieht (externer Transistor nötig). Dann ist die Reaktionszeit der 
ISR deutlich entspannter.

*: Möglicherweise ginge auch mit I2C etwas (Idee dahinter: Start 
Condition als 1-Wire Interrupt, mit Ausnutzung vom Clock Stretching), 
oder vielleicht SPI. Halt alles was eine passende Hardware-Reaktion 
auslöst.

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

> Wenn die 8-MHz Version optimiert ist versuche ich mich an die 4-MHz
> Variante heranzutasten.

Strom sparen durch Taktreduktion funktioniert nicht grundsätzlich. So 
ein AVR hat nämlich einen gewissen "Grundverbrauch", der immer ansteht, 
wenn er nicht schläft. Mit weniger Takt ist er aber länger wach. Also 
lieber mit 8MHz zum nächsten SLEEP sprinten, als mit 1MHz dahin trödeln.
ATmega8 5V:
16MHz-> 20mA. -> 0,800mA/MHz ->  32%
8MHz -> 11mA  -> 1,375mA/MHz ->  55%
1MHz -> 2,5mA -> 2,500mA/MHz -> 100%

Von deinen Zeitproblemen mal ganz abgesehen.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Apropos Strom: Der ATmega88PA braucht bei 16MHz nur ca. ein Drittel.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Carl Drexler schrieb:
> 16MHz-> 20mA. -> 0,800mA/MHz ->  32%

?

von Peter D. (peda)


Lesenswert?

Warum muß es unbedingt 1-wire kompatibel sein?
Die Gegenseite programmierst Du doch auch.

Es gibt außerdem deutlich bessere Busse für Busspeisung, z.B.:
https://de.wikipedia.org/wiki/M-Bus_%28Feldbus%29

von c-hater (Gast)


Lesenswert?

Carl D. schrieb:

> Strom sparen durch Taktreduktion funktioniert nicht grundsätzlich.

Doch, natürlich. Der Zusammenhang ist linear und man kann ihn sich in 
jedem AVR-Datenblatt als Diagramm ansehen. Und man erkennt anhand des 
Diagramms sofort, dass die Stromaufnahme bei 0 Hz sehr, sehr nahe bei 0 
liegen muss.

> So
> ein AVR hat nämlich einen gewissen "Grundverbrauch"

Ja, natürlich, durch die unvermeidlichen Leckströme der 
CMOS-Technologie. Aber: er liegt im µA-Bereich.

> der immer ansteht,
> wenn er nicht schläft.

Schlafen ("PowerOff") bedeutet im Wesentlichen einfach nur: Takt=0. Und 
genau deswegen nimmt er dann halt auch nur die o.g. µA auf. Allerdings 
gibt es dabei ein Problem: Wenn der Takt durch den AVR selber erzeugt 
wird und er dabei als Quarz-Oszillator (mit extern angeschlossenem 
Quarz) arbeitet, dann wird natürlich auch der Oszillator beim Sleep 
angehalten. Das ist kein Problem. Ein Problem ist aber, dass durch die 
hohe Güte bedingt, es wirklich lange Zeit dauert, bis der Oszillator 
nach dem Restart wieder hinreichend stabil schwingt zum Betrieb der MCU. 
Und in dieser ganzen Zeit wird zwar schon kräftig Energie verbraucht, 
der Controller kann aber noch nix sinnvolles tun.

Und weil das so ist, ist dein Ansatz zumindest für den Fall des Betriebs 
mit einem Quarz definitiv und leicht nachweisbar eine 
Milchmädchenrechnung.

Deutlich komplizierter ist es für den Betrieb mit einem internen 
RC-Oszillator, da ist das nicht so leicht zu entscheiden. Dafür gibt es 
keine einfache Entscheidungshilfe, in aller Regel sind zum Erreichen des 
Optimums erst lange Messreihen statistisch hinreichend aussagefähig.

Oder anders ausgedrückt: es ist dann fast völlig huppse, ob du kurz 
schnell rechnest oder länger langsamer. Das einzige, was garantiert 
positiv wirkt, ist die Reduktion der insgesamt benötigten Rechenleistung 
pro Zeiteinheit. Sprich: effizienter Code.

von Carl D. (jcw2)


Lesenswert?

Wenn du meinst, dann muß es ja stimmen. Ist ja quasi ein Fakt. Hatten 
wir das nicht vor kurzen schon mal: die einzige Wahrheit.

von Bernhard S. (bernhard)


Lesenswert?

@alle

Ein ganz großes Dankeschön für die sehr hilfreichen Anregungen und 
Tipps.

Die 4MHz 1-WIRE-Version:

Beitrag "1-Wire OW-wire slave device <=4MHz low current AVR assembler ATmega8"


Bernhard

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.