Hallo zusammen Habe ein riesen Problem. Zwar verwende ich ein timer mit eingestellter frequenz von 122.88 kHz. Wenn ich die Frequenz am OCO messe erhalte ich diese auch, jedoch wenn ich über den zugehörigen Interrupt einen Port toggle erhalte ich nur noch ca. 35kHz. Weiss dass ich für den Aufruf und des setzen des Ports zeit verliere .... aber das gleich so ein unterschied entsteht. Wie könnte man das Problem lösen oder ist es schlichtweg nicht möglich bei dieser grossen Frequenz den Port auf 122.88 kHz über die Interrupt-routine zu togglen? Habe daszu noch ne frage .... Eigentlich brauche ich exakt 122.88kHz, jedoch stellt sich meine Frequenz zwischen 122.90101 kHz - 122.91248kHz ein. Wie realisier ich das, dass ich genau 122.88 kHz erhalte ? Indem ich einen externen Quarz anschliesse oder gibt es eine andere möglichkeit? besten dank für eure Hilfe.
Bitte erkäre mir, wie du denkst, dass wir dir helfen können, wenn wir deinen Code nicht kennen?
> Eigentlich brauche ich exakt 122.88kHz, > jedoch stellt sich meine Frequenz zwischen 122.90101 kHz > - 122.91248kHz ein. > Wie realisier ich das, dass ich genau 122.88 kHz erhalte ? > Indem ich einen externen Quarz anschliesse oder gibt es > eine andere möglichkeit? Wenn Du den Controllerinternen RC-Oszillator verwendest, dann sind die von Dir geschilderten Abweichungen vollkommen normal. Dieser Oszillator ist nunmal ungenau. Verwende entweder einen Quarz und schließe den als Resonator an die Oszillatorschaltung des Controllers an (meist XTAL1 und XTAL2 genannt), und vergiss nicht die erforderlichen Kondensatoren. Oder verwende einen Quarzoszillator als externe Taktquelle.
Tanja Hofmann wrote:
> Wie realisier ich das, dass ich genau 122.88 kHz erhalte ?
Indem du zuerst eine Taktquelle organisierst, die 0 ppm Abweichung hat.
Oder die überlegst, was für dich "exakt" bedeutet.
Mhhh habe da glaubich ein grösseres Problem, weil auf dem Board (atmega128L drauf) am XTAL1 und XTAL2 schon ein Quarzoszillator vorhanden ist ( 7.3728 MHz ). Das Problem ist eben das ich nach 15 Perioden von der Frequenz 122.88 kHz einen Port auf High setzten muss und anschliessen nach 15 Perioden der Frequenz 122.88 kHz wieder auf Low ..... So das ich schlussendlich immer nach 15Perioden der Frequenz 122.88kHz ein Bit ausgeben kann und somit ein Bitmuster zu erzeugen. Per Interrupt kann ich das ja nicht aufzählen, weil dort der Aufruf bei dieser Frequenz nicht mehr richtig klappt. Hätte da jemand eine Idee wie ich das am Besten lösen könnte? Bin wirklich sehr, sehr dankbar für eure Hilfe.
Wahrscheinlich betreibst du den Timer im falschen Modus und setzt ihn im Interrupt neu. Besser: PWM- oder CTC-Modus.
Tanja Hofmann wrote: > (atmega128L drauf) am XTAL1 und XTAL2 schon ein Quarzoszillator > vorhanden ist ( 7.3728 MHz ). Aha, endlich wissen wir wenigstens, daß es um einen AVR geht. > So das ich schlussendlich > immer nach 15Perioden der Frequenz 122.88kHz ein Bit ausgeben kann Und warum machste dann den Interrupt nicht gleich mit 8,192kHz? > Per Interrupt kann ich das ja nicht > aufzählen, weil dort der Aufruf bei dieser Frequenz nicht mehr richtig > klappt. Was bisher immer noch nur eine Behauptung von Dir ist, da wir das ja mangels Source-File nicht nachprüfen können. > Hätte da jemand eine Idee wie ich das am Besten lösen könnte? Bin > wirklich sehr, sehr dankbar für eure Hilfe. Ja, ich hätte ne Idee: Informationen liefern. Peter
Ja das Problem ist dass ich die Frequenz von 122.88 kHz am Ausgang OC1A brauche und die 8,192 kHz auf einem anderen Port. 2 verschiedene Timer kann ich nicht verwenden da die Signale genau phasengleich sein müssen. Hier ist mal mein code: #include <avr\io.h> #include <avr\interrupt.h> bool counter = 0; void port_init(void) { DDRB = (1<<PB5); // OC1A als output DDRE = 0xFF; // Alle Ports E als Output definieren PORTE = 0x00; } void timer1_init(void) { TCCR1A = (1<<COM1A0); TCCR1B = (1<<CS10) | (1<<WGM12); TCNT1 = 0; OCR1A = 0x001D; TIMSK = (1<<OCIE1A); } void init_devices(void) { port_init(); timer1_init(); sei(); } ISR(TIMER1_COMPA_vect){ // hier liegt das Problem // bekomme hier ein signal if(counter==15){ // von rund 35kHz und nicht PORTE = 0x01; // die erwarteten 8.192kHz }else if (counter==30){ PORTE = 0x00; counter = 0; } counter++; } int main(void) { init_devices(); while(1); }
Wie weit zählt bei dir eine Variable, die per Definition nur 2 Werte haben kann (bool)?
Der Jitter dem du oben angegeben hast beträgt ca 100ppm. Das ist zwar nicht ganz so gut wie ein Quarz sein kann, aber nicht so arg weit weg davon. Erst recht, wenn das Messgerät auch nicht viel besser sein sollte - besonders wenn das ein DSO ist (=> Abtastproblem). Wenn das korrekt gemessen ist und zu viel ist, dann benötigst du eine präzisere Taktquelle. Daher auch meine Frage, wie genau für dich genau genug ist. Und warum 122880 / 30 = 8192 gelten soll ist für mich nicht nachvollziehbar.
Was ist mit 100ppm genau gemeint? 100ppm entsprechen 1 us/sec. Somit 122.88 kHz entsprechen 8.138 * 10-6. Dass heisst nun diese zeit kann bei 100ppm zwischen 7.138 * 10-6 und 9.138 *10-6 varieren?
Aber ein grosses Problem habe ich immer noch, wenn ich in der ISR den kanal toggle komme ich nicht auf die 122.88kHz wie beim OC1A. Wieso ist das so???
Tanja Hofmann wrote: > Aber ein grosses Problem habe ich immer noch, wenn ich in der ISR den > kanal toggle komme ich nicht auf die 122.88kHz wie beim OC1A. Wieso ist > das so??? Wo ist der code? Du musst auch mit 245,76kHz togglen, damit du eine Frequenz von 122,88kHz erhälst. Außerdem ist der interne Taktgeber recht ungenau (wie schon gesagt).
Tanja Hofmann wrote: > Aber ein grosses Problem habe ich immer noch, wenn ich in der ISR den > kanal toggle komme ich nicht auf die 122.88kHz wie beim OC1A. Wieso ist > das so??? Mensch, Tanja, das haben wir doch vor ein paar Wochen in dem anderen Thread bis zum Erbrechen durchdiskutiert! Ein Interrupt Handler hat zu viel Overhead. Da kommst Du mit Deinem Setup nicht auf die benötigten 245 kHz!!!
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.