Hauptmenü

 

Login



 
 

Content

Seiten: [1]   Nach unten
Autor Thema: Internen Oszillator ausschalten  (Gelesen 784 mal)
Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« am: Juli 19, 2010, 18:45:11 »
ZitierenZitat

Guten Tag,

ich benutze derzeit einen PIC18F1320 PIC Microkontroller mit nano-Watt Technologie.
Diese haben ja einen internen Oszillator.

Welche Einstellungen muss ich treffen, damit der interne Oszillator aus ist?

Das Problem ist, dass ich meinen PIC mit einem externen Uhren-Quarz betreiben möchte.
Habe diesen wie gewohnt angeschlossen. Der PIC aber tacktet mit einer anderen Frequenz,
die deutlich schneller ist, als die Frequenz des Uhren-Quarzes.
Das ist doch ein Zeichen dafür, dass die externe Tacktversorgung nicht funktioniert.

Laut Datenblatt http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf sollte diese Einstellung dafür sorgen, dass nur die externe Tacktquelle verwendet wird!

Code:
       #pragma config OSC = EC   //  External Clock on OSC1, OSC2 as FOSC/4 ; CPU= 32768 Hz

        OSCCONbits.IDLEN = 0; // Run mode enabled; CPU core is clocked in Run modes, but not Sleep mode
OSCCONbits.IRCF2 = 1;   // 4MHz Als Test, dass interne Tacktquelle verwendet wird, da zu schnell!
OSCCONbits.IRCF1 = 1;   // ''
OSCCONbits.IRCF0 = 0;   // ''
OSCCONbits.OSTS = 1; // Oscillator Start-up Timer time-out has expired; primary oscillator is running
OSCCONbits.IOFS = 1; // INTOSC frequency is stable
OSCCONbits.SCS1 = 0; // Primary oscillator (Sleep and PRI_IDLE modes)
OSCCONbits.SCS0 = 0;   // ''

Das klappt aber nicht. Kann mir Jemand ein Tipp geben?
« Letzte Änderung: Juli 19, 2010, 18:50:45 von Victor » Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #1 am: Juli 20, 2010, 09:39:25 »
ZitierenZitat

Hallo,

Zitat
#pragma config OSC = EC      //  External Clock on OSC1, OSC2 as FOSC/4 ; CPU= 32768 Hz
Ist das wirklich ein Oszillator ? Die schreibst im Text von Quarz, dann musst du LP als Einstellung in der CONFIG verwenden.

Btw:
Code:

OSCCONbits.OSTS = 1; // Oscillator Start-up Timer time-out has expired; primary oscillator is running
OSCCONbits.IOFS = 1; // INTOSC frequency is stable
kannst du dir sparen, da die Bits ohnehin nur lesbar sind, nicht schreibbar.

Gruß
Stefan
Gespeichert


Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #2 am: Juli 20, 2010, 14:11:14 »
ZitierenZitat

Tut mir Leid, habe mich verschrieben. Bei meiter Tacktquelle handelt es sich um einen
Uhrenquarz.

Danke für den Tipp!
Habe die Einstellung geändert.

Code:
#pragma config OSC = LP

Nun habe ich ein anderes Problem: Der Controller funktioniert beim Einschalten nicht jedes mal richtig.
Mal ist er mit der Frequenz der internen Tacktquelle getacktet, woraufhin er nach einer Sekunde ausgeht.
(Erkennbar durch die blinkende leds)
Manchmal aber (jedes 10 Mal) läuft er einwandfrei mit der richtigen Frequenz.


Hmmm. Seltsam.

Es gibt doch nur das OSCON-Register, um die Tacktquelle einzustellen.
Ein Wackelkontackt kann ich ebenfalls ausschließen.


Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #3 am: Juli 20, 2010, 14:15:24 »
ZitierenZitat

Hier ist das Quellcode

* bin_uhr.c (2.89 KB - runtergeladen 17 Mal.)
Gespeichert

Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 298



Profil anzeigen
« Antworten #4 am: Juli 20, 2010, 18:01:33 »
ZitierenZitat

Hallo Victor,

wie Stampede schon geschrieben hat, sind folgende Zuweisungen unzulässig bzw. unsinnig:

Code:
OSCCONbits.OSTS = 1; // Oscillator Start-up Timer time-out has expired; primary oscillator is running
OSCCONbits.IOFS = 1; // INTOSC frequency is stable

Deine Beschreibung aus dem vorletzten Post passt auch: Weil du nicht wartest, bis die Frequenz stabil anliegt, kommt es nach dem Reset zu unterschiedlichen Taktungen.

Bau das auf Abfragen um (Hinweis: while()Zwinkernd, dann sollte das Problem behoben sein. (Habe mir den Quelltext nicht weiter angesehen)


Grüße,
Edson
Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #5 am: Juli 21, 2010, 14:41:56 »
ZitierenZitat

Habe die Konfiguration geändert:

Code:
        #pragma config OSC = LP    //  CPU= 32768 Hz
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  //  Watchdog Timer
#pragma config LVP = OFF  //  Low Voltage ICSP
#pragma config MCLRE = OFF
#pragma code

        OSCCONbits.IDLEN = 0; // Run mode enabled; CPU core is clocked in Run modes, but not Sleep mode
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 0;
OSCCONbits.SCS1 = 0; // Primary oscillator (Sleep and PRI_IDLE modes)
OSCCONbits.SCS0 = 0;

        // gleich nach der Konfigurtation!
        while(!OSCCONbits.OSTS && !OSCCONbits.IOFS){
Delay1KTCYx(4);
}


Habe eine while-Schleife eingefügt, die dafür sorgen soll, dass der Controller mit der richtigen Frequenz läuft.

Leider hat sich an meinem Problem nichts getan. Der Controller ist manchmal sehrschnell oder genau richtig getacktet.
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #6 am: Juli 21, 2010, 15:50:38 »
ZitierenZitat

Hi,

Schalte mal explizit "Internal External Switchover" und den "Fail Save Monitor" aus (in der CONFIG). Es könnte nämlich sein, dass der Quarz zu lange braucht zum anschwingen, und dann der interne Oszi rettend einspringt. Welche Werte hast du für die Lastkondensatoren am Quarz verwendet?

Gruß
Stefan
Gespeichert


Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #7 am: Juli 21, 2010, 19:54:56 »
ZitierenZitat

Habe die Änderungen vorgenommen:

Code:
/** Configuration ********************************************************/
#pragma config OSC = LP    //  CPU= 32768 Hz
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  //  Watchdog Timer
#pragma config LVP = OFF  //  Low Voltage ICSP
#pragma config MCLRE = OFF
#pragma config IESO = OFF // Internal External Switch Over mode disabled
#pragma config FSCM = OFF // Fail-Safe Clock Monitor disabled
#pragma code

OSCCONbits.IDLEN = 0; // Run mode enabled; CPU core is clocked in Run modes, but not Sleep mode
OSCCONbits.IRCF2 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF0 = 0;
OSCCONbits.SCS1 = 0; // Primary oscillator (Sleep and PRI_IDLE modes)
OSCCONbits.SCS0 = 0;

while(!OSCCONbits.OSTS && !OSCCONbits.IOFS){
Delay1KTCYx(4);
}


Nun ist es so, dass der PIC "stabiler" läuft. Vor der Einstellung lief der Controller mit der internen Frequenz nicht stabil, ging einfach aus.
Jetzt ist es so, dass der Controller oft mit der internen Frequenz startet und ohne abzustürzen läuft.
Ab und zu startet aber dieser auch mit der richtigen Frequenz 32768Hz.

Die Lastkondensatoren am Quarz haben jeweils eine Kapazität von 22pF.
Bin nochmal mit dem Multimesser rangegangen und habe festgestellt, dass die Pins (ohne irgenetwas anzuschließen) OSC1 und OSC2 mit einander verbunden sind. Bei den anderen PICs ist es genauso. Ist das richtig so?
Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #8 am: Juli 23, 2010, 14:55:28 »
ZitierenZitat

Habe den PIC noch paar mal programmiert und siehe da
auf einmal läuft er mit der erwünschten Frequenz (32.768MHz) !!!

Komisch! Ich frage mich warum der PIC nach dem ersten Brennen nicht richtig funktioniert hat.  Unentschlossen

Aber jetzt läuft dieser wie es sein soll.  Lächelnd
Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #9 am: Juli 25, 2010, 20:14:49 »
ZitierenZitat

War ein bischen zuvoreilig!  Verlegen

Der Controller läuft doch nicht mit der erwünschten Freqenz von 32768MHz. (Externer Quarz).

Habe einen Sekundentackt erzeugt: Timer0 als 8-Bit breit definiert und den Vorteiler auf 32 gestellt.
Demnach tacktet der PIC mit einer Frequenz von 8.192Hz. Der Timer0 läuft somit durch den Vorteiler mit einer
Frequenz von 256Hz.
Das heißt Timer0 läut jede Sekunde einmal über und erhöht jedesmal durch einen Interrupt den PORTB um eins.
Habe den PIC so programmiert, dass er wie eine Uhr läuft (0-59 Sek).

Nach ein paar Stunden geht der PIC, gegenüber einer normalen Uhr, eine paar Sekunden nach.
Über die ganze Nacht stimmt die Sekundenanzeige garnicht mehr.

Durch die Tatsache, dass der PIC zu langsamm läuft, glaube ich das dieser durch die interne Tacktquelle getacktet wird (30Hz).
Dabei habe ich doch die interne Tacktquelle (IRCF2:IRCF0: Internal Oscillator Frequency Select bits) so eingestellt, dass der PIC
mit 4MHz läuft.

Habe mir das Datenblatt schon zichmal durchgelesen.
Was habe ich blos für einen PIC erwischt.  Unentschlossen
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #10 am: Juli 26, 2010, 16:27:28 »
ZitierenZitat

Zitat
Was habe ich blos für einen PIC erwischt.
Victor, du hast immer so dubiose Probleme! Wenn man die Dinger richtig bedient, dann machen die auch was man will!

Zitat
Habe einen Sekundentackt erzeugt: Timer0 als 8-Bit breit definiert und den Vorteiler auf 32 gestellt.
Demnach tacktet der PIC mit einer Frequenz von 8.192Hz. Der Timer0 läuft somit durch den Vorteiler mit einer
Frequenz von 256Hz.
Das heißt Timer0 läut jede Sekunde einmal über und erhöht jedesmal durch einen Interrupt den PORTB um eins.
Habe den PIC so programmiert, dass er wie eine Uhr läuft (0-59 Sek).
Soweit alles klar und gut. Die Ungenauigkeit kann entweder durch die ISR (eher unwahrscheinlicht) oder eine grundsätzliche Abweichung des Quarzes hervorgerufen werden. Welche Genauigkeit hat der Quarz? Mal geprüft ob 22pF auch wirklich der optimale Wert ist ? Stell doch mal ISR hier rein, vielleicht ist da auch was faul!

Zitat
Durch die Tatsache, dass der PIC zu langsamm läuft, glaube ich das dieser durch die interne Tacktquelle getacktet wird (30Hz).
Dabei habe ich doch die interne Tacktquelle (IRCF2:IRCF0: Internal Oscillator Frequency Select bits) so eingestellt, dass der PIC
mit 4MHz läuft.
Wenn du das richtig eingestellt hast läuft der PIC auch mit der Quelle die du vorgibst. Bei 31kHz und der entsprechenden Toleranz des RC Oszillators kannst du ja ausrechnen ob das hinkommt...
Zitat
Habe mir das Datenblatt schon zichmal durchgelesen.
Das ist schon mal gut! Smiley Manche Leute verzichten gerne dadrauf, und wundern sich warum nix klappt.

Gruß
Stefan
Gespeichert


Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 298



Profil anzeigen
« Antworten #11 am: Juli 26, 2010, 20:11:04 »
ZitierenZitat

Hallo,

@Victor

wo genau hast du eigentlich den Uhrenquarz angeschlossen, an OSC1:2 oder T1OSO/T1OSI ?


Grüße,
Edson
Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #12 am: Juli 28, 2010, 13:40:59 »
ZitierenZitat

Den Uhrenquarz habe ich wie gewohnt an OSC1:2 angeschlossen.
Hoffe es ist richtig so!

An dem Uhrenquarz kann es eigentlich nicht liegen. Habe mit dem gleichen Uhrenquarz auch einen anderen PIC getacktet (16F628A).
Dabei habe ich auch die selben Kondensatoren verwendet: 22pF.


Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #13 am: Juli 29, 2010, 15:30:59 »
ZitierenZitat

So langsam glaube ich, dass  das Problem an der Interrupt-Routiene liegt!

Und zwar habe ich bis jetzt die ISR folgendermaßen aufgerufen:
Code:
// ================= Interrupt ====================
#pragma code InterruptVector = 0x08
#pragma interrupt InterruptVector

void InterruptVector(void){
sekunde_vergangen=1;
INTCONbits.TMR0IF = 0;
}

In der Hilfdatei unter "Interrupt Vectors " von C18-Compiler habe ich die Interupt-Routiene in einer anderen Form gefunden
und meinen Bedürfnissen angepasst:

Code:
void high_isr(void);

#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
  _asm GOTO high_isr _endasm
}
#pragma code /* return to the default code section */
#pragma interrupt high_isr
void high_isr (void)
{
  sekunde_vergangen=1;
INTCONbits.TMR0IF = 0;
}


Nun lasse ich "Die Uhr" gerade laufen. Bis jetzt scheint die Zeit zu stimmen.

Ob es an der Interrupt-Routiene gelegen hat???
Gespeichert

Victor
Full Member
***
Offline Offline

Beiträge: 107



Profil anzeigen WWW
« Antworten #14 am: August 02, 2010, 16:36:23 »
ZitierenZitat

Vielen Dank für die Unterstützung!

Das Problem war also nicht der interne Oszillator,
sondern eine falsch geschriebene Interrupt-Service-Routiene.

Dass der µC mit der falschen ISR trotzdem gelaufen ist, ist seltsam  Huch
Gespeichert

Seiten: [1]   Nach oben
AntwortenDrucken
 
Gehe zu:  

Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC | Theme Kani By Fussilet

Seite erstellt in 0.149 Sekunden mit 19 Zugriffen.


 
Design by Next Level Design / Script by Joomla!