Hallo @all, ich hab ein Problem, ich benutze zwei Timer vom ATmega8 die mir überläufe zählen sollen. Das funktioniert auch soweit. Die eine Variable ist uint32_t k und die andere ist uint32_t j. Die Überläufe sollen dafür verwendet werden die Phasen differenz zwischen zwei signalen zu ermittel. Die Berechnung lautet wie folgt: char s[20]; uint32_t T0,T2; double PHI; T0 = (k << 8) + TCNT0; //Wert für die ganze periode (T) << 8 = *256 T2 = (j << 8) + TCNT2; //Wert für die delta t PHI = ((T2 +0.0)/T0)*360.0; wenn ich mir mit uart_puts( ultoa( k, s , 10)); k ausgeben lasse kriege ich auch einen Vernünftigen wert z.b. 208 ( (16Mhz/(208 * 256)) = 300Hz der frequenz die ich auch anlege mal per hand gerechnet.) uart_puts(ultoa(j, s, 10)); lifert z.b. einen Wert von 4 somit kann ich mir mal schnell ausrechnen (((4*256)/(208*256))*360)= 6,92° Phasenverschiebung) wenn ich mir das aber mit uart_puts( dtosrtf(PHI, 10, 4, s)); Kommt was anderes raus auch wenn ich mir nur mal die Werte für k und j ausgeben lasse alleine kriege ich die 208 und die 4 wenn ich noch PHI ausgeben lasse dann sehen die Werte plötzlich ganz anders aus. uatr_puts(...) hier entnommen: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART Ich weis das sind hier nur mal code auszüge. Initiealisierungen und so weiter solten eigentlich soweit stimmen. Vielleicht hatte ja schon jemand ein ähnliches problem oder weis rat ich würde mich freunen danke schon mal. mfg m.s.
Du benutzt Variablen sowohl im Interrupthandler als auch in der main-Schleife. volatile ist hier das Stichwort. Außerdem ist der Atmega8 ein 8-Bit-µC, muss also jede 32-Bit-Operation aufwendig mit mehreren Befehlen nachbilden. Davon weiß aber der Interrupthandler nichts, es kann also sein, daß während des Zugriffes auf die 32-Bit-Variable sich bereits Teile davon ändern. Stichwort hier ist atomare Operation.
Erst mal danke für die schnelle Antwort. vor der berechnung schalte ich die interrupts an INT0 und INT1 ab mit hilfe von GIMSK &= ~((1<<INT0) | (1<<INT1)); nach der ausgabe schalte ich sie wider ein mit GIMSK |= (1<<INT0) | (1<<INT1);. Vor der Ausgbae werden auch noch die TIMER angehalten so das es eigentlich zu keinen weiteren überläufen kommen kann. Die variablen k und j sowie T0 und T2 hatte ich als extern deklarirt. Werde das mal morgen mit volatile überprüfen ob es daran gelegen hat ansonsten werde ich mal die kompletten interrupts ausschalten vor der Ausgabe und dSie nach der asugabe wider einschalten. mfg m.s.
Hi Rufus, danke noch mal es lag tatsechlich daran das ich nicht die kompletten interrupts ausgeschaltet habe sondern nur einen Teil davon. Jetzt wird vor der ausgabe cli(); und nach der ausgabe sli(); gesetzt und es geht. wobei mich das etwas iretiert da es eigentlich laut meinem Verständnis zu keinen problemen kommen solte wenn ich die Interrupts an INT0 und INT1 ausschalte und die Timmer nicht laufen kann es ja auch nicht zu überlauf Interrupts kommen. Naja ist j auch egal man steckt halt nicht drinne und weis nicht immer ganz was da alles passiert. mfg m.s.
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.