Forum: Mikrocontroller und Digitale Elektronik C8051F120, 100 MHz Mode


von Peter S. (Gast)


Lesenswert?

Hi,

ich bin mal wieder mit meinem Latein am Ende. Ich benutze bereits seit 
ein paar Wochen meinen F120 erfolgreich im 24,5 MHz Modus (interner 
Oszillator auf full speed). Nun möchte ich per internem PLL auf 100 MHz 
Takten um die volle Leistung aus meinem µC zu bekommen. Doch ich 
scheitere kläglich daran. Ich habe mir die Dokumentation zu dem Thema 
durchgelesen und alle Einstellung wie beschrieben vorgenommen. Nach 
einigen Tests muss ich jedoch feststellen, dass der µC immer an einer 
bestimmten Stelle hängen bleibt.
1
void main()
2
{
3
  // Watchdog timer deaktivieren
4
  //////////////////////////////  
5
  WDTCN = 0xDE;   
6
    WDTCN = 0xAD;
7
8
  //SFR-Page Einstellungen
9
  /////////////////////////
10
  SFRPAGE = 0x0F;
11
    SFRPGCN = 0x00;  //disables automatic paging
12
  
13
  // Porteinstellungen
14
  /////////////////////                  
15
    XBR2 = 0x40; // Ports auf weak pull-up einstellen und cross-bar 
16
                    // aktivieren
17
18
  //Systemclock (100 MHz)
19
  ////////////////////////
20
    OSCICN =  0x83; //interne Oszillatorfrequenz auf 24.5 MHz
21
  while(!(OSCICN & 0x80)); //Wartet bis die Oszillatorfrequenz stimmt
22
  PLL0CN = 0x00; //Systemclock wird für PLL Eingang benutzt
23
  SFRPAGE = 0;
24
  FLSCL = 0x30; //Flash Read Timing auf 100 MHz geändert
25
  SFRPAGE = 0x0F;
26
  PLL0CN = 0x01; //PLL-Power aktivieren
27
  PLL0DIV = 0x01; //Dividiert den Systemclock (24.5 MHz) durch 1
28
  PLL0FLT = 0x01; //Filtereinstellung: 24.5 MHz Eingang, 100 MHz Ausgang
29
  PLL0MUL = 0x04; //24.5 MHz * 4 = 98 MHz
30
  Sleep(1); //Wait at least 5 µs, to provide a fast frequency lock.
31
  PLL0CN = 0x03; //Aktiviert PLL
32
  while(!(PLL0CN & 0x10)); //Warte bis PLL bereit ist
33
  CLKSEL = 0x02; //Als Systemclock wird nun PLL verwendet
34
35
  P04 = false;
36
37
        while(1);
38
}

Also die LED auf P04 leuchtet nie. Das Debuggen zeigte mir, dass sich 
nach CLKSEL = 0x02; der µC aufhängt und nichts mehr geht. Nach drücken 
auf Halt im Keil µVision 3.23 stürzt das Programm (Keil) ab und ich muss 
es neu starten.

Aber warum, ich habe mir alles mehrmals durchgesehen und laut 
Dokumentation müsste es so stimmen. Ich bin absolut ratlos was ich 
übersehen haben könnte bzw. falsch eingestellt haben könnte?!

Hat schonmal jemand hier den F120iger oder einen ähnlichen µC mit 100 
MHz und PLL betrieben und könnte hier seinen Code/Erfahrungen mit mir 
teilen? Bzw. hat sonst jemand eine Idee, was ich falsch gemacht haben 
könnte?

Vielen Dank für eure Hilfe!

PS: Sleep() ist eine Funktion, die eine gewisse Anzahl an Millisekunden 
wartet (abhängig vom übergebenen Wert).

von AKKS (Gast)


Lesenswert?

Hallo,

1. Lade dir den Silabs Configuration Wizard von der Silabs-Seite runter, 
das nimmt dir viel Arbeit ab. 
http://www.silabs.com/products/mcu/Pages/SoftwareDownloads.aspx

2. P04 und false werden auch definiert? Sonst übersetzt er ja eigentlich 
auch auch nicht.

3. Die Led geht nicht an, und wenn du einen Breakpoint dahin setzt wird 
die Zeile auch nicht erreicht?

Hab gerade keinen Zugriff auf meine Programme, aber prinzipiell geht es.

AKKS

von Ralf (Gast)


Lesenswert?

Hi Peter,

ohne mir jetzt deinen Code genauer angesehen zu haben:
- P04 ist deine eigene Definition des Ports oder ist der Code abgetippt?
- Im SiLabs-Beispiel wird PLL0CN mit 0x01 und 0x02 für die Versorgung 
und das Aktivieren der PLL verodert, du schreibst die Werte direkt. 
Vielleicht liegts daran... Hast du das SiLabs-Beispiel ausprobiert?
- Wenn du den Wechsel auf die PLL auskommentierst, geht dann die LED an?
- Hast du probiert, das Programm einfach zu flashen, dann die 
Stromversorgung zu trennen und wieder anzuschließen? Also ohne 
Debugmodus aus Keil heraus. Geht dann die LED an? Das Problem ist, dass 
die Keil-Implementierung mit dem Debugadapter nicht immer gut 
funktioniert. Ich könnte mir vorstellen, dass der Debugadapter beim 
Umschalten auf 100MHz einfach ein Problem hat...

Ralf

von Peter S. (Gast)


Lesenswert?

Also erstmal danke für eure schnelle Hilfe!

Danke für den Tipp mit dem Configuration Wizard. Hab auch bereits den so 
generierten Code probiert, erfolglos.

P04 spricht direkt den Pin4 von Port0 an. Habe ich mir zur Erleichterung 
in die C8051F120.h hineingeschrieben. Ebenso false, true und null.
1
sbit P04  = 0x84;

Ein Breakpoint der bei P04 = false; gesetzt wird wird nicht erreicht.

Verodern ändert nichts.

Wenn ich den Wechsel zu PLL auskommentiere geht die LED an, ja!

Das mit dem flashen funktioniert leider auch nicht...

Ich wusste ehrlich gesagt gar nicht, dass Silabs Beispiel Code zum 
Download anbietet. Hab das jetzt gegooglet und mit der Suche von der 
Silabs Seite versucht zu finden aber ich übersehe das glaub ich 
irgendwie?! Habt ihr nen Link?

von Ralf (Gast)


Angehängte Dateien:

Lesenswert?

> Ich wusste ehrlich gesagt gar nicht, dass Silabs Beispiel Code zum
> Download anbietet. Hab das jetzt gegooglet und mit der Suche von der
> Silabs Seite versucht zu finden aber ich übersehe das glaub ich
> irgendwie?! Habt ihr nen Link?
Die Beispiele sind Bestandteil der IDE, d.h. die musst du runterladen... 
:)
Siehe Anhang...

Ralf

von AKKS (Gast)


Lesenswert?

.
1
OSCICN =  0x83; //interne Oszillatorfrequenz auf 24.5 MHz
2
  while(!(OSCICN & 0x80)); //Wartet bis die Oszillatorfrequenz stimmt

Macht keinen Sinn, oder?

Folgendes sagt das Datenblatt(Das entspricht nicht dem was du 
machst->odern):

Step 1. Ensure that the reference clock to be used (internal or 
external) is running and stable.
Step 2. Set the PLLSRC bit (PLL0CN.2) to select the desired clock source 
for the PLL.
Step 3. Program the Flash read timing bits, FLRT (FLSCL.5–4) to the 
appropriate value for the
new clock rate (see Section “15. Flash Memory” on page 199).
Step 4. Enable power to the PLL by setting PLLPWR (PLL0CN.0) to ‘1’.
Step 5. Program the PLL0DIV register to produce the divided reference 
frequency to the PLL.
Step 6. Program the PLLLP3–0 bits (PLL0FLT.3–0) to the appropriate range 
for the divided
reference frequency.
Step 7. Program the PLLICO1–0 bits (PLL0FLT.5–4) to the appropriate 
range for the PLL output
frequency.
Step 8. Program the PLL0MUL register to the desired clock multiplication 
factor.
Step 9. Wait at least 5 μs, to provide a fast frequency lock.
Step 10. Enable the PLL by setting PLLEN (PLL0CN.1) to ‘1’.
Step 11. Poll PLLLCK (PLL0CN.4) until it changes from ‘0’ to ‘1’.
Step 12. Switch the System Clock source to the PLL using the CLKSEL 
register.

Du setzt erst PLL0CN = 0x01, dann PLL0CN = 0x02, die Reihenfolge lt. 
Datenblatt ist aber anders

von AKKS (Gast)


Lesenswert?

Vergiss was ich geschrieben habe. Mumpitz.

von AKKS (Gast)


Lesenswert?

1
void Oscillator_Init()
2
{
3
    int i = 0;
4
    SFRPAGE   = CONFIG_PAGE;
5
    OSCICN    = 0x83;
6
    CCH0CN    &= ~0x20;
7
    SFRPAGE   = LEGACY_PAGE;
8
    FLSCL     = 0xB0;
9
    SFRPAGE   = CONFIG_PAGE;
10
    CCH0CN    |= 0x20;
11
    PLL0CN    |= 0x01;
12
    PLL0DIV   = 0x01;
13
    PLL0FLT   = 0x01;
14
    PLL0MUL   = 0x04;
15
    for (i = 0; i < 15; i++);  // Wait 5us for initialization
16
    PLL0CN    |= 0x02;
17
    while ((PLL0CN & 0x10) == 0);
18
    CLKSEL    = 0x02;
19
}
Das sagt der Configuration Wizard.

Hast du das so getestet?

von Peter S. (Gast)


Lesenswert?

Ich habe nun das Beispiel von Silabs und den generierten Code vom 
Configuration Wizzard ausprobiert... erfolglos.

Außerdem habe ich, da ich ja momentan die Spannung vom Debugadapter zum 
Versorgen des µC verwende, eine externe Spannungsquelle probiert. Ich 
habe auch die Spannungsversorgung des µCs, die durch eine Zenerdiode auf 
3 V begrenzt war auf 3,6V erhöht. Auch kein Erfolg.

Weiters habe ich auch noch den µC ausgetauscht, ebenfalls erfolglos.

Nun sind mir ehrlich gesagt die Ideen ausgegangen...

von Peter S. (Gast)


Lesenswert?

Ich versuche es nun mit der Silabs IDE anstelle von Keil µVision 3.23. 
Aber scheinbar fehlt bei der IDE der Compiler?!
Woher bekommt man den?

von Peter S. (Gast)


Lesenswert?

Ok dann muss ich wohl zwangsweise auch mit der Silabs IDE den Keil 
Compiler verwenden...

von Bernd N (Gast)


Lesenswert?

>> Ok dann muss ich wohl zwangsweise auch mit der Silabs IDE den Keil
>> Compiler verwenden...

mußt du nicht.

http://www.silabs.com/Support%20Documents/TechnicalDocs/an198.pdf

von Peter S. (Gast)


Lesenswert?

Ok mit dem SDCC Compiler und der Silabs IDE passiert der selbe Fehler. 
Der µC hängt sich beim CLKSEL = 0x02; auf und die IDE verliert die 
Verbindung zum µC.

von Bernd N (Gast)


Lesenswert?

Was ist mit dem Watchdog ? kann nicht sehen wo du den ausschaltest.

Beim SDCC sollte das auch vor dem startup code stehen, siehe SDCC doku.

von Peter S. (Gast)


Lesenswert?

Siehe 1. Post:
1
// Watchdog timer deaktivieren
2
  //////////////////////////////  
3
  WDTCN = 0xDE;   
4
    WDTCN = 0xAD;

von Bernd N (Gast)


Lesenswert?

Da bist du schon mittendrin.

>> Ok mit dem SDCC Compiler und der Silabs IDE passiert der selbe Fehler.

Auszug aus meinem Code... ist zwar ein anderer Typ aber so macht man 
das.
1
uint8_t _sdcc_external_startup ()  {
2
    PCA0MD &= ~0x40;                     // disable watchdog
3
4
....weitere Befehle....
5
    return 0;

Das habe ich nirgendwo gesehen. Denk mal daran was so ein C Compiler 
alles vor "main" so treibt, Stichwort startup code. Der WDT sollte schon 
abgeschaltet sein bevor der startup Code rennt.

von Peter S. (Gast)


Lesenswert?

Ok verstehe.
1
uint8_t _sdcc_external_startup()
2
{
3
   WDTCN = 0xde; // Disable watchdog timer
4
   WDTCN = 0xad;
5
6
   return 0;
7
}

habe ich nun eingefügt. Aber ich bekomme folgenden Error: "syntax error: 
token -> '_sdcc_external_startup' ; column 30".

Laut Dokumentation von SDCC müsste es aber stimmen. Ich benutze SDCC 
2.9.

Was habe ich falsch gemacht?

von Bernd N (Gast)


Lesenswert?

uint8_t mach da mal nen unsigned char draus :-) und dann überlege wo die 
Datentypen definiert sind.

von Peter S. (Gast)


Lesenswert?

Danke für deine Hilfe!

Es funktioniert (unsigned ist jedoch nicht notwendig da char sowieso 
unsigned ist). Ich bin davon ausgegangen, dass er _sdcc_external_startup 
nicht kennt, da das ja in der Fehlermeldung steht und nicht uint8_t.

Das Problem besteht aber weiterhin. Der µC stürzt ab sobald man in 100 
MHz Mode wechselt.

Ich bin ab heute leider eine Woche nicht zu hause. Kann also ersten 
morgen in einer Woche auf eure Antworten antworten. Danke für euer 
Verständnis!

von Bernd N (Gast)


Lesenswert?

http://www.silabs.com/support/forums/Pages/default.aspx

gerade gefunden, schaus dir mal an.

von Bernd N (Gast)


Lesenswert?

mh, konnte nicht verlinken, hier der Inhalt:

You are using SiLabs Config 2 utility, but it seems an very old version.
Get a new version, and it generates better code for the OSC-PLL setting.

SiLabs Software Downloads page

https://www.silabs.com/products/mcu/Pages/SoftwareDownloads.aspx

Schau doch mal bei Silabs im Forum.

von Ralf (Gast)


Lesenswert?

Wie ich in deinem anderen Post erwähnt hatte, ist die Generierung der 
Versorgungsspannung mittels Z-Diode für einen Controller unüblich. 
Vielleicht solltest du wenigstens probeweise einfach mal zwei Batterien 
in Reihe anschließen, und schauen ob's dann geht.

Ralf

von Peter S. (Gast)


Lesenswert?

Ok ich weis nun woran es liegt. In den Beispiel von Silabs steht, dass 
man die Versorgung ordentlich entkoppeln soll wenn man den 100 MHz modus 
benutzt ansonsten resetet der µC sobald CLKSEL gesetzt wird ^^ Sprich 
genau das Problem, das ich habe. Habe ich leider erst jetzt gelesen -.-

Ich muss noch auf die entsprechenden Kondensatoren warten, aber sobald 
ich es getestet habe werde ich euch darüber berichten.

Danke nochmal für eure Unterstützung!

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.