PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Timerablauf/neu ICP1 funktioniert nur einmal



Ceos
19.08.2009, 10:12
!!!!die fortsetzung mit dem neuen problem ist weiter unten!!!

ich verwende in einem meiner programme einen timer um eine mikrosekundengenaue pause einzubauen, dafür hab ich den timer2 eines M32 auf PS 1 und FastPWM gesetzt

in der overflow ISR dekrementier ich ne variable um die überläufe zu zählen, ist der wert dann ebi 0 angelangt, schalte ich den interrupt für das OCR register frei, in dem ich n = rest_µS*16 stehen habe ... ist das compare ereignis eingetreten, ist die pause beendet und der timer wird gestoppt

komisch nur, dass mir scheinbar öfters genau ein timerüberlauf verloren geht! der timer beendet manchmal 16µS zu früh und ich komm auf denn teufel nciht drauf WARUM bitte helft mir



ISR(SIG_OVERFLOW2) // Timer 2
{
if (faktor != 0) faktor--;
cli();
if (faktor == 0){
TIMSK &= ~(1<<TOIE2);
if (TCNT2+10 > OCR2) timeUp2();
else TIMSK |= (1<<OCIE2);
}
sei();
}

ISR(SIG_OUTPUT_COMPARE2)
{
cli();
timeUp2();
sei();
}
ISR(SIG_COMPARATOR)
{
cli();
ACSR &= ~(1<<ACIE); // disable interrupt
STOP;
TCNT2 = 0;
TCCR2 |= (1<<CS20); // enable timer2
TIFR |= (1<<TOV2);
TIMSK |= (1<<TOIE2);
sei();
}
void timeUp2()
{
START;
TIMSK &= ~(1<<OCIE2); // disable timer2 output compare interrupt
TCCR2 &= ~((1<<CS22) | (1<<CS21) | (1<<CS20)); // disable timer2 (clockselect 0)
}

sternst
19.08.2009, 10:38
Als allererstes entfernst du mal sämtliche cli/sei aus den Interrupt-Funktionen, die haben darin nichts verloren (verursachen höchstens Probleme).

Dann hast du einen logischen Fehler:
ist der wert dann ebi 0 angelangt, schalte ich den interrupt für das OCR register frei,Das Interrupt-Flag ist aber längst gesetzt, so dass der Interrupt dann sofort nach dem Ende der Overflow-ISR kommt, und nicht erst beim nächsten Compare-Ereignis. Du musst also auch noch das Flag löschen.

Ceos
19.08.2009, 10:41
stimmt ... ich versuchs mal bis gleich

leider hab ich sehr viele interrupts und die cli() und sei() sind mit bedacht gesetzt und stabilisieren sogar das ergebnis ... ich mag darüber nicht diskutiern sofern es nicht das problem ist, die ergebnisse sprechen bände (ehrlich)

PS: keine änderung leider

Hubert.G
19.08.2009, 11:51
Schau dir in der Simulation mal das SREG an wenn ein ISR ausgelöst wird. Du wirst sehen das das I-Bit sofort auf 0 gesetzt wird. Genau das machst du noch mal mit dem cli().
Was dir passieren kann ist, ein weiterer Interrupt steht an, wird am Ende deiner ISR durch dein sei() freigegeben, diese ISR wird sofort angesprungen ohne die laufende zu beenden. Wozu das führen kann wirst du ja auch bedacht haben.
Ich will dir keinesfalls etwas einreden, aber stabilisierend kann das nicht wirken.

Ceos
19.08.2009, 12:26
ja, streckenweise rechne ich sogar fest mit dieser reaktion! es bleibt aber genügend zeit um die verschachtelung abzubauen ... problematischer ist es wenn zwischen den operationen in der ISR ne unterbrechung entstehen würde!

die ISR für den Komparator werd ich demnächst reduzieren, ich werd einen externen komoparator einsetzen, der die funktion meiner makros "START" und "STOP" übernimmt und den controller quasi nurnoch über das ereignis informieren, der dann die notwendigen schritte einleitet

ausserdem es müssten wirklich ziemlich genau 256 takte sein die ins land ziehen um diesen effekt auszulösen ... da der effekt IMMER dieselbe größe hat(und auch nur negativ ist) statt einer 100S pause warte ich 84µS .. ein "mehr" oder "weniger" ist nicht, es sind nur diese beiden ergebnisse .. 100µS sollen es sein, 84µS sind es wenn der timer mal wieder spinnt

vielleicht hat ja jemand noch nen gedanklichen beitrag, wie ich eine µS genaue verzögerung einbauen kann, die in der summe aber bis 500mS (eventuell mehr) dehnbar ist und parallel die abarbeitung eines datenbus erlaubt

und noch einmal, sehr viele testläufe haben erwiesen, dass die menge der ISR und die verwendung von cli() und sei() darin auf das gesamte timing keinen einfluss haben, nur eben dieser eine effekt stört gewaltig und bleibt mir ein rätsel .. der code den ich oben geschrieben habe beinhaltet eigentlich alles was mit den timern zu tun hat und auch alle ISR die größer sind als 2 zeilen

in de rmain werden nur diverse variablen abgefragt um auf kommunikation und probleme reagieren zu können

leider kann cih hier nicht alles posten

PS: für die simulation fehlen mir die externen ereignisse und ne handeingabe fällt flach, wegen der zufälligkeit (was mich auch an dem simulationsergebnis zweifeln lässt) ^^

Gock
19.08.2009, 12:26
Ich kann meinen Vorrednern nur zustimmen.
Die ganze Struktur dieses Codes (und sein Format ganz neben
bei auch, dafür gibt es Code-Tags...) mit CLI und SEIs in der ISR und dann auch noch Unterprogrammaufrufen in diesen Ausmaßen sind einer mikrosekundengenauen Zeitmessung mehr als gegenläufig.
Außerdem ist das Programm so nicht zuverlässig terminiert, was dazu führen kann, dass es stundenlang läuft und sich dann mit einem Stackoverflow verabschiedet.
SEI und CLI sind zudem in allen Fällen außer Overflow2 völlig überflüssig, weil beim Eintritt in eine ISR ohnehin ein CLI ausgeführt wird und bei Austritt entsprechend ein SEI. Kann sogar sein, dass der Compiler diesen Unfug gleich wegoptimiert, sofern Du die Optimierung eingeschaltet hast, was ich doch hoffe.
Zuverlässig wäre es, wenn die ISR viel kleiner wird, möglicherweise nur ein Flag gesetzt wird, alle SEIs und CLIs draußen sind und die Unterprogrammaufrufe möglichst durch Code ersetzt werden, denn diese kosten Zeit.
Dann fällt auf, dass Du entweder eine alte GCC oder einen anderen Compiler benutzt. In ersterem Fall würde sich ein Update lohnen.
Ich befürchte, Dein Problem ist zuverlässig nicht nebenbei zu lösen, ohne den Rest des Programms auch zu kennen.
Gruß

Ceos
19.08.2009, 12:36
(und sein Format ganz neben
bei auch, dafür gibt es Code-Tags...)

ich versteh jetzt nciht ganz was du meinst


und die Unterprogrammaufrufe möglichst durch Code ersetzt werden naja das ist jetzt nur ne variante gewesen weil ich das OC ereignis im verdacht hatte, da hab ich den code in ne nmethode ausgelagert und im overflow kontrolliert ob ich mindestens ne 10 im OCR stehen hab und sonst direkt in den zweig einsteige

und jetzt noch die preisfrage, wie kommst du darauf, dass mein compiler zu alt sein soll ??? ich hab mal neuesten winavr installiert aber geändert hat siocih nix

Gock
19.08.2009, 13:04
Das sind Code-Tags:

ISR(SIG_OVERFLOW2) // Timer 2
{
if (faktor != 0) faktor--;
cli();
if (faktor == 0){
TIMSK &= ~(1<<TOIE2);
if (TCNT2+10 > OCR2) timeUp2();
else TIMSK |= (1<<OCIE2);
}
sei();
}
Du schreibst "[ code ]...[/ code ] ohne die Leerzeichen zwischen den Code. Außerdem ließe sich Dein Geschreibsel wesentlich besser lesen, wenn Du richtige deutsche Wörter (ein statt "ne") und Satzzeichen benutzen würdest.
Du benutzt "ISR(SIG_OVERFLOW)"
Das hat mich verwirrt, weil SIG... ist die alte Schreibweise, das heißt jetzt (TIMER1_OVF_vect)". Die neuen GCCs prüfen das aber und es funktioniert.
Gruß

Ceos
19.08.2009, 13:15
achsoooooo ja gut hab mich halt so dran gewöhnt mit den SIG'S ..

tut mir leid dass ich nicht grammatikalisch korrekt schreibe, satzzeichen verwende ich auch schon hin und wieder

ich weis dass diese art des schreibens manchen leuten "eines forums unwürdig" erscheint und ich verpflichte sie auch nicht zu antworten wenns ihnen nicht passt

ich rechne es dir dennoch hoch an dass du es trotzdem tust ;)

ich "rede" halt mehr als dass ich schreibe, hab halt immer zu viel gechattet und da gewöhnt man sich ein paar übelkeiten an

zu den tags, ich hab doch code tags verwendet oder hast du die da jetzt rein editiert wie ich sie vergessen habe .. oder hab ich jetzt wieder was falsch verstanden .. sorry ich bin ein wenig unkonzentriert weil ich der verzweiflung nahe bin, kann sein, dass ich vergessen habdie einzufügen ..

der code an sich sah auch schonmal schöner aus ... des debuggings wegen hab ich ihn nur schwer verschandelt um mögliche ursachen einzugrenzen (alles in methoden verpackt und dann schrittweise abgeschaltet)


PS:
ich hab jetzt deinen rat befolgt und flags verwendet, die ich in der main polle und bei bedarf von dort aus die methoden aufrufe

zumindest hat diese aktion die reproduzierbarkeit auf scheinbar 0 zurückgeführt

möglicherweise ist das problem auch gelöst, aber da helfen mal wieder nur tests ..

ausserdem hab ich mir irgendwann im verlauf der untersuchung meine automatische kalibrierung zerschossen ^^ aber das wird schon wieder

sternst
19.08.2009, 14:01
Nach dem Lesen deiner Antworten drängt sich mir der Verdacht auf, dass du das mit den cli/sei noch nicht wirklich verstanden hast. Das macht die Hardware von ganz alleine. Beim Ausführen einer ISR wird das I-Flag gelöscht und durch das reti am Ende wieder gesetzt. Dein cli ist damit schon mal ohne jegliche Funktion, und das sei enabled die Interrupts nur etwas eher als es ohne der Fall wäre. Das bringt dir keinerlei Vorteil, nur potenzielle Nachteile.

Ceos
19.08.2009, 14:15
okay ... jetzt wo cih nochmal genau geschaut habe, hast du recht! hab ich gar nicht so gewusst

irgendwann aber, meine ich, hab ich gelesen (so in den anfängen) dass die ISRs verschachtelt aufgerufen werden können wenn ich sie nicht per cli und sei sperre ... und irgendwie hat das auch wirklung gezeigt ...

PS mein winavr war von 2007 (man sollte gebrauchtes equipment wirklich vorher überprüfen ^^) wenn ich mich vorhin nicht verguckt habe .. kann es sein dass das erst später dazukam ?

Ceos
19.08.2009, 15:30
HIER GEHTS MIT "ICP1 funktioniert nur einmal" WEITER


ISR(SIG_INPUT_CAPTURE1)
{
PORTB |= (1<<PB0);
if(TCCR1B & (1<<ICES1)) {
TCCR1B &= ~(1<<ICES1);
ramptimeusec = (ICR1>>1);
ramptimemsec = mtime;
}
else {
TCCR1B |= (1<<ICES1);
unsigned int ramptime = ((unsigned int)(mtime - ramptimemsec)) * 1000;
ramptime = (signed int)ramptime + (signed int)(ICR1>>1) - (signed int)ramptimeusec;
.....
}
PORTB &= ~(1<<PB0);
}

in dieser ISR versuche ich eine impulslänge zu messen ...

die flanken werden u.a. durch start und stop ausgelöst/erzeugt

kann es sein, dass durch das LÖSCHEN des edgeselect

TCCR1B &= ~(1<<ICES1);

der interrupt gestört wird ? wenn ich die zeile aus dem true-zweig nämlich rauseditiere gehts, dann bekomme ich den strobe mit!

ich hab jetzt die startbedingung geändert und den edgeselect auf falling initialisiert, und siehe da ich bekommen GARKEINEN impuls ... hab ich meinen komparator geschrottet ? hab ich beim schreiben der ISR was nicht beachtet ??? warum bekomm cih auf fallende flanken plötzlich keinen interrupt mehr ?

das signal hab ich auf dem oszi überprüft, einwandfrei!

sternst
19.08.2009, 15:54
irgendwann aber, meine ich, hab ich gelesen (so in den anfängen) dass die ISRs verschachtelt aufgerufen werden können wenn ich sie nicht per cli und sei sperre ...Dann bezog sich der Text entweder nicht auf den AVR oder er war schlicht falsch.


PS mein winavr war von 2007 (man sollte gebrauchtes equipment wirklich vorher überprüfen ^^) wenn ich mich vorhin nicht verguckt habe .. kann es sein dass das erst später dazukam ?Wie bereits gesagt, es ist ein Feature der Hardware, der Compiler hat nicht das Geringste damit zu tun.

Ceos
19.08.2009, 16:00
mh ergibt sinn, er springt an die adresse und unterdrückt dabei die interrupts ... naja man lertn halt nie aus ...

dennoch

wie kann es sein dass mein input capture keine fallenden flanken detektiert ?! das macht mich jetzt echt stutzig

egal was ich mach es kommt einfach kein interrupt zustande, trotz sauberem 5V Impuls mit fallender als auch steigender flanke!


OCR1A = 2000;
TCCR1A |= (1<<WGM11) | (1<<WGM10);
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS11);// | (1<<ICES1);
// TIFR |= (1<<TOV1);
TIMSK |= (1<<TICIE1) | (1<<TOIE1);


das ist der initialisierungscode, wenn ich den ICES1 wieedr einschalte, bekomme ich einen strobe solange ich ihn anlasse, schalte ich ihn ab kommt wieder kein strobe/interrupt

sternst
19.08.2009, 16:37
Lasse mal folgendes aus dem Datenblatt in deinen Code einfließen, und probiere es dann nochmal:

After a change of the edge, the input capture flag (ICF1) must be cleared by software (writing a logical one to the I/O bit location).

Außerdem würde ich ICR1 so früh wie möglich auslesen (insbesondere noch vor der Flankenänderung), also:
unsigned int capture = ICR1;gleich als allererste Zeile in der ISR, und dann mit capture weiterarbeiten.

Ceos
19.08.2009, 19:36
die zeile muss ich überlesen haben ... muss ich morgen mal ausprobieren, danke für den hinweis

die variable wollte ich eigentlich umgehen, da ich davon ausging dass kein neues ereignis auftreten kann (zumindest in der praxis) aber kann ja was schief gehn ^^ ... komisch aber dass es vorher funktioniert hat ... äußerst seltsam ... kann das evtl. am alten compiler manchmal liegen ?!

Ceos
20.08.2009, 09:05
kein erfolg ....


/** Interruptservice routine for timer 1 input compare.
*/
ISR(SIG_INPUT_CAPTURE1)
{
PORTB |= (1<<PB0);
if(TCCR1B & (1<<ICES1)) {
TCCR1B &= ~(1<<ICES1);
TIFR |= ICF1;
ramptimeusec = (ICR1>>1);
ramptimemsec = mtime;
}
else {
TCCR1B |= (1<<ICES1);
TIFR |= ICF1;
unsigned int ramptime = ((unsigned int)(mtime - ramptimemsec)) * 1000;
ramptime = (signed int)ramptime + (signed int)(ICR1>>1) - (signed int)ramptimeusec;

}
PORTB &= ~(1<<PB0);
}


//initialisierung
...
OCR1A = 2000;
TCCR1A |= (1<<WGM11) | (1<<WGM10);
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS11) | (1<<ICES1);
TIFR |= (1<<TOV1) | (1<<ICF1);
TIMSK |= (1<<TICIE1) | (1<<TOIE1);
...



ich bekomme genau EINEN impuls und dann totenstille

EDIT: ich kann auch nur ausdrücklich betonen: das eingangssignal ist ein rechtecksignal, beginnend mit steigender und abschliessend fallender flanke, variabler länge und wiederholfrequenz mit pegeln von 0V und 5V und sieht auf dem oszi traumhaft aus! ich kanns mir nciht erklären oder ich hab was elementares übersehen ... es hat aber SO schonmal funktioniert ... selbst mit nem 2008 compiler gehts nciht ... 2007 (also der ganz alte) finde cih garnichtmehr zum

EDIT: es liegt nicht am computer! habs grad an nem anderen compiliert ...

ich habe es mal simuliert und einfach den ICP pin über das port register geschaltet, da funktioniert es einwandfrei ...

da ich das ICES in der ISR ändere, muss ich laut simulation nicht mal das flag löschen ... das scheint da automatisch zu passieren ...

in der realität habe ich einen spannungspegel von einem anderen pin angeschlossen, der etwas schaltet das signal ist aber ganz normal und dennoch detektier ich KEINE FALLENDEN flanken

Ceos
20.08.2009, 12:48
triple post ... aber ... GELÖST

meine güte wie dämlich von mir ...

TIFR |= (1<<TOV2);

löscht AUTOMATISCH mein ICF mit ... ist ja völlig logisch >_<

mit TIFR = (1<<TOV2); geht es jetzt

tja das passiert wenn man zu sehr die refgisternutzung verallgemeinert ^^

sast
20.08.2009, 14:02
mmh verstehe ich nicht. Wieso soll das setzen eines ganzen Bytes besser sein als das eines Bits? Wenn ich das richtig sehe im Datenblatt, dann wird doch der ICF1 mit 1 gelöscht. Dh du setzt ihn mit dem Aufruf von TIFR = (1<<TOV2); auf 0.
Ist das wirklich das was du wolltest?

sast

sast
20.08.2009, 14:02
mmh verstehe ich nicht. Wieso soll das Setzen eines ganzen Bytes besser sein als das eines Bits? Wenn ich das richtig sehe im Datenblatt, dann wird doch der ICF1 mit 1 gelöscht. Dh du setzt ihn mit dem Aufruf von TIFR = (1<<TOV2); auf 0.
Ist das wirklich das was du wolltest?

sast

Ceos
20.08.2009, 15:01
ja klar, lt. DAtenblatt muss ich das ICF-flag und das TOV-flag löschen, BEVOR ich den interrupt einschalte ... wennn ich aber nun

TIFR |= (1<<TOV0);

schreibe und DABEI das ICF1-flag auch gesetzt ist, schreibe ich die aus dem register entnommene 1 bei ICF1 auch wider als 1 zurück und lösche damit dieses flag (bisher) unwissentlich ... wenn ich aber einfach alles 0 lasse und nur dem flag ne 1 geb das ich auch löschen will, also:

TIFR = (1<<TOV);

dann löäsche ich auch nur exakt dieses bit und die anderen bleiben durch die 0 unberührt

sast
20.08.2009, 15:31
TIFR = (1<<TOV0); bedeutet, dass du das Bit an der Stelle TOV0 auf 1 setzt. Sagen wir mal TOV0 ist 0, dann steht in TIRF nach der Operation eine 1 egal ob da vorher 518 oder 3 drin stand. Das ist eine Zuweisung des Wertes (1<<TOV0).
Durch das bitweise ODER setzt du ja gerade nur das Bit welches du ändern willst und die anderen bleiben unberührt.

sast

Ceos
20.08.2009, 15:55
nein eben nicht, das TIFR ist ein flag-register, das schreiben einer 1 an eine position löscht das bit, das schreiben einer 0 lässt das bit so wie es ist! also 0 ODER 1 es ist bei den flags genau umgekehrt, und deshalb bin ich gestolpert!

sast
21.08.2009, 08:11
Vielleicht hab ich mich mal wieder etwas unverständlich ausgedrückt im letzten post. Mit TOV0 ist 0 meinte ich, dass es ein #define TOV0 0 gibt, um die Bitposition im Byte anzugeben. Im Grunde ist egal ob 0 oder 1 nun ein Bit löscht. Mir ging es darum, dir klarzumachen, dass du bei X = (1<<0); X eine 1 zuweist, auch wenn vorher X == 122 war. Mit X |= (1<<0); wird da aber 123 draus. Hoffe das war jetzt verständlicher.

sast

Ceos
21.08.2009, 10:46
ich hab dich vollständig verstanden und dennoch wird wenn vorher im flag register vorher eine 122 steht und ich

register |= (1<<0) ;

schreibe, danach im register 0 stehen!

denn GENAU WEIL das setzen des bit es nach der operation löst einfach alles zu 0 wird

ich schreibs mal bitweise auf

10010010 // register =
10010010 | // register |
00000001 | // (1<<0)
=
00000000 // denn das setzen einer 1 löscht das bit, das setzen einer 0 lässt es unverändert

im konkreten beispiel ist TOV0 UND ICF1 gesetzt

TIFR also xx1xxxx1

wenn cih jetzt

xx1xxxx1 |= 00000001

also

xx1xxxx1 |
xx1xxxx1 |
00000001

rechne kommt

TIFR = 00000000

raus, denn wenn x bereits 1 ist im flagregister, löscht es sich durch das ver-odern selbst aus, wenn x aber 0 ist blleibt es eben unbverändert 0

Hubert.G
21.08.2009, 11:13
Also Ceos, was du da schreibst ist unfug.

In einer Oder-Verknüpfung wird nie auf 0 gestellt wenn es nicht schon 0 ist.
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1

register |=(1<<0) setzt bit0 auf 1
register &= ~(1<<0) setzt bit0 auf 0
und zwar wird immer nur bit0 verändert, die anderen bleiben unverändert.

Siehe auch hier: www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_Register

sast
21.08.2009, 11:18
Du siehst mich ratlos.

Bis heute war ich der irrtümlichen Meinung, dass
1|1=1
1|0=1
0|1=1 und
0|0=0 sind.

Aber vielleicht ist das ja bei Registern anders :)

sast

Edit: Wie ich sehe gibt es auch noch andere die nach der alten Schule gelernt haben

021aet04
21.08.2009, 11:25
Was ist der Unterschied zwischen dem was Hubert geschrieben hat und was sast geschrieben hat? Das ist doch das gleiche.
Das hat Hubert geschrieben


0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1


Das hat sast geschrieben



1|1=1
1|0=1
0|1=1 und
0|0=0 sind.

sast
21.08.2009, 11:37
@021...
Sorry, dass ich vor dem Verschicken meiner Nachricht nicht nachgesehen hatte, ob es schon eine Antwort nach Ceos's Post gab

das ist natürlich das Gleiche

sast

Ceos
21.08.2009, 16:04
Öhm ich glaub ihr überseht den zusammenhang!!!!1111einseinself

ich rede von dem TIFR das Timer Interrupt Flag Register

jedesmal wenn es uum GENAU dieses Register geht, steht AUSDRÜCKLICH


4. Some of the Status Flags are cleared by writing a logical one to them. Note that the CBI and SBI instructions will operate on
all bits in the I/O Register,writing a one back into any flag read as set, thus clearing the flag. The CBI and SBI instructions
work with registers $00 to $1F only. zu lesen auf Seite 327 im M32 Datenblatt ziemlich weit oben direkt unter der Tabelle

sast hat den kontext scheinbar nicht mitbekommen oder diesen fakt üübersehen und ich geh mal davon aus, dass hubert sich hat nur mitreissen lassen und auch den kontext übersehen hat


da jetzt der zusammenhang hergestellt ist, sag ihc es nocheinmal:

mein problem war, wenn ich das Overflow Flag mit |= gelöscht habe, wurde auch das Input Capture Flag MITGELÖSCHT ... erst als ich im debugging gemerkt habe, wie bei TIFR |= (1<<TOV0) auch das ICF1 ausging, kam mir die erleuchtung!

darum schreibe ich es nochmal für später suchende die hier mal landen, wenn man ein flag löschen will, niemals SBI(), CBI(), |= oder &= verwenden, sondern ganz einfach NUR dieses bit auf 1 setzen mit

register = (1<<das_bit);

sast
21.08.2009, 16:20
Da steht nach meinem engl. Verständnis nur, dass man die Register auch bitweise setzen kann. Du hast mich also noch nicht überzeugt.

sast

Ceos
21.08.2009, 16:32
Note that [...] writing a one back into any flag read as set, thus clearing the flag

beachten sie [...] dass das schreiben einer 1(one) in ein flag, das als 1(set) ausgelesen wurde, das bit löscht(clear)

(das bezieht sich u.a. auf CBI und SBI, die das register auslesen und dann den ausgelesenen wert, zuzüglich der gewünschten veränderung, zurückschreiben, also das was man mit |= und &= bewirkt)

ich denke das müsste deutlich sein?!

Hubert.G
21.08.2009, 18:35
Der große Irrtum ist, denke ich mal, entstanden das es nicht klar war, das es sich ausschließlich um das TIFR-Register handelt und nicht um die |= Funktion.
Beim TIFR Register ist es so wie Ceos geschrieben hat, aber ausschließlich bei diesem Register. Zumindest weiss ich kein anderes.

sast
21.08.2009, 18:56
So richtig verstanden hab ich das jetzt immer noch nicht.
Ich glaube zwar, dass ich es kapiert habe, aber hätte trotzdem noch mal gern einen Check.

Beim ODER wird zb bei Bit0 eine 1 gesetzt (was das Bit0 löschen soll), aber durch eine 1 in Bit3 des TIFR wird nach dem ODERdes Bits auch eine 1 und die löscht dann das Bit3. Hab ich das so richtig verstanden?

sast

Ceos
21.08.2009, 19:21
genau

weil durch das "|=" einmal der wert des registers VOR dem "|=" mit dem wert HINTER dem "|=" verODERt wird und dann in das register zurückgeschrieben wird

und da eben in diesem speziellen register eine 1 das löschen bedeutet, löschen sich alle gesetzen flags selbst aus ... das dient eigentlich nur dazu, dass man das flagregister nicht manipulieren kann, sondern nur gezielt bits löschen kann ...

warum dazu nun gerade eine "1" gebraucht wird erschließt sich mir auch nicht .... eine "0" hätte es da doch auch getan, oder weis jemand gerade warumd as bei dem register so ist ?! eine spezielle logikschaltung über dem register? irgendeine konvention in der digitaltechnik ?

sast
21.08.2009, 19:57
Nach dem letzten Satz in Punkt 4 sollte es eigentlich bei allen Registern so sein, ab 1F. Denn nur bis dahin arbeiten CLI und SBI normal.

sast