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
voidmain()
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
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).
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
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
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
sbitP04=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?
> 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
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
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...
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.
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
....weitereBefehle....
5
return0;
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.
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?
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!
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.
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
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!