Hi,
ich habe mir zwei kleine Mikrocontroller Experimentierboards selber
gebaut. Auf dem einen werkelt ein P89LPC935 und auf dem anderen ein
P89LPC936. Der einzige Unterschied zwischen den beiden ist die Größe des
internen Flash. Den Schaltplan dieser Boards habe ich angehängt.
Mein Problem ist nun, dass beide Boards beim Anlegen der
Betriebsspannung nur sporadisch einen sauberen Power-on Reset
durchführen. Ich sage mal in 5/10 Fällen startet der Controller auf
Anhieb und in den anderen Fällen erst, wenn ich den externen Reset
Taster einmal betätige. Laut Datenblatt beinhaltet der Controller eine
interne Power-on Reset Funktion, weshalb es mir momentan etwas unklar
ist, wieso diese nur so unzuverlässig funktioniert.
Ich habe schon getestet wie schnell die Betriebsspannung am Controller
ansteigt, nachdem ich die Spannung per USB oder externem Netzteil
angelegt habe. Die Zeit beträgt gerade mal ~20µs zum Erreichen der
vollen Betriebsspannung von 3,3V.
Ich habe zum Testen mittlerweile schon das simpelste Testprogramm
geschrieben, das mir eingefallen ist:
1 | #include <REG935.H>
| 2 |
| 3 | void main() {
| 4 | // LED Pin P3.0 als Open-Drain konfigurieren
| 5 | P3M1 = 0xFF;
| 6 | P3M2 = 0x01;
| 7 |
| 8 | // LED einschalten
| 9 | P3^0 = 0;
| 10 |
| 11 | // Endlosschleife
| 12 | while (1);
| 13 | }
|
Es wird nichts weiter gemacht, als eine LED eingeschaltet, welche an
P3.0 dranhängt. Dadran sehe ich schön, ob der Code abgearbeitet wurde
oder nicht.
Die Fuses beim Programmieren sind: 1 | UCFG1=0x43
| 2 | Interner RC Oszillator aktiviert
| 3 | Brownout Detect deaktiviert
| 4 | Watchdog Timer deaktiviert
| 5 | Externer Reset PIN (P1.5) aktiviert
| 6 | Watchdog Reset deaktiviert
|
Ein Deaktivieren des externen Reset Pins bringt keine Veränderung an dem
Verhalten.
Die Jumper auf dem Board sind folgendermaßen gesetzt:
2x ISP offen (ISP deaktiviert)
1x ICP geschlossen (ICP deaktiviert)
2x RS232 gesetzt (RS232 an FTDI)
CLOCK_SELECT2 auf 2-3 (P3.0 an LED)
AUX_POWR auf 1-2 (3,3V an Stiftleisten)
PWR_SELECT1 auf 2-3 (3,3V vom Spannungsregler)
Also mir gehen so langsam die Ideen aus wodran es liegen kann, dass der
Einschaltreset nur so sporadisch funktioniert. Vielleicht übersehe ich
ja das Offensichtlichste und merke es nicht mal.
Also ich bin für Vorschläge jeglicher Art offen. :)
Ciao,
Rainer
CLOCK_SELECT1 steht auch auf 2-3 ?
Schon mal versucht beide auf 1-2 zu setzen?
Thomas R. schrieb:
> CLOCK_SELECT1 steht auch auf 2-3 ?
>
> Schon mal versucht beide auf 1-2 zu setzen?
Das hab ich ganz vergessen aufzuzählen. CLOCK_SELECT1 ist nicht gesetzt,
womit kein externer Takt, sei es vom FTDI oder Quarz, an den Controller
geleitet wird. Es geht mir ja gerade dadrum, dass ich den internen
Oszillator verwenden kann.
Die fuses 0x43 sind ok.
> Ich sage mal in 5/10 Fällen startet der Controller auf
> Anhieb und in den anderen Fällen erst, wenn ich den externen Reset
> Taster einmal betätige. Laut Datenblatt beinhaltet der Controller eine
> interne Power-on Reset Funktion, weshalb es mir momentan etwas unklar
> ist, wieso diese nur so unzuverlässig funktioniert
To generate a proper Power-On-Reset (POR), VDD must have dropped
below 0.2V before being powered back up.
Power-cycling without VDD having dropped below 0.2V may result
in incorrect Program Counter values.
Please also see the VPOR specification in LPC935 Datasheet,
DC electrical characteristics. Section 8.15 (Reset)
states that during a power cycle, VDD must fall below VPOR.
Fox Mulder schrieb:
> Die Fuses beim Programmieren sind:UCFG1=0x43
> Interner RC Oszillator aktiviert
> Brownout Detect deaktiviert
> Watchdog Timer deaktiviert
> Externer Reset PIN (P1.5) aktiviert
> Watchdog Reset deaktiviert
Schalte mal den Brownout Reset an.
Bei den AVRs muß man das auch immer machen, wenn zuverlässiger Reset
benötigt wird oder der EEPROM nicht vergeßlich werden darf.
Peter
Thomas R. schrieb:
> To generate a proper Power-On-Reset (POR), VDD must have dropped
> below 0.2V before being powered back up.
> Power-cycling without VDD having dropped below 0.2V may result
> in incorrect Program Counter values.
> Please also see the VPOR specification in LPC935 Datasheet,
> DC electrical characteristics. Section 8.15 (Reset)
> states that during a power cycle, VDD must fall below VPOR.
Ich habe ein paar Sekunden zwischen den Tests gehabt und in der Zeit ist
die Spannung schon wieder auf 0V gegangen. Es sind ja keine großen
Pufferkondensatoren in der Stromversorgung und der Controller braucht
alleine ~10mA. Interessanterweise klappt der Power-on Reset fast immer,
wenn ich zwischen den Versuchen nur so 0,5s vergehen lasse. Das würde ja
dem Errata Sheet dann eher widersprechen.
Peter Dannegger schrieb:
> Schalte mal den Brownout Reset an.
>
> Bei den AVRs muß man das auch immer machen, wenn zuverlässiger Reset
> benötigt wird oder der EEPROM nicht vergeßlich werden darf.
Ich dachte ich hätte das heute Mittag schon versucht gehabt, aber ich
werde es sicherheitshalber morgen noch mal ausprobieren.
Ciao,
Rainer
Also ich habe heute noch mal ein paar Sachen getestet.
Die Fuse für den Brownout zu setzen hat leider keine Änderung
hervorgebracht. Ich habe dann mal noch die Fuse für den Watchdog Timer
Reset gesetzt, welcher ja notfalls einen definierten Reset beim
Überaufen erzeugen sollte. Aber selbst dieser ist nicht passiert. Also
es scheint so, als würde der Controller wirklich in einem total
undefinierten Zustand hängen.
Nun habe ich noch mit der Taktquelle etwas experimentiert und da habe
ich dann doch noch etwas herausgefunden. Wenn ich anstatt des internen
RC Oszillators eine externe Tatkquelle verwende (12MHz vom FTDI Chip),
dann läuft der Controller immer zuverlässig an.
Aber wie kann es denn sein, daß der interne RC Oszillator nicht mehr
richtig funktioniert? Die Controller sind gerade mal ~2-3 Jahre alt und
ich glaube nicht, dass der C-Anteil des Oszillators sich derart
verschlechtert hat, dass er nicht mehr stabil läuft.
Hat noch Jemand eine Idee, was das Problem mit dem internen RC
Oszillator sein könnte?
Ciao,
Rainer
Also der interne RC Oszillator funktioniert problemlos, wenn ich ein
anderes älteres Programm aufspiele. Nur bei meinem momentanen Programm
und seltsamerweise auch bei meinem super-simpel Testprogramm
funktioniert er nicht zuverlässig. Ich kann auf Anhieb aber keine
relevanten Unterschiede finden, die den Oszillator betreffen würden.
Aber ich werde die Tage mal weitersuchen und versuchen das Geheimnis zu
lüften. :)
Ciao,
Rainer
PS: ich bin heute in eine selbstgestellte Falle gelaufen, als ich bei
einem SFR davon ausgegangen bin, dass unbenutzte Bits 0 sind. Der Bug
hat mich über eine Stunde gekostet, weil µVision diese Bits in der
Simulation mit 0 zurückliefert, wärend der Controller tatsächlich aber
eine 1 zurückliefert. ;)
Fox Mulder schrieb:
> PS: ich bin heute in eine selbstgestellte Falle gelaufen, als ich bei
> einem SFR davon ausgegangen bin, dass unbenutzte Bits 0 sind. Der Bug
> hat mich über eine Stunde gekostet, weil µVision diese Bits in der
> Simulation mit 0 zurückliefert, wärend der Controller tatsächlich aber
> eine 1 zurückliefert. ;)
Es kann durchaus sein, daß undefinierte Bits keinen konstanten Zustand
haben. Wenn Dein Programm undefinierte Bits auswertet, ist es kein
Wunder, wenn es nicht richtig funktioniert.
Erst wenn im Datenblatt definitiv steht, daß sie immer 1 sind, dann
darfst Du sie benutzen. Ansonsten mußt Du sie ausmaskieren.
Generell sollte man undefinierte oder unbenötigte Bits nicht auswerten,
also immer ausmaskieren.
Ein beliebter Anfängerfehler ist, zur Tastenabfrage nicht nur den einen
Pin, sondern den ganzen Port zu vergleichen und dabei die restlichen 7
Pins floaten zu lassen. Dann kann man ja gleich Lotto spielen.
Peter
Peter Dannegger schrieb:
> Es kann durchaus sein, daß undefinierte Bits keinen konstanten Zustand
> haben. Wenn Dein Programm undefinierte Bits auswertet, ist es kein
> Wunder, wenn es nicht richtig funktioniert.
> Erst wenn im Datenblatt definitiv steht, daß sie immer 1 sind, dann
> darfst Du sie benutzen. Ansonsten mußt Du sie ausmaskieren.
Grundsätzlich ist mir das auch klar, nur irgendwie habe ich das dort
total übersehen gehabt. Aber das Problem mit den undefinierten Bits hat
leider nichts mit dem Power-on Reset Problem zu tun. Ich wollte es nur
mal nebenbei erwähnen. :)
Ciao,
Rainer
Zeig dochmal das super-simpel Testprogramm, was nicht geht.
Peter
Ich habe das mini Testprogramm eben noch mal neu compiliert und auf zwei
Boards getestet. Das Verhalten ist leider immer noch das Gleiche, wenn
es diesesmal auch häufiger gestartet hatte (~8/10 Starts haben
geklappt).
Hier das Programm: 1 | #include <REG936.H>
| 2 |
| 3 | sbit led_rot = P3^0;
| 4 |
| 5 | void main() {
| 6 | // LED Pin P3.0 als Open-Drain konfigurieren
| 7 | P3M1 = 0xFF;
| 8 | P3M2 = 0x01;
| 9 |
| 10 | // Ser0: Mode=1 REN=1
| 11 | SCON = 0x50;
| 12 |
| 13 | // SMOD=1
| 14 | PCON = 0x80;
| 15 |
| 16 | // Break-detect aktivieren um in den ISP Modus wechseln zu können
| 17 | AUXR1 |= 0x40;
| 18 |
| 19 | // 115200Bps bei 7,3728MHz
| 20 | BRGR0 = 0x30;
| 21 | BRGR1 = 0x00;
| 22 | BRGCON = 0x03;
| 23 |
| 24 | // LED einschalten
| 25 | led_rot = 0;
| 26 |
| 27 | // Endlosschleife
| 28 | while (1);
| 29 | }
|
Die Fuses sind auf 0x43 gesetzt, wodurch nur der externe Reset Pin
aktiviert ist, aber keine weiteren Features. Der Teil für die serielle
Schnittstelle ist nur drin, damit ich per FlashMagic den Controller in
den Bootloader versetzen und neu flashen kann.
Ich habe mal den Quellcode samt der µVision Projektdateien mit
angehängt.
Ciao,
Rainer
Also ich habe das Problem gefunden. :)
Es war etwas tricky, aber nachdem ein älteres Programm immer
funktionierte und das Neue nicht, konnte ich anfangen nach Unterschieden
zu suchen. Am Ende habe ich es auf die Initialisierung des Port 1
eingrenzen können. Sobald ich den Pin P1.0 (RXD) als input-only
definiere, scheint das Board nicht mehr richtig zu starten. Setze ich
den Modus auf quasi-bidirektional funktioniert der Start wieder
problemlos.
Anscheinend wurde dieser Pin direkt nach dem Einschalten manchmal
kurzzeitig als Low-Pegel gelesen, bevor der FTDI Ausgang diesen auf
High-Pegel setzt. Dadurch wurde, in Verbindung mit dem aktivierten
Break-detect Bit, der Bootloader sofort gestartet und das Programm nicht
abgearbeitet. Setze ich den Pin auf quasi-bidirektional scheint der
interne Pull-Up auszureichen, dass der Pin nicht als Low-Pegel gelesen
wird.
Die Lösung ist also, den Pin nicht als input-only zu betreiben, da ich
das Break-detect nicht abschalten will.
Ciao,
Rainer
Fox Mulder schrieb:
> Anscheinend wurde dieser Pin direkt nach dem Einschalten manchmal
> kurzzeitig als Low-Pegel gelesen
Man sollte generell dem Pegel an Eingängen direkt nach dem Einschalten
nicht trauen. Mache ein Delay von einigen ms, bevor Du den Break-Mode
einschaltest.
Sofern es nicht stört, ist das Einschalten des Pullup an den Eingängen
immer eine gute Idee.
Peter
Fox Mulder schrieb:
> Sobald ich den Pin P1.0 (RXD) als input-only
> definiere, scheint das Board nicht mehr richtig zu starten.
Tust Du in Deinem Super-Simpel-Testprogram aber doch gar nicht. Trotzdem
funktioniert es nicht ...?
Gruß
Jobst
Jobst M. schrieb:
> Fox Mulder schrieb:
>> Sobald ich den Pin P1.0 (RXD) als input-only
>> definiere, scheint das Board nicht mehr richtig zu starten.
>
> Tust Du in Deinem Super-Simpel-Testprogram aber doch gar nicht. Trotzdem
> funktioniert es nicht ...?
Das stimmt, das mache ich nicht. Aber der default Betriebsmodus bei den
LPC900 direkt nach dem Einschalten ist für jeden Portpin input-only.
Deshalb hatte auch mein Testprogramm das gleiche Fehlverhalten. Ich
hätte den Modus ändern müssen, damit es richtig startet. ;)
Ciao,
Rainer
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|