Hallo zusammen, ich habe ein kleines Programm für einen PIC 16F84A geschrieben in C. Das soll mir einfach ein Rechteckimpuls mit der Frequenz 125 KHz erzeugen. Leider erreiche ich laut Oscar nur 16,66 KHz. Ausserdem ist die Ration nicht ganz 50:50, der Low-Bereich ist ein wenig kürzer als der High-Bereich. Kann mir jemand einen Tip geben woran das liegen mag? Danke schonmal. Tobias
> Unsymmetrisches Signal
Statt
1 | if(RB1 == 0) |
2 | RB1 = 1; |
3 | else if(RB1 == 1) |
4 | RB1 = 0; |
schon mal
1 | RB1 ^= 1; |
benutzt, um den Portpin zu toggeln? > Frequenz 1/ Oszilloskop richtig kalibriert, Timebase richtig eingestellt und korrekt abgelesen? 2/ Mit welchem Takt läuft der PIC? Reicht die Rechenleistung bei dieser Taktrate für 125 kHz aus? Das Aufrufen der Interruptroutine und die Abarbeitung benötigt Rechenzeit. Die maximal mögliche Togglefequenz bei gegebener Taktrate könntest du herausfinden, indem du den Timer mal weglässt und die Hauptschleife so machst:
1 | while (1) |
2 | {
|
3 | RB1 ^= 1; |
4 | }
|
3/ Stimmt der Prescaler und der Vorladewert von TMR0? TMR0 = 255 heisst ja, dass der nächste Timertakt bereits den Overflow-Interrupt auslöst. Im Interrupt kommt dann der Reset auf 255. D.h. du arbeitest zusammen mit dem Prescaler im schnellstmöglichen Interruptbetrieb! Ich schätze Punkt 2/ kneift dich.
Tobias John wrote: > Hallo zusammen, Hallo ;-) > Das soll mir einfach ein Rechteckimpuls mit der Frequenz 125 KHz > erzeugen. Leider erreiche ich laut Oscar nur 16,66 KHz. Viele (alle?) PICs nutzen als Zählertakt nicht die Quarzfrequenz, sondern nur ein Viertel davon. Mach doch mal genauere Angaben bzgl. Quarztakt. > Ausserdem ist die Ration nicht ganz 50:50, der Low-Bereich ist ein wenig > kürzer als der High-Bereich. Das liegt an deinem Code. Für den Low-Bereich wird nur "if RB1 == 0" abgearbeitet; für High "if RB1 == 0" und "if RB1 == 1". Das kannst du aber so lösen indem du schreibst RB1 = ~RB1; Bist du sicher, dass dein Timer rückwärts zählt? Gruß micha
> schon mal >
1 | > RB1 ^= 1; |
2 | >
|
> benutzt, um den Portpin zu toggeln? Werde ich morgen mal versuchen. Was genau macht denn "^" ? > 1/ Oszilloskop richtig kalibriert, Timebase richtig eingestellt und > korrekt abgelesen? auf jeden Fall ;-) > 2/ Mit welchem Takt läuft der PIC? Reicht die Rechenleistung bei dieser > Taktrate für 125 kHz aus? Das Aufrufen der Interruptroutine und die > Abarbeitung benötigt Rechenzeit. > > Die maximal mögliche Togglefequenz bei gegebener Taktrate könntest du > herausfinden, indem du den Timer mal weglässt und die Hauptschleife so > machst: >
1 | > while (1) |
2 | > { |
3 | > RB1 ^= 1; |
4 | > } |
5 | >
|
Das werde ich mal versuchen. Die Rechenleistung sollte durchaus reichen. Der PIC läuft auf 4 MHz. > 3/ Stimmt der Prescaler und der Vorladewert von TMR0? > > TMR0 = 255 heisst ja, dass der nächste Timertakt bereits den > Overflow-Interrupt auslöst. Im Interrupt kommt dann der Reset auf 255. > D.h. du arbeitest zusammen mit dem Prescaler im schnellstmöglichen > Interruptbetrieb! Ich schätze Punkt 2/ kneift dich. Das ist gewollt. Deshalb habe ich auch einen Vorteiler von 1:8 eingestellt. Da der Timer ja auf 1/4 der PIC-Frequenz arbeitet heißt das, dass die Timerfrequenz 1MHz beträgt und damit nach 1/8 von 1 MHz also 125 KHz der Interrupt ausgelöst wird. > Viele (alle?) PICs nutzen als Zählertakt nicht die Quarzfrequenz, > sondern nur ein Viertel davon. > Mach doch mal genauere Angaben bzgl. Quarztakt. Quarz: 4MHz. Daher ist die Timerfrequenz 1/4 4MHz = 1 MHz. > Das liegt an deinem Code. > Für den Low-Bereich wird nur "if RB1 == 0" abgearbeitet; für High "if > RB1 == 0" und "if RB1 == 1". > > Das kannst du aber so lösen indem du schreibst > RB1 = ~RB1; Danke, werd ich gleich mal versuchen. Was macht denn "~" genau? > Bist du sicher, dass dein Timer rückwärts zählt? Nö warum sollte er. Ich habe ja den Vorteiler auf 1:8 gestellt und damit sollte der Timer alle 0,000008 Sek (8µs) den TMR0 incrementieren und somit, da TMR0 auf 255 vorgeladen wird, den Interrupt auslösen. Danke & Gruß, Tobias
Very interesting Beitrag, aber geht das auch in Assembler?
my name is nobody wrote: > Very interesting Beitrag, aber > geht das auch in Assembler? Sicher geht das auch in Assembler. Das Grundprinzip kann ich dir gerne erklären - aber mach doch dazu bitte ein neuen Beitrag auf, denn eigentlich soll hier das oben erläuterte Problem geklärt werden. Gruß, Tobias
>Da der Timer ja auf 1/4 der PIC-Frequenz arbeitet heißt das, dass die >Timerfrequenz 1MHz beträgt und damit nach 1/8 von 1 MHz also 125 KHz der >Interrupt ausgelöst wird. Und der PIC läuft auch nur mit 1MHz. Also 1us pro Befehl. D.h. du hast 8 Befehle um irgendwas mit 125kHz auszugeben. Einige Befehle brauchen aber auch mehr als 1us. Wie bitte schön soll das jemals funktionieren ?
Ich glaube du hast da was falsch verstanden. Der Pic läuft auf 4 MHz. Wie kommst du darauf, dass der Pic nur auf 1 MHz läuft? Der Timer läuft mit 1/4 des Pic-Taktes. D.h. aber nicht, dass der Pic auch auf 1 MHz läuft. Der läuft weiterhin auf 4 MHz. Somit braucht ein Zyklus 25ns. Wo ist dann das Problem? 125 KHz entsprechen einer Periode von 8µs. Somit habe ich 32 Zyklen Zeit für andere Geschichten. Oder verstehe ich da etwas falsch?
Alle 8µs ein Wechsel wären 62,5 kHz.
Tobias John wrote: > Werde ich morgen mal versuchen. Was genau macht denn "^" ? ^ ist das Exklusiv-Oder ... wird vermutlich nicht unbedingt zu dem gewünschten Ergebnis führen. >> Das kannst du aber so lösen indem du schreibst >> RB1 = ~RB1; > Danke, werd ich gleich mal versuchen. > Was macht denn "~" genau? ~ ist eine einfache Negation (Einer-Komplement). >> Bist du sicher, dass dein Timer rückwärts zählt? > Nö warum sollte er. Ich habe ja den Vorteiler auf 1:8 gestellt und damit > sollte der Timer alle 0,000008 Sek (8µs) den TMR0 incrementieren und > somit, da TMR0 auf 255 vorgeladen wird, den Interrupt auslösen. Gut okay, wenns gewollt war ists okay. Was soll denn eig. für Signal rauskommen? Soll eine komplette Schwingung 125kHz sein oder nur der Umschwung von high-low/low-high? Das ist ein Unterschied. Sonst bräuchtest du ja eine Timerfrequenz von 250kHz. Versuch mal, dass Rücksetzen des Timers (auf 0xFF) gleich ganz am Anfang der Interruptroutine zu machen. Gruß micha
> Somit braucht ein Zyklus 25ns. sorry, ich meine 250ns >Was soll denn eig. für Signal rauskommen? >Soll eine komplette Schwingung 125kHz sein oder nur der Umschwung von >high-low/low-high? Das ist ein Unterschied. Sonst bräuchtest du ja eine >Timerfrequenz von 250kHz. Es soll eine komplette Periode mit T=8µs bei rauskommen. D.h. der high-bereich soll 4µs und der low-bereich soll 4µs sein. Aber Dein Hinweis ist glaube ich nicht ganz falsch. Da muss der Interrupt natürlich mit einer Frequenz von 250kHz auslösen. Ich probiere das gleich mal aus. Danke!
Passt vielleicht nich ganz zum Thema, aber trotzdem: Für welche Operation, Negation oder Exclusives-Oder, werden eigentlich mehr Takte benötigt? Noch was: Das Abarbeiten des Interrupts benötigt doch auch in irgendeiner Weise Rechenzeit bzw. eine bestimmte Anzahl an Takten. Müsste man dann nicht einen anderen Vorteiler nehmen (eine größere Auflösung) und das Abarbeiten, des Interrupts auch in den Startwert des Timers mit einbeziehen? (Genau meine ich den ersten Befehl des Interrupts - Timer resetten.) Für das Problem hier ist das vermutlich irrelevant, da hier ein paar Hz mehr oder weniger wohl egal sind. Gruß Michael
Genau, passt nicht ins Thema. Und wie du siehst macht man mit solchen Beiträgen ein ganzes Thema mal eben "platt". Danke! I.ü. haut das mit dem Takterzeugen bei 4MHz wirklich nicht ganz hin. Muss ich mal sehen ob ich nicht anders 125KHz erzeugen kann - ohne Mikrocontroller, was ja auch eigentlich unnötig ist ;-)
Du könntest höchstens nen größeren Controller nehmen und das ganze mit ner Hardware-PWM machen. Die stellst du einmal ein und dann musst du dich im Code nicht wieder drum kümmern.
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.