Hi, ich habe mal eine richtig naive Anfängerfrage. Ich würde gerne prüfen, ob nun wirklich ein Ausgang geschaltet wurde, möchte also schauen (natürlich kommt noch eine Rückantwort von dem was auch immer Zeugs was angeschlossen ist), ob nun wirklich noch Ausgangssignal an einem Pin ist. Der Code wäre: while(1) { if (PINC & (1 << PC0) ) { PORTA |= (1 << PA0); delay_ms(100); } if (PINC & (1 << PC1) & (PINA & (1 << PA0)) ) { PORTA |= (1 << PA1); } } Ich ahne die Antwort schon irgendwie: Entweder Eingang oder Ausgang... ? Danke! LG, Jens
Ich habe die Frage zwar nur halb verstanden, aber der AVR liest mit PINx den realen Zustand eines Ausgangs-Pins, nicht den Sollzustand. Es ist sogar so, dass ADC-Pins auch bei einem Ausgang den Spannungswert am Pin messen - was bei den typischerweise eher niederohmigen resistiven Touchschreens eine Selbstkalibierung ermöglicht (bei denen der recht variable Spannungsverlust durch die Ausgangstreiber eine wesentliche Rolle spielt).
Gehen tut das schon. Wenn du das Datenblatt gelesen hast, weisst du ja, das das PIN Register den wahren Wert am Eingangspin liest. Ich zitiere mal aus dem ATMega8 Datenblatt: > Independent of the setting of Data Direction bit DDxn, the port pin can be read through the PINxn Register Bit. A. K. schrieb: > dass ADC-Pins auch bei einem Ausgang den Spannungswert am Pin > messen Ich hab nur noch nicht ausprobiert, was passiert wenn man einen Pin liest, für den im DIDR0 Register die digitalen Register abgeschaltet sind.
Danke, A.K., aber meine Frage ist noch viel trivialer: Ist es möglich, den Ausgang eines Pins ohne eine Brücke auf einen anderen Eingangspin zu erfragen? mea culpa
Ist übrignens jetzt ein Atmega16. Port A ist Ausgang, Port C ist Eingang über Dip-Schalter.
Wieso willst du das? Der Ausgang hat den Wert welchen du ihm gibts, es sei den da hängt eine extrem niederohmige Last/Kurzschluss dran, dann wird aber der "reale" Zustand im schlechtestem Falle undefiniert sein da weder eindeutig 0 noch eindeutig 1. Oder traust du dem AVR nicht? --> Anderen Controller nutzen Oder deiner Software nicht? --> Debuggen...
J. W. schrieb: > Danke, A.K., aber meine Frage ist noch viel trivialer: Ist es möglich, > den Ausgang eines Pins ohne eine Brücke auf einen anderen Eingangspin zu > erfragen? mea culpa Exakt das hatte ich doch geschrieben. Es ist kein zweiter Pin nötig. Du kannst direkt den Zustand des Ausgangspins im Input-Register lesen. Nur dass dies bei AVRs wenig Sinn ergibt (vom erwähnten ADC-Fall mal abgesehen). Wichtiger ist das bei Controllern, die ihre Outputs auf Open-Drain konfigurieren können. Und da gibts Dummbeutel, bei denen der Input hirnrissigerweise den Sollzustand an Stelle des realen Zustands wiederspiegelt.
> Exakt das hatte ich doch geschrieben. Es ist kein zweiter Pin nötig. Du > kannst direkt den Zustand des Ausgangspins im Input-Register lesen. Ja, sorry, genau das hatte ich vom Kontroller auch erwartet. Ich checke nur nicht, warum der Code oben nicht funktioniert, vielleicht mal der ganze: #include <avr/io.h> #include <util/delay.h> void delay_ms(uint16_t ms) { for (uint16_t t=0; t<=ms; t++) { _delay_ms(1); } } int main(void) { DDRA = 0xFF; PORTA = 0x00; DDRC &= ~( (1 << DDA0) | (1 << DDA1) | (1 << DDA2) | (1 << DDA3) | (1 << DDA4) | (1 << DDA5) | (1 << DDA6) | (1 << DDA7) ); while(1) { if (PINC & (1 << PC0) ) { PORTA |= (1 << PA0); delay_ms(100); } if ((PINC & (1 << PC1)) & (PINA & (1 << PA0)) ) { PORTA |= (1 << PA1); } } }
Welches Verhalten hast du erwartet und welches Verhalten hast du beobachtet? Was ist an PC0?
An Port A sind LEDs und an C sind Dip-Schalter. Wenn ich Taste eins drücke, dann geht Led1 an. Wenn ich Taste zwei drücke, dann hätte ich erwartet, dass geprüft wird, ob der Ausgang für Led1 geschaltet ist. Weil aber das funktioniert, sprich, Led1 leuchtet, hätte ich erwartet, das nun Led2 leuchtet... tut sie aber nicht...
Ich habe übrigens alles getestet, alle Leds funktionieren und alle Dip-Schalter.
Hi >Ist übrignens jetzt ein Atmega16. Port A ist Ausgang, Port C ist Eingang >über Dip-Schalter. Du hast aber hoffentlich das JTAG-Interface deaktiviert (JTAG-Fuse)? Wenn nicht funktioniert der PortC nur teilweise. MfG Spess
Verdammte scheiße, habe ich gerade auch gesehen, habe die Fuses gelesen, da ist JTAG wieder dabei... hatte ich extra deaktiviert mit Burn-O-Mat, ich dachte das ist dauerhaft, benutze Studio 6. Das kann es sein...
Hi >hatte ich extra deaktiviert mit Burn-O-Mat, >ich dachte das ist dauerhaft,.... Wenn man es richtig macht, ist es auch dauerhaft. MfG Spess
Spess53 schrieb: > Du hast aber hoffentlich das JTAG-Interface deaktiviert (JTAG-Fuse)? > Wenn nicht funktioniert der PortC nur teilweise. Allerdings betrifft das nur PC2-PC5. Hier geht es um PC1.
J. W. schrieb: > Ich habe übrigens alles getestet, alle Leds funktionieren und alle > Dip-Schalter. Die DIPs haben externe Pullups oder -downs? Die internen sind bei dir abgeschaltet.
A. K. schrieb: > J. W. schrieb: >> Die DIPs haben externe Pullups oder -downs? Die internen sind bei dir >> abgeschaltet. Mein Kumpel ist zwar noch im Halbschlaf, aber er meint, die sind Pulldowns. Heißt das aber nicht, das dann sofort Led2 angehen müsste? Bei den internen habe ich nix gefummelt, die müssten doch normalerweise aus sein? Ich lese D9 E1. Wie kann ich denn sehen, ob die internen an sind? Totaler Neuling lässt grüßen...
J. W. schrieb: > if ((PINC & (1 << PC1)) & (PINA & (1 << PA0)) ) { Dieser Code egibt immer nur False, dürfte also wegoptimiert werden. 1 & 2 == 0
AAAAAAAAAAAAAAAHHHHHHHHHH OMG Nicht if ((PINC & (1 << PC1)) & (PINA & (1 << PA0)) ) sondern if ((PINC & (1 << PC1)) && (PINA & (1 << PA0)) ) wie bitter ist das denn... danke für euren Support, ich schäme mich in Grund und Boden
J. W. schrieb: > An Port A sind LEDs und an C sind Dip-Schalter. Wenn ich Taste eins > drücke, dann geht Led1 an. Wenn ich Taste zwei drücke, dann hätte ich > erwartet, dass geprüft wird, ob der Ausgang für Led1 geschaltet ist. > Weil aber das funktioniert, sprich, Led1 leuchtet, hätte ich erwartet, > das nun Led2 leuchtet... tut sie aber nicht... Dann würde ich mal darauf tippen, daß du mit deiner LED soviel Strom ziehst, daß die Spannung am Ausgang nicht über den Wert steigt, den der Eingang braucht, um ein "High" zu sehen. Was hältst du davon, einfach mal die Spannung am Pin bei leuchtender LED zu messen, um festzustellen, ob da wirklich High-Pegel anliegt? Ich gehe mal davon aus, daß das nicht der Fall ist, denn dein Programm sollte ansonsten tatsächlich die von dir beschriebene Funktionalität implementieren. Übrigens: Wenn ich recht habe, bedeutet das implizit, daß du den Ausgang massiv überlastest. Es wäre wohl sinnvoll, intensiv über Notwendigkeit und Wert eines Vorwiderstandes für die LED nachzudenken...
c-hater schrieb: > mal davon aus, daß das nicht der Fall ist, denn dein Programm sollte > ansonsten tatsächlich die von dir beschriebene Funktionalität > implementieren. > Nein, denn: & -> bitweise Verknüpfung && -> logisches UND Wurde aber schon geschrieben. Gruß Bernd
Ich hab mir auch früher mit dem unübersichtlichen Bitgefummel selber oft ins Knie geschossen. Ich benutze es daher nicht mehr. Ich hab mir ne "sbit.h" geschrieben, damit geht es viel einfacher und vor allem leserlicher:
1 | #include "sbit.h" |
2 | |
3 | #define BLUB PIN_A0
|
4 | #define PLOP PIN_C1
|
5 | |
6 | if( BLUB && PLOP ){ |
7 | ...
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.