Hallo zusammen, mein Atmega88 ist auf int. 8Mhz "gefused". Auch im AtmelStudio habe ich die F_CPU=8000000UL angegeben. Wenn ich jetzt mit folgendem Code meinen Ausgang setzte, ist dieser (oszi) genau 82us eingeschaltet. Das ist ca. Faktor 10 + etwas ungenauigkeit ? ISR (INT0_vect) { PORT_D7 = 1; _delay_us(10); PORT_D7 = 0; komisch ist, dass die Zeit bei weglassen der Definition F_CPU=8000000UL ~korrekt ist. Jedoch bringt er dann den Fehler F_CPU not defined.. Was kann der Fehler sein?
Philipp L. schrieb: > komisch ist, dass die Zeit bei weglassen der Definition F_CPU=8000000UL > ~korrekt ist. > Jedoch bringt er dann den Fehler F_CPU not defined.. wie geht das?
Philipp L. schrieb: > Hallo zusammen, > > mein Atmega88 ist auf int. 8Mhz "gefused". > Auch im AtmelStudio habe ich die F_CPU=8000000UL angegeben. > > Wenn ich jetzt mit folgendem Code meinen Ausgang setzte, ist dieser > (oszi) genau 82us eingeschaltet. > Das ist ca. Faktor 10 + etwas ungenauigkeit ? Genauer gesagt läuft es um Faktor 8 falsch, das kommt dadurch dass die CPU tatsächlich mit 1 MHz läuft... Mach Mal den 8er Vorteilen (LOW.CKDIV8 Fuse) weg, dann sollte es richtig funktionieren...
Du hast in den Screenshot noch die CKDIV8-Fuse gesretzt, die teilt den Takt nochmal durch 8. Also hast du reell nur noch 1MHz
Wenn F_CPU nicht gesetzt ist, wird die Warnung ausgegeben und F_CPU auf 1MHz gesetzt. Dass das Timing dann stimmt, spricht dafür, dass der Controller mit 1 MHz läuft, also CKDIV8 aktiv ist.
Vielen Dank, das war auch das Problem der restlichen Programmfehler. Aber: Mit folgendem Code müsste ich doch nun genau auf 87us kommen. Hatte ich auf dem Mega8 mit Timer2 auch schon gemessen, muss aber nun auf Mega88 und Timer0 umstellen. Ich messe nun aber 92us (also +5us). Auszug der Intitialisierung: OCR0A=87; //Compareregister TCCR0A |= (1<<WGM00)+(1<<WGM01); //Fast PWM mit TOP=0xFF TCCR0B |= (1<<CS01); //Prescaler=8 TCNT0 = 0; //Aktuellen Zählerstand=0; TIMSK0 |= (1<<OCIE0A); //CompareA=Ein ISR (INT0_vect) { PORT_D7 = 0; TCNT0 = 0; } ISR (TIMER0_COMPA_vect) { PORT_D7 = 1; }
:
Bearbeitet durch User
Du gehst davon aus das die 8 MHz stimmen. Tun sie aber nicht. Und dein Quelltext dürfte auch noch genug Fehler haben...
:
Bearbeitet durch User
> Du gehst davon aus das die 8 MHz stimmen. Tun sie aber nicht. Beim Mega8 (DIP auf Steckbrett) sind es mit dem code (auf Timer2) ganz genau 87us. Gehen die MLF´s nach der Reflow-Behandlung denn soo falsch? > Und dein Quelltext dürfte auch noch genug Fehler haben... Von Quellcode (siehe oben) kann man dabei eher nicht sprechen. Ich schalte in der ISR doch nur den Ausgang.
:
Bearbeitet durch User
Philipp L. schrieb: >> Du gehst davon aus das die 8 MHz stimmen. Tun sie aber nicht. > Beim Mega8 (DIP auf Steckbrett) sind es mit dem code (auf Timer2) ganz > genau 87us. Timer2 ist das mit TCCR0 aber nicht, 87us sind Zufall. > Gehen die MLF´s nach der Reflow-Behandlung denn soo falsch? Der RC Takt ist Produktions, Temperatur und Spannungsabhängig. Kann aber kalibriert werden. > >> Und dein Quelltext dürfte auch noch genug Fehler haben... > Von Quellcode (siehe oben) kann man dabei eher nicht sprechen. > Ich schalte in der ISR doch nur den Ausgang. Alleine was man da schon sieht... Beschreib doch mal EXAKT was der Code GENAU machen soll, nicht das Fernziel sondern nur der Testcode.
> Alleine was man da schon sieht... Beschreib doch mal EXAKT was der Code > GENAU machen soll, nicht das Fernziel sondern nur der Testcode. Das Gesamtprogramm funktioniert mit exaktem Takt und bedarf daher aktuell keiner Detailbeschreibung (DCC-Dekoder). Mit dem Testcode teste ich doch nur den Takt... Dies soll folgendes machen: Bei int0 (kommt regelmäßig) -> Ausgang ausschalten und Timer0 rücksetzen Bei Timer0-compareA (nach 87us) -> Ausgang einschalten > Timer2 ist das mit TCCR0 aber nicht Beim Mega8 auf Timer 2 ist es natürlich eine andere Initialisierung, schon richtig. Hier beziehe ich mich ja auf das aktuelle Problem und nicht auf die funktionierende Steckbrettvariante.. >87us sind Zufall. 8Mhz Takt Prescaler 8 beim Timer = 1Mhz Compare = 87 Da sind 87us eher kein Zufall...
:
Bearbeitet durch User
> Mit folgendem Code müsste ich doch nun genau auf 87us kommen.
Zum einen beginnt ein Timer bei 0, man muss bei OCR0A also 1 abziehen.
Zum anderen vergeht nach dem Erreichen des Compare-Werts eine gewisse
Zeit (Latenz), bis das Port-Schalten in der ISR erreicht wird, wieviel
genau muss ein C-Kenner sagen. Für Assembler siehe den Datenblattauszug
im Anhang.
Philipp L. schrieb: > Ich messe nun aber 92us (also +5us). Was fummelst du auch in der ISR am Zählstand rum. Wenn deine Latenz höher ist, als die Periode des Timertaktes, verlierst du Schritte, d.h. die Zeit verlängert sich. Lass deine Routine einfach mal im Simulator oder mit Debugger laufen und guck dir an, was der Timer macht, während in die ISR gesprungen und die Register gesichert werden.
Philipp L. schrieb: > Mit folgendem Code müsste ich doch nun genau auf 87us kommen. > Ich messe nun aber 92us (also +5us). > > Auszug der Intitialisierung: > OCR0A=87; //Compareregister > TCCR0A |= (1<<WGM00)+(1<<WGM01); //Fast PWM mit TOP=0xFF ... > ISR (TIMER0_COMPA_vect) > { > PORT_D7 = 1; > } Was soll das Setzen von PD7 in der ISR? Der Sinn einer Hardware-PWM besteht doch genau darin, daß die Hardware die Pins wackeln läßt und man nicht mehr den unkalkulierbaren Zeitversatz für den Aufruf der ISR drauf hat.
Axel S. schrieb: > Was soll das Setzen von PD7 in der ISR? Na was wohl? Soll er die 87µs dem Oszi durch gut Zureden mitteilen? Deine Fragen werden von Tag zu Tag intelligenter.
Vollpfostenberater schrieb: > Na was wohl? Soll er die 87µs dem Oszi durch gut Zureden mitteilen? Nein, er könnte das Oszi an den OC0A Pin hängen. > Deine Fragen werden von Tag zu Tag intelligenter. Wer im Glashaus sitzt ...
Vollpfostenberater schrieb: >> Was soll das Setzen von PD7 in der ISR? > Na was wohl? Soll er die 87µs dem Oszi durch gut Zureden mitteilen? > Deine Fragen werden von Tag zu Tag intelligenter. Bist du ganz sicher, verstanden zu haben, wie ein PWM Timer funktioniert? Ich empfehle dir, das entsprechende Kapitel im Datenblatt in Ruhe zu lesen und ggf. fragen zu stellen, falls etwas unklar ist.
Eigentlich ist es ja lächerlich bei den Vorraussetzungen weiter zu machen aber was solls, ist Wochenende: - er "benutzt" den Fast PWM Mode, lässt aber keinen Pin direkt davon ansteuern, macht also keinen Sinn. - bastelt sich dann den Compare Interrupt, in dem er den Pin setzt, dafür braucht es keinen PWM Mode, aber geht. - dann wird der Pin zu beliebigen, von Aussen bestimmten, Zeitpunkten zurück gesetzt, eben wenn ein Int0 kommt, warum auch immer. - diverse Ungenauigkeiten (nicht kalibrierte RC Clock, Latenz der ISRs) kommen auch noch dazu. Und trotzdem soll das Ding genau 87us haben? (was eigentlich? Periode, high, low? Aber eigentlich auch egal weil es die 87us wenn überhaupt nur zufällig hat.) Das Ganze mal abgesehen davon das mir die PORT_XY = 1/0 Syntax nicht geläufig ist, aber ich benutze auch noch das 4.19 AVR Studio, würde aber auf irgendein selbstgebasteltes/kopiertes/sonstwas Makro tippen, dessen genaue Funktion ich aber nicht kenne.
:
Bearbeitet durch User
Tim T. (tim_taylor) Du bist immer sehr schnell mit Kritik... Das ist ja okay, aber kritisiere doch bitte keinen mehrfach als test bezeichneten Code: Das ich in der PWM-ISR manuell einen Ausgang setze, ist doch nur mal schnell für die Zeitkontrolle am Oszi gewesen. Ich habe einen externen Interrupt (positive Flanke am int0) und möchte jedesmal genau 87us nach diesem interrupt ein paar Befehle ausführen. Der nächste Interrupt am int0 kommt frühestens nach 116us und stört daher nicht. Bestimmt kann man das auch besser machen, aber darum geht es hier doch überhaupt nicht. Dieses Vorgehen funktioniert ebenfalls mit compare=87 auf dem mega8 (dip) und timer2 im fast-pwm ganz exakt mit 87us.. Die Frage war: Sollte der oben gelistete Code nicht auch auf diesem mega88 genau 87us nach int0 den Ausgang schalten? Funktioniert ja auf dem mega8 (steckbrett) auch.. Die Frage war nicht: Ist das die allerbeste Vorgehensweise.
Und dann eben nochmal: Mit dem Programm und der Taktquelle sind die 87us ZUFALL.
Vom Interrupt-Ereignis bis zur Ausführung der Interruptroutine vergehen einige Takte, mal mehr mal weniger. Bei Eintritt in die Interruptroutine werden einige Register auf den Stack gesichert, bevor dein I/O Pin gesetzt wird. Pi mal Daumen würde ich hier von bis zu 12 Takten ausgehen. Bei deinen 1MHz Systemtakt macht das bis zu 12ms Verzögerung aus.
Tim T. schrieb: > Und dann eben nochmal: Mit dem Programm und der Taktquelle sind die 87us > ZUFALL. Reiner Zufall wird es wohl eher nicht sein, sondern seinen Grund haben. Der µC macht genau das, was man ihm gesagt hat. Also stimmt einfach nur die Erwartung nicht mit den tatsächlichen Abläufen überein. Um diese Diskrepanz zu klären, muss man dem µC genau auf die Finger schauen. Nur so kann man feststellen, was ihn daran hindert, den Pin nach 87µs zu wackeln. Betrachtung im Simulator, Debugger und der tatsächlich ablaufende Code - µC-Takt für µC-Takt - werden die Lösung offenbaren. Ein Fehler im µC wäre mit hoher Wahrscheinlichkeit wohl anderen schon aufgefallen.
Stefanus F. schrieb: > macht das bis zu 12ms Verzögerung aus. Das würde ich aber nochmal nachrechnen :-)
> Dieses Vorgehen funktioniert ebenfalls mit compare=87 auf dem mega8 > (dip) und timer2 im fast-pwm ganz exakt mit 87us.. Glück gehabt! Setzen Sie mal beim ATmega8 den Systemtakt von 8 MHz auf 1 MHz herunter und als Ausgleich den Vorteiler von Timer2 von 8 auf 1. Dann sollten Sie doch auch wieder "exakt 87 us" erhalten, oder? Ich wette mein Rennrad gegen einen Tretroller, dass das nicht der Fall ist.
Stefanus F. schrieb: > Pi mal Daumen würde ich hier von bis zu 12 Takten ausgehen. Bei deinen > 1MHz Systemtakt macht das bis zu 12ms Verzögerung aus. 12 Takte bei 1MHz würden 12 Microsekunden machen (und nicht Millisekunden). Die Responsetime des ATmega beträgt nach Datenblatt min. 4 Zyklen (macht bei 1MHz Systemtakt schon mal 4 µS). Ich würde dieses Teil wieder mit 8 MHz laufen lassen (und nicht mit 1 MHz) und den Timer 0 hierfür neu berechnen, damit die 4 Taktzyklen Responsetime nicht mehr so satt ins Gewicht fallen dürften. Abgesehen davon hat der interne Oszillator (wie oben schon geschrieben) so seine Toleranzen. 2% bis 3% sind normal, 5% wären viel aber imho noch zulässig und das ganze ist dann auch noch temperaturabhängig.
Dieter F. schrieb: > Stefanus F. schrieb: >> macht das bis zu 12ms Verzögerung aus. > > Das würde ich aber nochmal nachrechnen :-) Sorry, ich meinte natürlich 12µs
Philipp L. schrieb: > Das ich in der PWM-ISR manuell einen Ausgang setze, ist doch nur mal > schnell für die Zeitkontrolle am Oszi gewesen. Und war gerade deswegen eine blöde Idee <tm> > Ich habe einen externen Interrupt (positive Flanke am int0) und möchte > jedesmal genau 87us nach diesem interrupt ein paar Befehle ausführen. Nach genau 87µs oder nur nach "genau" 87µs? Und geht es wirklich darum, daß nach dieser Zeit "Befehle ausgeführt" werden, oder nicht doch eher darum, daß dann eine Reaktion zur Außenwelt erfolgen soll? > Bestimmt kann man das auch besser machen, aber darum geht es hier doch > überhaupt nicht. Du hast dich doch beschwert, daß die Zeit nicht eingehalten wird. Du meintest also, es wäre nicht gut genug und es müßte folglich besser gemacht werden. > Die Frage war: > Sollte der oben gelistete Code nicht auch auf diesem mega88 genau 87us > nach int0 den Ausgang schalten? > Die Frage war nicht: > Ist das die allerbeste Vorgehensweise. Die Frage wäre eher: ist das überhaupt eine geeignete Vorgehensweise, um die 87µs mit der geforderten (aber uns nach wie vor unbekannten) Genauigkeit einzuhalten? Und die Antwort hat dir dein Mega88 laut und deutlich ins Gesicht gebrüllt: NEIN.
Ralph S. schrieb: > Abgesehen davon hat der interne Oszillator (wie oben schon geschrieben) > so seine Toleranzen. 2% bis 3% sind normal, 5% wären viel aber imho noch > zulässig und das ganze ist dann auch noch temperaturabhängig. Und spannungsabhängig auch noch ;)
Ralph S. schrieb: > Die Responsetime des ATmega beträgt nach Datenblatt min. 4 Zyklen (macht > bei 1MHz Systemtakt schon mal 4 µS). Mit Leitfähigkeiten hat das ganze Problem überhaupt nichts zutun, zumal ein Wert von 4µS fast schon für einen Isolator steht. Und vom Systemtakt wäre die schon gar nicht abhängig.
S.I. schrieb: > Mit Leitfähigkeiten hat das ganze Problem überhaupt nichts zutun Das haben schon alle so verstanden, wie es gemeint war. Nur du nicht, weil du es nicht verstehen wolltest.
Nochmal zusammengefasst, was dir hier schon einige aufgeschrieben haben: So ist der Ablauf: 1) Flanke an Pin löst externen Interrupt aus 2) Verzögerung bis zum Aufruf der ISR (inklusive Register sichern etc.) mindestens 4 Takte, mit Register sichern mehr, bei 1MHz also mindestens 4µs (sperrst du in der Hauptschleife zeitweise die IRQs?) 3) Pin D7 wird auf 0 gesetzt 4) Timer wird - mindestens* einen Takt später, bei 1MHz also mindestens 1µs später - auf 0 gesetzt 5) 87µs +- Ungenauigkeit des RC-Oszillators vergehen 6) Compare-Interrupt wird ausgelöst 7) Verzögerung bis zum Aufruf der ISR (inklusive Register sichern etc.) mindestens 4 Takte, mit Register sichern mehr, bei 1MHz also mindestens 4µs 8) Pin D7 wird auf 1 gesetzt Nun weiß ich nicht, ob du mit dem Oszi die Zeit von der Flanke in Schritt 1 bis zur Flanke in Schritt 8 misst oder von der Flanke in Schritt 3 bis zur Flanke in Schritt 8, aber definiert 87µs ist nur Schritt 5. Und das auch nur mit der Genauigkeit des RC-Oszillators, der schonmal einige Prozent daneben liegen kann. MfG, Arno *mindestens, weil ich nicht weiß, wie PORT_D7 = 0 in Assembler übersetzt wird, das Konstrukt kenne ich so nicht.
Stefanus F. schrieb: > Nur du nicht, weil du es nicht verstehen wolltest. Ich habe nur in Worte gefasst, was Ralph geschrieben hat. Vielleicht meint er auch "8MHz", wenn er "1MHz" schreibt, weil er sich angewöhnt hat die 8 als "1" zuschreiben. Kann jeder machen, wie er möchte - kann aber durchaus auch mal nach hinten los gehen.
4µs ... zufrieden ? SEKUNDEN und nicht SIEMENS ! Darf man das überhaupt groß schreiben? SEKUNDEN ? Oder verstehen es deutsche Menschen nur dann, wenn es Sekunden heißt? Liest ein Elektroniker automatisch SIEMENS (oder Siemens?) wenn es um Zeit geht? Und warum brennt nacht im Kühlschrank das Licht, wenn die Leitfähigkeit zur Lampe nur 4µS beträgt (das s jetzt GROSS geschrieben S ... und bitte als Siemens zu lesen)? Sind dann 3,66mh eine Sekunde oder ist das jetzt eine falsch geschriebene Spule? Mein lieber Henry aber Siemens auch, Herr Isaac Ohm (oder hieß der Newton, Tesla oder Heinrich der 8. von Hertzen) dreht sich bestimmt im Stromkreisgrabe um? By the way, wenn das alles irgendwie Namen von Verstorbenen sind, warum finde ich dann keinen Menschen, der Sekunde oder Seconds mit Nachnamen heißt? Hab ich da was verpasst? Okay, ich bin ungebildet und gebe an die besser gebildeten ab !
Beitrag #5811132 wurde von einem Moderator gelöscht.
Ralph S. schrieb: > Hab ich da was verpasst? Ja: den knall. Jeder normale Mensch versteht trotzt des kleinen Rechtschreibfehlers, was gemeint war.
Ralph S. schrieb: > Hab ich da was verpasst? Okay, ich bin ungebildet und gebe an die besser > gebildeten ab ! Korrekte Terminologie ist wichtig. Und dazu gehören auch die korrekten Einheiten. Wenn man sich das gleich richtig angewöhnt tut es nicht weh und man muss später nicht in Foren deshalb rumheulen. Das hat auch nichts mit Bildung zu tun sondern mit Sorgfalt.
:
Bearbeitet durch User
Taiga Wutz schrieb im Beitrag #5811132: > Philipp L. schrieb: >> Das Gesamtprogramm funktioniert mit exaktem Takt und bedarf daher >> aktuell keiner Detailbeschreibung (DCC-Dekoder). > > Für DCC sind aber andere Zeiten als 87µs gebräuchlich. Siehe hier: > > http://www.miba.de/morop/nem670_d.pdf OT: 87µs sind "die Mitte" zwischen 58µs und 116µs - das ist genau der richtige Abtastzeitpunkt, um festzustellen, ob ein Puls 58µs oder 116µs lang ist. MfG, Arno
Arno schrieb: > OT: 87µs sind "die Mitte" zwischen 58µs und 116µs - das ist genau der > richtige Abtastzeitpunkt, um festzustellen, ob ein Puls 58µs oder 116µs > lang ist. Und da kommt es dann auf 10 µs mehr oder weniger an? Pah... :-) Da soll er den Timer halt mit den ca. 8 MHz laufen lassen - dann spielt der Prolog der ISR nicht die entscheidende Rolle und das Bit wird zuverlässig erkannt.
Beitrag #5811404 wurde vom Autor gelöscht.
Mich hat doch nur gewundet, warum das "gleiche" Programm beim Mega8 und Mega88 so unterschiedliche Zeiten ergibt. Es ist ja kein Problem, ich passe den compare auf 82 an und alles ist gut. Auch ist die Genauigkeit für DCC auch so schon ausreichend. Ich hätte beide Codes mit beiden Oszi-Auswertungen vernünftig nebeneinander stellen sollen. Arno schrieb: > Nochmal zusammengefasst, was dir hier schon einige aufgeschrieben haben: Ja, habe ich mitgenommen -> Danke! Am besten wir brechen den Thread hier ab, besser wirds nicht mehr :-) Dann folgt gleich eine hofffentlich echte Frage in neuem Thread.
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.