Timing Problem: PIC32MX795F512L; Config Bits

Gast #4573259
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ß
Gast #4573785
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)
Gast #4574087
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren