Forum: Mikrocontroller und Digitale Elektronik Ausgangsbits werden nicht gelöscht


von Julian S. (r4id)


Lesenswert?

Hallo

Ich habe das Problem, dass der gesetzte Ausgang nicht gelöscht werden 
kann.
Der Ausgang bleibt permanent auf High. Am Ausgangspin messe ich 5V.


1
#include <avr/io.h>
2
# define F_CPU 1000000UL
3
#include <util/delay.h>
4
5
int main(void)
6
{
7
  /*Eingänge definieren*/
8
    DDRC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6) | (1<<PC7) ); // Datenrichtungsregister für PORT C setzen (Eingänge)
9
    PORTC |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6) | (1<<PC7); // Datenregister für PORT C setzen (Pull-Up-Widerstände aktivieren)
10
  
11
    DDRB &= ~( (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) ); // Datenrichtungsregister für PORT B setzen (Eingänge)
12
    PORTB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4); // Datenregister für PORT B setzen (Pull-Up-Widerstände aktivieren)
13
  
14
    DDRA &= ~( (1<<PA0) | (1<<PA1) | (1<<PA0) ); // Datenrichtungsregister für PORT A setzen (Eingänge)
15
    PORTA |= (1<<PA0) | (1<<PA1) | (1<<PA2);  // Datenregister für PORT A setzen (Pull-Up-Widerstände aktivieren)
16
17
  /*Ausgänge definieren*/
18
    DDRD |= (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7); // Datenrichtungsregister für PORT D setzen (Ausgänge)
19
    
20
    while(1)
21
    {
22
    PORTD |= (1 << PD0);
23
    _delay_ms(5000);
24
    PORTD &= ~(1 << PD0);
25
26
    }
27
  return 0;
28
}

: Verschoben durch User
von Ch. K. (Gast)


Lesenswert?

probier mal ;)
1
   
2
    while(1)
3
    {
4
    PORTD |= (1 << PD0);
5
    _delay_ms(5000);
6
    PORTD &= ~(1 << PD0);
7
    _delay_ms(5000);
8
    }

von Julian S. (r4id)


Lesenswert?

Okay das funktioniert, aber Warum?

Anderes Bsp.

Warum funktioniert:
1
 while(1)
2
    {
3
  
4
       if ( (PINC & (1<<PC2))) 
5
       {
6
       PORTD |= (1 << PD0);
7
       _delay_ms(2000);
8
       }
9
       if( !(PINC & (1<<PC2)))
10
       {
11
                   PORTD &= ~(1 << PD0);
12
      _delay_ms(2000);
13
       }
14
15
    }

und warum funktioniert folgendes nicht:
1
 while(1)
2
    {
3
  
4
       if ( (PINC & (1<<PC2))) 
5
       {
6
       PORTD |= (1 << PD0);
7
       }
8
       if( !(PINC & (1<<PC2)))
9
       {
10
       PORTD &= ~(1 << PD0);
11
      }
12
13
    }

von Ch. K. (Gast)


Lesenswert?

Julian Sch schrieb:
> Okay das funktioniert, aber Warum?

guck dir einfach an wie lange dein pin auf high und wie lange auf low 
gesetzt ist.  dann siehst du:

- dein pin wird auf high gestellt
- dann wartest 5s -> dein pin bleibt 5 sek auf high
- dein pin wird auf low gestellt
- dein pin wird auf high gestellt -> das low signal lag nur für n paar 
mikro/nano sekunden an
- ...

die frage ist jetzt wie du misst. mit einem multimeter kannst du das 
kurze low signal nicht sehen.  mit einem oszi musst du das richtig 
einstellen damit du diesen kurzen low peak auf n bildschirm hast.


Julian Sch schrieb:
> und warum funktioniert folgendes nicht

bei deinem zweiten beispiel toggelt der pin schnell hin und her... das 
sollte man auf nem oszi eigentlich sehen... also hier auch frage, womit 
misst du?

von Julian S. (r4id)


Lesenswert?

Nunja ich messe mit einem Multimeter an PD0 dauerhaft 5V. Es wird nicht 
zurückgesetzt.

Habe letztes Beispiel an einem Testaufbau laufen. Es wird ein 
Magnetventil angesteuert das wiederum einen Zylinder mit Luftdruck 
ansteuert.
In diesem Zylinder befinden sich 2 Sensoren (Oben und Unten) die die 
Stellung des Kolbens ermitteln.

1. Wenn Sensor_Unten an ist wird Magnetventil angesteuert.
2. Wenn Sensor_Oben an dann wird Magnetventil nicht mehr angesteuert.

1.Schritt klappt und Ventil bleibt dauerhaft angesteuert

von Julian S. (r4id)


Lesenswert?

Hatte einen Fehler drin
So ist es Richtig. Funktioniert aber immer noch nicht
1
while(1)
2
    {
3
  
4
       if ( (PINC & (1<<PC2))) 
5
       {
6
       PORTD |= (1 << PD0);
7
       }
8
       if( (PINC & (1<<PC1)))
9
       {
10
       PORTD &= ~(1 << PD0);
11
      }
12
13
    }

von Ch. K. (Gast)


Lesenswert?

Julian Sch schrieb:
> Hatte einen Fehler drin
> So ist es Richtig. Funktioniert aber immer noch nicht

was misst du bei PC2 und PC1 mit dem multimeter, wenn der kolben oben 
angekommen ist?

von spess53 (Gast)


Lesenswert?

HI

Um welchen AVR handelt es sich überhaupt? Bei den 40-pol. könnte ein 
Teil von Port C durch das JTAG-Interface blockiert sein (PC2..5).

MfG Spess

von Julian S. (r4id)


Lesenswert?

>was misst du bei PC2 und PC1 mit dem multimeter, wenn der kolben oben
>angekommen ist?

Genau er ist oben, und bleibt dort, da der Ausgang nicht abgeschaltet 
wird.


>Um welchen AVR handelt es sich überhaupt? Bei den 40-pol. könnte ein
>Teil von Port C durch das JTAG-Interface blockiert sein (PC2..5).

Atmega324PA, Ausgänge sind am PortD angeschlossen und Eingänge am PortC.
JTAG habe ich über Atmel Studio 6.2 schon deaktiviert (Haken habe ich 
rausgenommen).

von Karl H. (kbuchegg)


Lesenswert?

Julian Sch schrieb:
>>was misst du bei PC2 und PC1 mit dem multimeter, wenn der kolben oben
>>angekommen ist?
>
> Genau er ist oben, und bleibt dort, da der Ausgang nicht abgeschaltet
> wird.
>

So.
Und jetzt mal langsam zum mitschreiben.

Wer (Schalter?) ist wo in welcher Form angeschlossen?

Eine Skizze wär cool.

Denn:
So wie du deinen C-Port initialisierst, sieht es so aus, als ob die 
Endschalter(?) bei Betätigung gegen Masse schalten. Könnte aber auch 
umgekehrt sein.

Daher: Je nachdem, wie du die Schalter verbaut hast und je nachdem, ob 
die öffnen oder schliessen, wenn der Kolben(?) die Endlage erreicht hat, 
muss hier
1
       if ( (PINC & (1<<PC2)))
bei den Abfragen der Endschalter ein ! rein oder auch nicht

Also: wie sind die Endschalter verbaut und was machen sie, wenn das 
bewegliche Teil den Endschalter erreicht? Schliessen sie oder öffnen 
sie?

: Bearbeitet durch User
von Julian S. (r4id)


Lesenswert?

>Daher: Je nachdem, wie du die Schalter verbaut hast und je nachdem, ob
>die öffnen oder schliessen, wenn der Kolben(?) die Endlage erreicht hat,
>muss hier
>       if ( (PINC & (1<<PC2)))
>bei den Abfragen der Endschalter ein ! rein oder auch nicht

Ja du hast Recht. Entschuldigung das habe ich in meinem Code eigentlich 
auch. Habe zwischendruch ein bisschen rumexperimentiert und die ! mal 
rausgenommen.
So sieht die aktuelle Schleife aus, die ebenfalls nicht funktioniert :P
1
while(1)
2
    {
3
  
4
       if ( !(PINC & (1<<PC2))) 
5
       {
6
       PORTD |= (1 << PD0);
7
       }
8
       if( !(PINC & (1<<PC1)))
9
       {
10
       PORTD &= ~(1 << PD0);
11
      }
12
13
    }

Sensor_ausgefahren (oben): PC1
Sensor_eingefahren (unten): PC2
Magentventil: PD0

Wenn PC2=0 ist, also wenn Sensor_eigefahren (unten) ein Signal hat, wird 
PD0 geschalten.
Magentventil gibt Druckluft auf den Zylinder und Kolben fährt aus.
Wenn PC1=0 ist, also wenn Sensor_ausgefahren (oben) ein Signal hat, wird 
der Ausgang PD0 sofort wieder abgeschalten

Die Sensor Eingänge gehen auf Optokoppler die Masse an die Eingangspins 
des µC ziehen.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Schön.
UNd was startet den ganzen Prozess.

Kannst du nicht einfach dein ganzes Programm posten? Die 5 
Programmzeilen
1
#include <avr/io.h>
2
3
int main()
4
{
5
  PORTC |= ( 1 << PC1 ) | ( 1 << PC2 );
6
  DDRD  |= ( 1 << PD0 );
7
8
  PORTD &= ~( 1 << PD0 );
9
10
  while( 1 ) {
11
    if( !( PINC & ( 1 << PC1 ) )
12
      PORTD |= ( 1 << PD0 );
13
    if( !( PINC & ( 1 << PC2 ) )
14
      PORTD &= ~( 1 << PD0 );
15
  }
16
}
sind jetzt wirklich nicht die Welt, um als ganzes per Copy&Paste 
übernommen zu werden, oder ganz einfach als C File angehängt.

Sicher, dass du die Schalter nicht vertauscht hast oder die 
Ventilsteuerunfg genau anders rum funktioniert?

: Bearbeitet durch User
von Julian S. (r4id)


Angehängte Dateien:

Lesenswert?

>Schön.
>UNd was startet den ganzen Prozess.

Die Versorgungsspannung

>Kannst du nicht einfach dein ganzes Programm posten?

Nunja das ist vorerst mein ganzes Programm.
1
#include <avr/io.h>
2
# define F_CPU 1000000UL
3
#include <util/delay.h>
4
5
int main(void)
6
{
7
  /*Eingänge definieren*/
8
    DDRC &= ~( (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6) | (1<<PC7) ); // Datenrichtungsregister für PORT C setzen (Eingänge)
9
    PORTC |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6) | (1<<PC7); // Datenregister für PORT C setzen (Pull-Up-Widerstände aktivieren)
10
  
11
    DDRB &= ~( (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) ); // Datenrichtungsregister für PORT B setzen (Eingänge)
12
    PORTB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4); // Datenregister für PORT B setzen (Pull-Up-Widerstände aktivieren)
13
  
14
    DDRA &= ~( (1<<PA0) | (1<<PA1) | (1<<PA0) ); // Datenrichtungsregister für PORT A setzen (Eingänge)
15
    PORTA |= (1<<PA0) | (1<<PA1) | (1<<PA2);  // Datenregister für PORT A setzen (Pull-Up-Widerstände aktivieren)
16
17
  /*Ausgänge definieren*/
18
    DDRD |= (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7); // Datenrichtungsregister für PORT D setzen (Ausgänge)
19
    
20
   while(1)
21
    {
22
  
23
       if ( !(PINC & (1<<PC2))) 
24
       {
25
         PORTD |= (1 << PD0);
26
       }
27
       if( !(PINC & (1<<PC1)))
28
       {
29
         PORTD &= ~(1 << PD0);
30
      }
31
32
    }
33
  return 0;
34
}


>Sicher, dass du die Schalter nicht vertauscht hast ....

Sehr sicher, da an den Sonsoren LED´s aufleuchten wenn sie schalten und 
ich die Spannung auch messe.

> oder die Ventilsteuerunfg genau anders rum funktioniert?

Bin mir sicher das es funktioniert, da ich sie selber entworfen habe.
Schaltung im Anhang.

: Bearbeitet durch User
von Julian S. (r4id)


Lesenswert?

Neuer Tag Neues Glück,

habe gerade das Programm nochmal probiert und siehe da es geht auf 
einmal.

Trotzdem danke für die Mühe.

von IchGlaubeEsNicht (Gast)


Lesenswert?

>Bin mir sicher das es funktioniert, da ich sie selber entworfen habe.

Diesen Satz werde ich in mein Standard-Repertoire "geniale Antworten" 
übernehmen.

von Julian S. (r4id)


Lesenswert?

>Diesen Satz werde ich in mein Standard-Repertoire "geniale Antworten"
>übernehmen.

:D

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.