Frage:
Gibt es ein Problem bei der Verwendung von Verzögerungsfunktionen bei Verwendung eines internen Oszillators in PIC?
Ahmad Hani
2017-01-16 05:49:24 UTC
view on stackexchange narkive permalink

Ich mache ein Projekt, bei dem der Mikrocontroller die Funktionen delay_ms () (Compiler CCS C) verwenden muss, um auf einen bestimmten Zeitraum zu warten.

Ich verwende PIC 16f628A und während das Programm wie in Proteus vorgesehen ausgeführt wurde, lief es ungefähr 85-mal schneller als beim Versuch auf dem Board.

Ich habe mich dafür entschieden, den internen Oszillator auf die minimal mögliche Frequenz (48 kHz) einzustellen, um den Stromverbrauch zu senken, und ich habe angegeben, dass im Assistenten und damit in der .h-Datei die Zeilenverwendungsverzögerung (intern = 48 kHz) angegeben ist.

Was mache ich falsch?

Drei antworten:
SamGibson
2017-01-16 07:21:08 UTC
view on stackexchange narkive permalink

Summary:

Sie müssen OSCF (Bit 3) im PCON -Register in Ihrem Code (dh zur Laufzeit) auf 0 setzen, wenn Sie möchten Der PIC INTOSC (Interner Oszillator) soll mit einer nominalen Frequenz von 48 kHz (tatsächlich irgendwo zwischen 31,4 kHz und 78,62 kHz) anstelle der INTOSC-Standardfrequenz beim Einschalten von 4 MHz betrieben werden.

Details:

Ich habe mich dafür entschieden, den internen Oszillator auf die minimal mögliche Frequenz (48 kHz) einzustellen, um den Stromverbrauch zu senken, und im Assistenten angegeben, dass die .h-Datei die Zeilenverwendungsverzögerung (intern = 48 kHz) aufweist.

Das Problem ist, dass keines der von Ihnen aufgelisteten Dinge die INTOSC -Hardware auf 48 kHz eingestellt hat. Basierend auf Ihren Aussagen geht Ihre Software davon aus, dass die CPU mit 48 kHz betrieben wird, Ihre Hardware jedoch weiterhin mit der Standard-INTOSC-Frequenz von 4 MHz.

Das Programm lief wie beabsichtigt in Proteus, aber es lief ungefähr 85 Mal schneller als das, als ich es auf dem Board ausprobiert habe.

Ja, das erwarte ich.

85 schneller x 48 kHz = 4 MHz (ungefähr)

Dieses Ergebnis deutet darauf hin, dass Ihre MCU tatsächlich noch mit der Standard-INTOSC-Frequenz von 4 MHz ausgeführt wurde.

Der wichtige Punkt ist, dass you diesen PIC nicht so konfigurieren kann, dass er mit 48 kHz von Power-on ausgeführt wird. Wenn Sie die CONFIG BITS (a.k.a. Fuses) auf eine der beiden Varianten der INTOSC-Einstellung einstellen, verwendet die MCU beim Einschalten die interne 4-MHz-Frequenz.

Wenn Sie es dann auf 48 kHz umschalten möchten (möglicherweise zu Beginn Ihres main () , aber möglicherweise an anderer Stelle in Ihrem Code - es liegt an Ihnen zu wählen), setzen Sie OSCF (Bit 3) auf 0 im Register PCON - that bit schaltet die INTOSC-Frequenz von 4 MHz auf 48 kHz (nach einer kurzen Umschaltung) Übergang).

extract from PIC16F628A datasheet showing OSCF bit in PCON register

Weitere Informationen finden Sie in Abschnitt 14.2.8 "BESONDERE FUNKTIONEN: DOPPELGESCHWINDIGKEITS-OSZILLATORMODI" auf Seite 101 des PIC16F628A-Datenblattes.

extract from PIC16F628A datasheet about switching INTOSC speed

Beachten Sie auch, dass im Datenblatt nicht die Genauigkeit des 48-kHz-Takts angegeben ist (dort wird nur die 4-MHz-Taktgenauigkeit angegeben).Die PIC16F628A-Errata zeigen jedoch, dass der 48-kHz-Takt tatsächlich zwischen 31,4 kHz und 78,62 kHz variieren kann.

PIC16F628A errata for INTOSC at 48 kHz

Das war das Problem, vielen Dank, ich sollte hinzufügen, dass es im CCS-Compiler eine Funktion gibt, die verwendet werden kann, ohne die Register zu schreiben (setup_oscillator (OSC_48KHZ);)
william
2017-01-16 06:16:43 UTC
view on stackexchange narkive permalink

Möglicherweise stellen Sie die Uhr nicht richtig ein. Sie können den folgenden Test durchführen:

  1. Führen Sie einen while-Schleifentest durch: während (1) {RB0 = 1; RB0 = 0;} Verwenden Sie ein Oszilloskop, um die Geschwindigkeit zu messen. Jeder Befehl würde 4 Taktzyklen dauern, um ausgeführt zu werden, wenn ich mich richtig erinnere. Wenn die Geschwindigkeit stimmt, bedeutet dies, dass die Uhr kein Problem hat. Andernfalls korrigieren Sie die Uhreinstellung.

  2. Wenn die Uhr stimmt, überprüfen Sie bitte den Code für die Verzögerungsfunktion. Ich habe einen Code angehängt, den ich zuvor für diesen Chip verwendet habe:

  3. ol>

    Ich glaube, ich habe den Quellcode erhalten von: http://www.alternatezone.com/electronics/dds.htm

    delay.c

      / *
     * Verzögerungsfunktionen
     * Siehe delay.h für Details
     * *
     * Stellen Sie sicher, dass dieser Code mit vollständiger Optimierung kompiliert wurde !!!
     * /
    
    #include "delay.h"
    
    Leere
    DelayMs (vorzeichenloses Zeichen)
    {
    #wenn XTAL_FREQ < = 2 MHz
        tun {
            DelayUs (996);
        } while (- cnt);
    #endif
    
    #if XTAL_FREQ > 2MHZ
        vorzeichenloses Zeichen i;
        tun {
            i = 4;
            tun {
                DelayUs (250);
            } während ich);
        } while (- cnt);
    #endif
    }}
     

    delay.h. Bitte beachten Sie, dass Sie den Wert von XTAL_FREQ definieren müssen. In diesem Beispiel ist es 4 MHz

      / *
     * Verzögerungsfunktionen für HI-TECH C auf dem PIC
     * *
     * Funktionen verfügbar:
     * DelayUs (x) Verzögerung der angegebenen Anzahl von Mikrosekunden
     * DelayMs (x) Verzögerung der angegebenen Anzahl von Millisekunden
     * *
     * Beachten Sie, dass es Bereichsgrenzen gibt: x darf 255 nicht überschreiten - für xtal
     * Frequenzen > 12MHz der Bereich für DelayUs ist noch kleiner.
     * Um DelayUs verwenden zu können, muss nur diese Datei eingefügt werden. benutzen
     * DelayMs Sie müssen delay.c in Ihr Projekt aufnehmen.
     * *
     * /
    
    / * Stellen Sie die Kristallfrequenz in der Liste der vordefinierten CPP-Symbole in ein
        HPDPIC oder auf der PICC-Befehlszeile, z.
        picc -DXTAL_FREQ = 4 MHz
    
        oder
        picc -DXTAL_FREQ = 100 kHz
    
        Beachten Sie, dass dies die Quarzfrequenz ist, die der CPU-Takt ist
        geteilt durch 4.
    
     * Stellen Sie sicher, dass dieser Code mit vollständiger Optimierung kompiliert wurde !!!
    
     * /
    
    #ifndef XTAL_FREQ
    #define XTAL_FREQ 4MHZ / * Kristallfrequenz in MHz * /
    #endif
    #MZZ definieren * 1000L / * Anzahl kHz in MHz * /
    #define KHZ * 1 / * Anzahl kHz in kHz * /
    
    #wenn XTAL_FREQ > = 12 MHz
    
    #define DelayUs (x) {unsigned char _dcnt;\.
                  _dcnt = (x) * ((XTAL_FREQ) / (12 MHz));\.
                  while (--_ dcnt! = 0) \
                      fortsetzen;}}
    #sonst
    
    #define DelayUs (x) {unsigned char _dcnt;\.
                  _dcnt = (x) / ((12 MHz) / (XTAL_FREQ)) | 1;\.
                  while (--_ dcnt! = 0) \
                      fortsetzen;}}
    #endif
    
    extern void DelayMs (vorzeichenloses Zeichen);
     
Leider habe ich kein Oszilloskop.
koalo
2017-01-16 06:16:54 UTC
view on stackexchange narkive permalink

Die Verwendung von delay_ms () ist immer wichtig, wenn Sie ein genaues Timing wünschen.Es ist schwierig, ohne Ihren Code zu sehen, aber wahrscheinlich dauert Ihre Verarbeitung zu lange.Ein einfaches Beispiel:

  while (1) {
  delay_ms (100);
  do_some_calculation ();
  toggle_an_led ();
}}
 

Sie denken vielleicht, dass die LED alle 100 ms umschaltet, aber wenn die Berechnung beispielsweise 10 ms dauert, beträgt das Intervall eher 110 ms.Selbst das Umschalten einer LED selbst hat Einfluss auf das Timing.

Wenn Sie also ein genaues Timing wünschen, verwenden Sie lieber einen Hardware-Timer und nicht delay_ms ().

Die Berechnung ist in meinem Code sehr minimal. Setzen Sie buchstäblich nur einen Pin hoch und dann eine Funktion, die Verzögerungs-ms für Minites verwendet. Ich brauche das Timing nicht kritisch, aber zumindest dem beabsichtigten Timing ähnlich, könnte der Mikrocontroller fehlerhaft sein.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...