lpc2148 PLL-Fehler

Gast #1146569
Hallo,
ich hab mir vor kurzem das Olimex-Dev-Board LPC-P2148 zugelegt. Nun hab 
ich mir folgenden PLL-Init-Code zusammengestellt, der aber leider nicht 
funktioniert, da bei meinem Testprogramm (siehe unten) nicht wie 
vorgesehen die LEDs im Sekundentakt, sondern nur etwa alle 5 Sekunden, 
wechseln. Ich schließe daraus, dass der PLL nicht aktiviert wird, kann 
aber leider keinen Fehler in meinem Code finden. Für eure Hilfe bedanke 
ich mich schon einmal im voraus.

PLL-INIT:
1
#define FOSC  12000000
2
#define PLL_M 5
3
#define PLL_P 2
4
#define CCLK  (PLL_M * FOSC)
5

6
void arch_init(void) {
7

8
  // CCLK = FOSC*PLL_M = 12000000*5 = 60000000
9
  PLL0->CFG = (PLL_M-1)|((PLL_P-1)<<5);
10
  // PLL aktivieren
11
  PLL0->CON = 0x01;
12
  PLL0->FEED = 0xAA;  //PLL Feed-Sequenz
13
  PLL0->FEED = 0x55;
14
  // Änderungen werden übernommen
15
  while ( !( PLL0->STAT & PLOCK ) );
16

17
  // PLL aktivieren/mit Taktgeber verbinden
18
  PLL0->CON = 0x03;
19
  PLL0->FEED = 0xAA;  //PLL Feed Sequence
20
  PLL0->FEED = 0x55;
21

22

23
  MAMCR=0x0;
24

25
  #if   CCLK < 20000000
26
    MAMTIM = 1;
27
  #elif CCLK < 40000000
28
    MAMTIM = 2;
29
  #elif CCLK >= 40000000
30
    MAMTIM = 3;
31
  #endif
32

33
  MAMCR=0x2;
34

35

36
  VPBDIV=0x1;
37

38
}


Test-Programm:
1
int main(void) {
2

3
  uin32_t i = 0;
4

5
  arch_init();
6

7
  GPIO0->DIR |= (1<<10);
8
  GPIO0->SET  = (1<<10);
9
  GPIO0->DIR |= (1<<11);
10
  GPIO0->SET  = (1<<11);
11

12
  while(1) {
13
    GPIO0->SET = (1<<11);
14
    GPIO0->CLR = (1<<10);
15
    for(i = 60000000;i>0;i--)
16
      NOP();
17
    GPIO0->SET = (1<<10);
18
    GPIO0->CLR = (1<<11);
19
    for(i = 60000000;i>0;i--)
20
      NOP();
21
  }
22

23
  return 0;
24
}
Woran ist ersichtlich, dass es im Sekundentakt abgehen müsste? Die 
Warteschleifen benötigen garantiert mehr als 1 Takt pro Iteration. Wenn 
NOP exakt ein NOP ist, komme ich auf mindestens 4 Takte (NOP=1, 
Subtraktion=1, Sprung>=2).
Gast
Ok,
ich hab mir nun den Code des Disassamblers heraus geschrieben:
1
 370:  nop      (mov r0,r0)
2
 374:  subs  r3, r3, #1  ; 0x1
3
 378:  bne  370 <main+0x4c>

Demnach dauert das Ganze 3 Takte. Ich hab jetzt die Schleife auf 
20000000 geändert. Die Folge: es dauert ungefähr 1.5s.
Gast
Wenn ich hingegen i=12000000 (der Takt des Quarzes) eingebe, erfolgt das 
Blinken genau im Sekundentakt. Da dieses Ergebnis aber durch die 
Ausführungszeit der Schleife verfälscht ist, frag ich nun andersrum: wie 
kann ich zuverlässig feststellen ob der PLL funktioniert?
Gast
Ja, ok das die branch-instruction mehr als einen Takt braucht ist klar.
Ich bin nun selbst darauf gekommen wie ich den PLL testen kann:
Ich hab nun einfach ein Timer-Interrupt geschrieben das die LEDs im 
Sekundentakt an- bzw. ausmacht und es funktioniert. Das es mit der 
Schleife nicht funktionieren kann ist mir nun auch klar (man lernt 
immerwieder etwas neues).
Danke für die Hilfe

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.