Forum: Mikrocontroller und Digitale Elektronik Reset beim STM32F7


von Marc V. (marvo)


Lesenswert?

Hallo,

ich habe ein Nucleo-Board F767ZI mit Ethernet im Einsatz. Auf der 
Netzwerk-Schnittstelle läuft ein Kommandointerpreter um Befehle zu 
empfangen und Antworten zu senden.

Nun das Problem: Wenn ich mit der USB-Verbindung zum ST-Link-Modul das 
Programm über CubeMX starte, läuft die Ethernet-Schnittstelle wie sie 
soll. Wenn ich aber ohne USB arbeite, sondern eine externe 
Spannungsquelle anlege, läuft die Ethernet-Schnittstelle nicht hoch 
(Keine Verbindung mit Ping). Dann muss erst der Hardware-Reset-Button 
gedrückt werden, dann funktioniert es.

Ich habe bereits die einfache R-C-Schaltung nach AN2017 auf den NRST 
geschaltet - läuft nicht! Auch die Beschaltung mit einem MAX809 
funktioniert nicht. Ich nehme an, das es darin liegt, dass die externe 
Spannung mit einer Rampe im Bereich von 30ms hochzieht.

Wie bekomme ich einen Sofortstart nach dem Einschalten der 
Spannungsversorgungen ohne Drücken des Reset-Buttons hin, womit auch die 
Netzwerk-Schnittstelle läuft?

Schon mal Danke vorab und noch ein gutes neues Jahr.
Marvo

von m.n. (Gast)


Lesenswert?

Marc V. schrieb:
> Ich nehme an, das es darin liegt, dass die externe
> Spannung mit einer Rampe im Bereich von 30ms hochzieht.

Da baue zu Programmstart eine Warteschleife >= 0,3 s ein, sodaß die 
Initialisierung erst bei stabilen Spannungen erfolgt.

von Frank K. (fchk)


Lesenswert?

Meine Vermutung ist, dass der PHY nicht richtig resettet wird. Bei 
meiner eigenen Hardware ist der RST vom PHY auf einem GPIO des STM. Beim 
Nucleo-Board ist der Reset aber am NRST des STM.

Du könntest prüfen, ob Du nicht SB177 öffnen willst, um dann den RST vom 
PHY mit einem freien GPIO Deiner Wahl und einem Pullup (wichtig! Nicht 
weglassen - da gibts ein Erratum zum PHY) zu verbinden. Dann hast Du den 
nämlich komplett unter Deiner Kontrolle.

Bei meiner Hardware verwende ich einen Schaltregler mit Power Good 
Ausgang, der mit am NRST des STM hängt. Damit ist sichergestellt, dass 
der STM erst startet, wenn die Versorgung stabil ist. Das hätte der 
MAX809 eigentlich auch machen solle, aber vielleicht passte da die 
Schaltschwelle oder Verzögerung oder irgendwas anderes nicht.

fchk

von Marc V. (marvo)


Lesenswert?

m.n. schrieb:
> Da baue zu Programmstart eine Warteschleife >= 0,3 s ein, sodaß die
> Initialisierung erst bei stabilen Spannungen erfolgt.

Erst mal Danke... Einfache Lösung dachte ich, also habe ich ein Delay 
eingebaut:
1
HAL_Init();
2
HAL_Delay(1000);
3
SystemClock_Config();
In ersten Moment schein es zu funktionieren. Die Ethernet-Schnittstelle 
läuft. ABER die Timer scheinen nicht loszulaufen. Ich werde es mir 
genauer anschauen müssen.

von m.n. (Gast)


Lesenswert?

Marc V. schrieb:
> ABER die Timer scheinen nicht loszulaufen. Ich werde es mir
> genauer anschauen müssen.

Die Warteschleife sollte ganz am Anfang stehen bevor irgendein init() 
passiert. Es reichte eine volatile Variable, die meinetwegen bis 
10000000 gezählt wird und nur Zeit schindet.

von Marc V. (marvo)


Lesenswert?

Danke Frank für die Hinweise. Den SB177 hatte ich tatsächlich übersehen, 
aber durch den eingebauten Zeitverzug in der Software ist der wohl nicht 
mehr erforderlich. Ich werde als nächstes das Software-Delay mit dem 
Reset vom MAX809 kombinieren und schauen, ob ich dann einen sauberen 
Start hinbekommen.

von Marc V. (marvo)


Lesenswert?

m.n. schrieb:
> Die Warteschleife sollte ganz am Anfang stehen bevor irgendein init()
> passiert. Es reichte eine volatile Variable, die meinetwegen bis
> 10000000 gezählt wird und nur Zeit schindet.

Genau so ist! Nun läuft das Ethernet und die Timer, wie sie sollen. Ich 
habe keine Beschaltung auf dem Reset.

Folgender Code wurde direkt nach der Variablendeklaration im main() 
eingesetzt:
1
for (Anlaufcounter=0; Anlaufcounter<10000000; Anlaufcounter++){
2
    ; // Macht nix! Abwarten bis Spannung ausgeregelt ist.
3
}
4
SCB_EnableICache();
5
SCB_EnableDCache();
6
HAL_Init();
7
SystemClock_Config();
Global habe ich die Variable angelegt:
1
__IO uint32_t Anlaufcounter=0;

Danke für die Unterstützung!

von uff basse (Gast)


Lesenswert?

Marc V. schrieb:
> Folgender Code wurde direkt nach der Variablendeklaration im main()
> eingesetzt:

Eventuell könnte ein kluger Compiler die leere Schleife weg-
optimieren, je nach Compiler-Flags und mangelnden Restriktionen.
Dann funktioniert's trotzdem nich ....

von Eins N00B (Gast)


Lesenswert?

uff basse schrieb:
> Marc V. schrieb:
>> Folgender Code wurde direkt nach der Variablendeklaration im main()
>> eingesetzt:
>
> Eventuell könnte ein kluger Compiler die leere Schleife weg-
> optimieren, je nach Compiler-Flags und mangelnden Restriktionen.
> Dann funktioniert's trotzdem nich ....

__IO ist ein #define auf volatile, da geht das dann nicht, ohne den 
Standard zu verletzen.

von Eins N00B (Gast)


Lesenswert?

Marc V. schrieb:
> Global habe ich die Variable angelegt:__IO uint32_t Anlaufcounter=0;

Wenn der Compiler das nicht entsprechend optimiert, spart es Flash, die 
Initialisierung wegzulassen. Und ich würde die Variable vermutlich in 
die Funktion verfrachten, zu Programmstart wird der Stack nicht all zu 
voll sein.
Sind aber beides eher so Mikrooptimierungen.

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.