AVR: Ausgang und Eingang?

OP #3108654
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
#3108656
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).
(Firma: matzetronics) #3108657
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.
#3108663
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.
OP #3108668
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);
    }
  }
}
OP #3108675
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...
Gast #3108680
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
OP #3108707
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...
Gast #3108729
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...
#3108770
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
...
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren