Forum: Mikrocontroller und Digitale Elektronik AVR: Ausgang und Eingang?


von J. W. (ontheway)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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).

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von J. W. (ontheway)


Lesenswert?

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

von J. W. (ontheway)


Lesenswert?

Ist übrignens jetzt ein Atmega16. Port A ist Ausgang, Port C ist Eingang 
über Dip-Schalter.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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...

von (prx) A. K. (prx)


Lesenswert?

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.

von J. W. (ontheway)


Lesenswert?

> 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);
    }
  }
}

von (prx) A. K. (prx)


Lesenswert?

Welches Verhalten hast du erwartet und welches Verhalten hast du 
beobachtet? Was ist an PC0?

von J. W. (ontheway)


Lesenswert?

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...

von J. W. (ontheway)


Lesenswert?

Ich habe übrigens alles getestet, alle Leds funktionieren und alle 
Dip-Schalter.

von Spess53 (Gast)


Lesenswert?

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

von J. W. (ontheway)


Lesenswert?

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...

von Spess53 (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von J. W. (ontheway)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

J. W. schrieb:
> if ((PINC & (1 << PC1)) & (PINA & (1 << PA0)) ) {

Dieser Code egibt immer nur False, dürfte also wegoptimiert werden.
1 & 2 == 0

von J. W. (ontheway)


Lesenswert?

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

von c-hater (Gast)


Lesenswert?

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...

von Bernd S. (bernds1)


Lesenswert?

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

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.