Forum: Mikrocontroller und Digitale Elektronik Timing Problem: PIC32MX795F512L; Config Bits


von Picomat (Gast)


Lesenswert?

Hallo,

ich nutze den : PIC32MX795F512L
http://www.microchip.com/wwwproducts/en/PIC32MX795F512L

Ich würde gerne den internen Rast Rc Oszillator nutzen. Es ist auch kein 
externen Quarz angeschlossen.

Ich würde gerne 40 MHz Systemtakt und 40 MHzPeripheral Bus Takt anlegen.

Meine Confi Bits sind die folgenden:
1
#pragma config   FNOSC     = FRCPLL // Fast RC w PLL 8mHz internal rc Osc
2
#pragma config   FPLLIDIV  = DIV_2  // PLL in 8mHz/2 = 4mHz; PLL INPUT Divider
3
#pragma config   FPLLMUL   = MUL_20 // PLL mul 4mHz * 20 = 80mHz 24??
4
#pragma config   FPLLODIV  = DIV_2  // PLL Out 8mHz/2= 40 mHz system frequency osc
5
#pragma config   FPBDIV    = DIV_1  // Peripheral Bus Divisor
6
#pragma config   FCKSM     = CSECME // Clock Switch Enable, FSCM Enabled
7
#pragma config   POSCMOD   = OFF    // Primary osc disabled
8
#pragma config   IESO      = OFF    // Internal/external switch over
9
#pragma config   OSCIOFNC  = OFF    // CLKO Output Signal Active on the OSCO Pin
10
#pragma config   FWDTEN    = OFF    // Watchdog Timer Enable:
11
12
#define SYS_FREQ (40000000L)
13
14
int main() {
15
16
    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
17
    // ...
18
}

Es ergibt sich SYSCLK = 40 MHz (8MHz Crystal / FPLLIDIV * FPLLMUL / 
FPLLODIV) und PBCLK = SYSCLK / FPBDIV) = 40 MHz/1.

Stimmt das alles so?
Habe Datenblätter, Foren, Reference Manual etc. durchgewälzt.

Ich versuche den Systemtakt von 40 MHz jetzt durch eine blinkende LED 
mit Warteroutinen zu verifizieren:
1
void delay_millis(unsigned int n)
2
{
3
    while (n --)
4
    {
5
        int i;
6
            for (i = 0; i < 4000; i++)
7
            asm volatile ("nop");
8
    }
9
}
10
11
// 1s = 1000 * 1ms = 1ms
12
void delay_sec(unsigned int n)
13
{
14
    while (n --)
15
    {
16
        int i;
17
        for (i = 0; i < 1000; i++)
18
            delay_millis(1);
19
    }
20
}

Für 40 MHz ergibt sich jetzt für einen "Tick" 25 ns = 1/40 MHz.
Das bedeutet, dass ich für 1 ms = X * 25 ns eigentlich den Zähler bis 
40.000 runterzählen müßte. Es funktioniert jedoch nur wenn ich den 
Zähler anstatt von 40.000 (ich weiss bei int gibt es einen Überlauf) von 
4000 runterzählen lasse!

Wo genau geht hier der Faktor 10 ein?
Was mache ich falsch?

Danke und Gruß

von Picomat (Gast)


Lesenswert?

Irgendwelche Ideen?

von Schleife (Gast)


Lesenswert?

Das Inkrementieren der Zählvariable und das Überprüfen der 
Abbruchbedingung der for-Schleife braucht eben auch seine Zeit.

von Pics (Gast)


Lesenswert?

1
#define  SYS_FREQ 120000000UL   // 120 Mips
2
3
#define CpuClock   (SYS_FREQ)
4
 #define CountClock (SYS_FREQ / 2)
5
 #define NsPerClock (1000000000 / SYS_FREQ)
6
 #define NsPerCount (1000000000 / CountClock)
7
 #define CountPerUs (CountClock / 1000000)
8
 #define CountPerMs (CountClock / 1000)
9
 #define CountPerS (CountClock)
10
 #define ShortDelayNS(ns) ShortDelayCycles(ns / NsPerClock)
11
 #define DelayDefined(CountCycles, DoSomething)   \
12
 {             \
13
 int countstart = _CP0_GET_COUNT();     \
14
 while ((unsigned int)(_CP0_GET_COUNT() - countstart) < (unsigned int)CountCycles) { \
15
  DoSomething;         \
16
 }             \
17
 }
18
 #define delay_ns(ns) DelayDefined(ns / NsPerCount, {})
19
 #define delay_ns_(ns, something) DelayDefined(ns * NsPerCount, something)
20
 #define delay_us(us) DelayDefined(us * CountPerUs, {})
21
 #define delay_us_(us,something) DelayDefined(us * CountPerUs, something)
22
 #define delay_ms(ms) DelayDefined(ms * CountPerMs, {})
23
 #define delay_ms_(ms,something) DelayDefined(ms * CountPerMs, something)
24
 #define delay_s(s) DelayDefined(s * CountPerS, {})
25
 #define delay_s_(s,something) DelayDefined(s * CountPerS, something)

von Picomat (Gast)


Lesenswert?

Schleife schrieb:
> Das Inkrementieren der Zählvariable und das Überprüfen der
> Abbruchbedingung der for-Schleife braucht eben auch seine Zeit.

Aber das führt doch nicht zum Faktor 10.
Wieviele Takte dauert die Inkrementierung und Überprüfung der 
Abbruchbedingung?

Ist das tatsächlich des Rätsels Lösung?

von Matthias T. (auchmonoabspielbar)


Lesenswert?

Die freie Version der IDE erzeugt meiner Meinung nach sehr schlechten 
Code. Du kannst Dir mal den erzeugten Assembler Code ansehen. Ich wäre 
nicht erstaunt, wenn es so aussieht:

load i
inc
store i
load i
compare
jump conditional
nop
jump

Ein Faktor 10 für die Schleife gegenüber eines einfach NOP halte ich für 
denkbar.

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
Noch kein Account? Hier anmelden.