In Arduino Uno ist mir aufgefallen, dass beim Festlegen einer PIN für die Ausgabe der Standardanfangszustand niedrig ist. Gibt es eine Möglichkeit, den anfänglichen Ausgangszustand auf hoch zu setzen?
Die Pinmode-Dokumentation unterstützt nur input
, input_pullup
und output
. Ich wünschte, es gäbe eine Option für output_pullup
. Wenn ich einen externen 10-kOhm-Pullup-Widerstand um den Ausgangs-PIN lege, hilft es ein wenig, den Anfangszustand in Richtung High zu verschieben.
Wenn es jedoch eine softwarebasierte Lösung gibt (dh den Arduino Uno auf die Standardausgabe auf hoch flashen), wäre dies sehr zu schätzen.
Nichts hindert Sie daran, die Ausgangsregister (PORTx) zu schreiben, bevor Sie die Richtungsregister (DDRx) schreiben. Leider haben die Arduino-Bibliotheksfunktionen ( pinMode
und digitalWrite
) eine Reihe von Nebenwirkungen und können funktionieren oder nicht. (Vielleicht kann jemand, der mit den Arduino-Bibliotheken besser vertraut ist als ich, sagen, ob a digitalWrite
gefolgt von a pinMode
funktioniert.
Eine direkte Registermanipulation kann also das erreichen, was Sie wollen, wenn die Lösung von @ Tom nicht ausreicht (die Lösung von Tom sollte in fast jedem Fall funktionieren). Konsultieren Sie zunächst Seite 77 des ATmega328-Datenblatts und beachten Sie Tabelle 14-1.
Angenommen, ein Pin beginnt mit gelöschten DDR- und PORT-Bits: Es handelt sich um einen Hi-Z-Eingangspin. Setzen Sie das PORT-Bit, der Pin ist jetzt ein Eingang mit einem Pullup. Wenn Sie nun das DDR-Bit setzen, geht der Pin von einem Eingang mit Pullup direkt zu einem Ausgang hoch.
Bearbeiten: Versuchen Sie besser zu verstehen, was mit dem folgenden Code passieren würde, indem Sie Folgendes durchlesen wiring_digital.c
:
// where p is an Arduino pin, x is the corresponding port,
// and n is the corresponding bit
// pin starts with DDRxn == 0, PORTxn == 0
digitalWrite(PINp, HIGH);
// PORTx |= 1<<n, from line 159
// PORTxn == 1, DDRxn == 0: input pullup
pinMode(PINp, OUTPUT)
// DDRx |= 1<<n, from line 56
// PORTxn == 1, DDRxn == 1: output high
Es scheint also, dass ein digitalWrite
vorheriger Anruf pinMode
genau das tut, was Sie wollen. Ignorieren Sie das Durcheinander über die direkte Registermanipulation oben.
Sie können den Hardwarestandard nicht ändern. Es gibt Code, der beim Start ausgeführt wird, den Sie nicht kontrollieren (es gibt zumindest einen Startcode im ROM im Prozessor, und es kann auch einen Bootloader geben, der geändert werden kann, aber für Sie schwer zu ändern ist). Manchmal kann dieser Code Pins auf unerwartete Weise umschalten, während er nach alternativen Startgeräten oder was auch immer sucht. Dies hat mir zu verschiedenen Zeiten in meiner Karriere viele Probleme bereitet, da es von den Siliziumanbietern (Billiganbieter der zweiten Stufe) nicht immer gut dokumentiert ist.
Aus Ihrer Frage geht nicht hervor, ob der Pin, den Sie verwenden möchten, vom Prozessor aktiv niedrig angesteuert wird oder ob er nur einen schwachen Pulldown hat. Wenn es nur ein schwacher Pulldown ist, können Sie ihn mit einem 1k-Pullup überwältigen. Sie können auch die zuvor erwähnten Ideen ausprobieren. Grundsätzlich müssen Sie irgendwie sicherstellen, dass die Daten auf hoch gesetzt sind, BEVOR die Richtung in dem Code ausgegeben wird, über den Sie die Kontrolle haben. Ich weiß nicht viel über Arduino, aber ich habe mich mit solchen Dingen in verschiedenen Mikroprozessoren befasst, und es ist normalerweise möglich, Daten zu setzen, bevor die Richtung eines IO-Pins festgelegt wird. Manchmal setzt dasselbe Bit, das den internen Pullup aktiviert, auch die Daten für die Ausgabe auf 1.
Wenn der Pin durch einen Code, den Sie nicht ändern können, aktiv auf Low gesetzt wird, wird ein Pullup das Problem nicht beheben. Aber Sie können möglicherweise die Dokumentation durchsehen (oder experimentieren) und einen anderen Pin finden, der nach dem Zurücksetzen nicht niedrig ist.
Viel Glück.
Obwohl es nicht genau das ist, wonach Sie gesucht haben, setup()
sollte das Hinzufügen von zusätzlichem Code funktionieren:
void setup() {
pinMode(PINx, OUTPUT); // replace PINx with the pin number
digitalWrite(PINx, HIGH); //makes PINx high almost immediately (few uS)
// rest of code
}
Es gibt kein Problem mit der Durchführung digitaler Schreib- oder Lesevorgänge in void setup(), Sie können alles in tun setup()
, aber es wird nur einmal ausgeführt. Es sei denn, Sie meinen "hoch gehen, die sofortige Leistung wird angelegt", weil Sie außer einem Pullup-Widerstand meiner Meinung nach Pech haben könnten
setup();
ist am Anfang in der Hauptfunktion (auch nach einem versteckten init()
Anruf).setup()
gerufen wurde
krass
setup()
. Wenn der Pin vom Bootloader konfiguriert wird, funktioniert die Lösung übrigens nicht.