Mit einem Atmega32 erzeuge ich am Pin OC0 eine PWM mit ca. 100Hz. Aus diversen Gründen muss ich in der High-Zeit der PWM Messungen machen. Und zwar nur dann!
Jetzt die Frage: Wie kann ich den Zustand des Portpins abfragen? Das entsprechende Bit (PB3) im Steuerregister ist ja laut meines Buches und der praktischen Erfahrung gesperrt. Hat da jemand eine Idee?
Mit einem Atmega32 erzeuge ich am Pin OC0 eine PWM mit ca.
100Hz. Aus diversen Gründen muss ich in der High-Zeit der PWM
Messungen machen. Und zwar nur dann!
Jetzt die Frage: Wie kann ich den Zustand des Portpins abfragen?
ich würde den Zustand einfach wie immer über das PIN-Register einlesen, also z. B. mit „in temp, PINB“ plus anschließender Ausmaskierung von Bit 3 etc.
Oder alternativ:
clc
sbrc PINB, PB3
sec
Danach steht der Pinzustand im Carry-Flag und kann mit „rol“ in irgendein Zustands-Queue-Byte geshiftet werden.
Das entsprechende Bit (PB3) im Steuerregister ist ja
laut meines Buches und der praktischen Erfahrung gesperrt.
Was für ein Steuerregister soll das denn sein? Wäre mir neu, dass da was gesperrt ist. Es muss nur DDR auf 1 gesetzt sein (Datenrichtung = „Output“), sonst wird das PWM-Signal zwar erzeugt, aber nicht auf den Pin geroutet.
Also in meinem Buch steht, dass es nicht geht. Und ich habe das auch schon ausprobiert. Das Bit des Ports kann irgendwie nicht aus dem PINB gelesen werden…
Also in meinem Buch steht, dass es nicht geht. Und ich habe
das auch schon ausprobiert. Das Bit des Ports kann irgendwie
nicht aus dem PINB gelesen werden…
Was heißt „irgendwie“? Was bekommst Du denn als Ergebnis beim Lesen zurück? Immer 0 oder immer 1 oder was anderes? Bist Du sicher, dass Dein Testprogramm korrekt ist?
Zitier mal die betreffende Passage im Buch (ist erlaubt; zitieren verstößt nicht gegen das Urheberrecht). Ich kann nicht glauben, dass es unmöglich sein soll, den tatsächlichen Pinzustand über das PIN-Register abzufragen.
In den Betriebsarten „Signalausgaben über Output Compare Timer“ OC0 muss das Richtungsbit im entsprechenden Parallelport (DDB3) auf 1 gesetzt werden, um den Ausgangstreiber durchzuschalten; das entsprechende Datenbit PB3 ist dann wirkungslos.
In den Betriebsarten „Signalausgaben über Output Compare
Timer“ OC0 muss das Richtungsbit im entsprechenden
Parallelport (DDB3) auf 1 gesetzt werden, um den
Ausgangstreiber durchzuschalten;
Richtig. Im Datenblatt von ATMEL:
If one or both of the COM1A1:0 bit are written to one, the OC1A output overrides the normal port functionality of the I/O pin it is connected to. [Es folgt derselbe Satz nochmal mit „B“ statt „A“]. However, note that the Data Direction Register (DDR) bit corresponding to the OC1A or OC1B pin must be set in order to enable the output driver.
das entsprechende Datenbit PB3 ist dann wirkungslos.
Das soll wohl heißen, dass es dann irrelevant ist, ob Du in das Bit für diesen Pin im PORT -Register eine 0 oder eine 1 reinschreibst. Das PORT-Registerbit als solches würde natürlich gelöscht/gesetzt, aber das hätte keinen Einfluss auf den Pin solange die PWM-Erzeugung läuft.
Ich sehe aber nicht, inwiefern das PIN -Register in seiner Funktion dadurch im Geringsten eingeschränkt sein soll (Unterschied zwischen PORT und PIN klar?).
das entsprechende Datenbit PB3 ist dann wirkungslos.
Das soll wohl heißen, dass es dann irrelevant ist, ob Du in
das Bit für diesen Pin im PORT -Register
eine 0 oder eine 1 reinschreibst. Das PORT-Registerbit als
solches würde natürlich gelöscht/gesetzt, aber das hätte
keinen Einfluss auf den Pin solange die PWM-Erzeugung läuft.
Okay, wenn es auf das Schreiben bezogen ist, dann macht das Sinn. Lesen sollte dann also gehen.
Ich sehe aber nicht, inwiefern das PIN -Register in seiner Funktion dadurch im
Geringsten eingeschränkt sein soll (Unterschied zwischen PORT
und PIN klar?).
ääh … also ganz ehrlich. Nach dieser Sache nun ist mir das vielleicht nicht mehr so klar. Außerdem bin ich mit den Atmels echt noch Rookie…Also erzähl mir bitte mal, was Du da weisst
By the way…: Dein Beispiel funktioniert. Hab das nur auf C geschrieben:
das entsprechende Datenbit PB3 ist dann wirkungslos.
Dein Beispiel funktioniert.
Das „kleine Einmaleins“ der Portpins solltest Du aber trotzdem lernen. Es geht so:
Für jeden Port (A, B, C, D) gibt es drei I/O-Register, nämlich DDR, PORT und PIN.
Mit DDR wird die Datenrichtung festgelegt, d. h. ob der Port Output oder Input sein soll. Wenn er Output ist, kannst Du die Ausgangs-Treiberstufe mit PORT auf H oder L schalten. Ist er dagegen Input und Du willst den aktuellen physikalischen Level des Pins wissen, dann musst Du dafür das PIN-Register (nicht PORT!) auslesen. Dadurch wird der Pin „ins Innere“ des Controllers geschaltet. Es steht Dir natürlich frei, PORT zu lesen, aber damit bekämst Du nur ganz doof das Bit zurück, dass Du zuletzt reingeschrieben hast. Umgekehrt kannst Du natürlich auch ein PIN-Bit lesen, wenn der Pin als Output konfiguriert ist. Bei normaler Output-Pin-Funktionalität bekommst Du dann stets dasselbe, das Du auch beim Lesen des PORT-Bits bekommen hättest. Wenn Du allerdings eine PWM generierst und sie über DDR = 1 auch auf den Pin ausgibst, gilt das nicht mehr, weil dann PORT kein Kommando mehr über den Pin hat (sondern der PWM-Generator). PIN funktioniert dagegen weiterhin anstandslos, weil PIN immer funktioniert.
In den Betriebsarten „Signalausgaben über Output Compare
Timer“ OC0 muss das Richtungsbit im entsprechenden
Parallelport (DDB3) auf 1 gesetzt werden, um den
Ausgangstreiber durchzuschalten; das entsprechende Datenbit
PB3 ist dann wirkungslos.
imho fehlen da noch die Abfragen (eine vorher, eine
hinterher), ob die PWM grad ein High oder ein Low ausgeben
will.
Das war nur der Versuch, den Zustand überhaupt in irgendeiner Form abzufragen. Aber auf diese Art und Weise kann ich nun verfahren, um mein zu Anfang genanntes Problem zu lösen.