mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C8051F120, 100 MHz Mode


Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
void main()
{
  // Watchdog timer deaktivieren
  //////////////////////////////  
  WDTCN = 0xDE;   
    WDTCN = 0xAD;

  //SFR-Page Einstellungen
  /////////////////////////
  SFRPAGE = 0x0F;
    SFRPGCN = 0x00;  //disables automatic paging
  
  // Porteinstellungen
  /////////////////////                  
    XBR2 = 0x40; // Ports auf weak pull-up einstellen und cross-bar 
                    // aktivieren

  //Systemclock (100 MHz)
  ////////////////////////
    OSCICN =  0x83; //interne Oszillatorfrequenz auf 24.5 MHz
  while(!(OSCICN & 0x80)); //Wartet bis die Oszillatorfrequenz stimmt
  PLL0CN = 0x00; //Systemclock wird für PLL Eingang benutzt
  SFRPAGE = 0;
  FLSCL = 0x30; //Flash Read Timing auf 100 MHz geändert
  SFRPAGE = 0x0F;
  PLL0CN = 0x01; //PLL-Power aktivieren
  PLL0DIV = 0x01; //Dividiert den Systemclock (24.5 MHz) durch 1
  PLL0FLT = 0x01; //Filtereinstellung: 24.5 MHz Eingang, 100 MHz Ausgang
  PLL0MUL = 0x04; //24.5 MHz * 4 = 98 MHz
  Sleep(1); //Wait at least 5 µs, to provide a fast frequency lock.
  PLL0CN = 0x03; //Aktiviert PLL
  while(!(PLL0CN & 0x10)); //Warte bis PLL bereit ist
  CLKSEL = 0x02; //Als Systemclock wird nun PLL verwendet

  P04 = false;

        while(1);
}

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).

Autor: AKKS (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/SoftwareD...

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

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
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?

Autor: Ralf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: AKKS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.
OSCICN =  0x83; //interne Oszillatorfrequenz auf 24.5 MHz
  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

Autor: AKKS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vergiss was ich geschrieben habe. Mumpitz.

Autor: AKKS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void Oscillator_Init()
{
    int i = 0;
    SFRPAGE   = CONFIG_PAGE;
    OSCICN    = 0x83;
    CCH0CN    &= ~0x20;
    SFRPAGE   = LEGACY_PAGE;
    FLSCL     = 0xB0;
    SFRPAGE   = CONFIG_PAGE;
    CCH0CN    |= 0x20;
    PLL0CN    |= 0x01;
    PLL0DIV   = 0x01;
    PLL0FLT   = 0x01;
    PLL0MUL   = 0x04;
    for (i = 0; i < 15; i++);  // Wait 5us for initialization
    PLL0CN    |= 0x02;
    while ((PLL0CN & 0x10) == 0);
    CLKSEL    = 0x02;
}
Das sagt der Configuration Wizard.

Hast du das so getestet?

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter S. (Gast)
Datum:

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

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/Technica...

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe 1. Post:
// Watchdog timer deaktivieren
  //////////////////////////////  
  WDTCN = 0xDE;   
    WDTCN = 0xAD;

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
uint8_t _sdcc_external_startup ()  {
    PCA0MD &= ~0x40;                     // disable watchdog

....weitere Befehle....
    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.

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok verstehe.
uint8_t _sdcc_external_startup()
{
   WDTCN = 0xde; // Disable watchdog timer
   WDTCN = 0xad;

   return 0;
}

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?

Autor: Bernd N (Gast)
Datum:

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

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.silabs.com/support/forums/Pages/default.aspx

gerade gefunden, schaus dir mal an.

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/Software...

Schau doch mal bei Silabs im Forum.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.