Forum: Compiler & IDEs Interrupt und Ausgang toggeln


von Georg (Gast)


Lesenswert?

Hallo!

Ich mache meine ersten Schritte mit GCC und C.
Für den Beginn möchte ich einen Ausgang toggeln, wenn ein Eingang 
betätigt wird:
1
// Eingang 1 schaltet das Relais 1 um
2
    if (PINB & (1<<PB0))
3
    {
4
    }
5
    else
6
    {
7
      if (PIND & (1<<PD0))
8
      {
9
        // Relais 1 ausschalten
10
        PORTD &= ~( 1 << PD0 );
11
      }
12
      else
13
      {
14
        // Relais 1 einschalten
15
        PORTD |= ( 1 << PD0 );
16
      }
17
    }


Davon abgesehen das mit mit einer negierung wohl die "else" vermeiden 
könnte:
Ist das so korrekt?

Kann aktuell wegen mangelder Hardware nur Simulieren und scheint zu 
passen.

Teste dann auf einem Atmega32 und Atmega644.

Toggeln unterstützen die Ausgänge ja nicht, oder?

2. Frage:
3 Interrupts wären verfügbar. Viel zu wenig. Ich habe in Summe 16 
Eingänge.
Ist also nur mit einer Schleife möglich und Interrupt eventuell für 3 
Eingänge erstellen?

Danke

Georg!

von npn (Gast)


Lesenswert?

Du hast imme rnur mit PD0 gearbeitet (Eingang und auch Ausgang). Das war 
bestimmt nicht so gedacht :-)

Toggeln kann man auch:
1
PORTD ^= (1 << PD0);

von chris (Gast)


Lesenswert?

Georg schrieb:
> Toggeln unterstützen die Ausgänge ja nicht, oder?

du kannst so togglen:
1
PORTD ^= ( 1 << PD0 );  // toggle PD0

Problem hierbei ist, dass es sich um eine Read-Modify-Write Operation 
handelt. Wenn du also im Hauptprogramm auch noch mit PORTD arbeitest, 
wird es zu Problemen kommen (sehr selten, aber sie werden vorkommen).

Neuere AVRs unterstützen atomares Togglen mit folgender Zuweisung:
1
PIND = ( 1 << PD0 );  // toggle PD0


lg
Chris

von npn (Gast)


Lesenswert?

chris schrieb:
> Neuere AVRs unterstützen atomares Togglen mit folgender Zuweisung:
> PIND = ( 1 << PD0 );  // toggle PD0

Das war mir neu. Ich hab's bis jetzt immer mit "^=" gemacht und hatte 
nie Probleme...
Ab welchen AVR's ist das atomare Toggeln möglich?

von Georg (Gast)


Lesenswert?

Hallo!

Ok, danke für das toggeln. Hatte ich zwar gefunden, aber hatte nicht 
funktioniert. Die Simulation markiert die Zeile, führt die aber nicht 
aus.
Daher dachte ich der Befehl ist nicht korrekt!

@Chris:
Ja, ich weiß was du meinst. Der Ausgang wird von 2 Stellen gesteuert. 
Einmal der Input und einmal (hoffe das ich das hinbekomme) über UDP.

@npn:
Ich hatte zuerst: Lesen des Status des Ausgang und dann schalten.

Ist im Atmel eigentlich eine Entprellfunktion enthalten? Sonst muss ich 
diese auch noch reinbauen.
20ms sollten passen denk ich für einen normalen Taster?

Danke!

Georg

von Karl H. (kbuchegg)


Lesenswert?

Georg schrieb:

> 3 Interrupts wären verfügbar. Viel zu wenig. Ich habe in Summe 16
> Eingänge.

Was hängt an den Eingängen?

Nur weil du einen Eingang hast, bedeutet das ja nicht, dass du dazu 
einen externen Interrupt benötigst. Den brauchst du nur dann, wenn die 
Änderung am Eingangspin so schnell und so kurz erfolgt, dass du Gefahr 
läufst, sie in der Hauptschleife zu verpassen. Da dein µC aber ein paar 
Hunderttausend Befehle pro Sekunde abarbeitet, müssen die Änderungen an 
den Eingaängen dann schon sehr kurz und sehr schell sein, damit das 
passiert.

dein µC arbeitet
1
int main()
2
{
3
  ...
4
5
  while( 1 ) {
6
7
    if( PINB & ( 1 << PB0 ) )
8
      PORTD ^= ( 1 << PD0 );
9
10
    if( PINB & ( 1 << PB1 ) )
11
      PORTD ^= ( 1 << PD1 );
12
13
  }
14
}

so schnell ab, dass du als Mensch praktisch keine Verzögerung wahrnehmen 
kannst, egal wie schnell du auf einen von 2 Tastern drückst. Ganz im 
Gegenteil musst du hier sogar den µC künstlich bremsen
1
int main()
2
{
3
  ...
4
5
  while( 1 ) {
6
7
    if( PINB & ( 1 << PB0 ) )
8
      PORTD ^= ( 1 << PD0 );
9
10
    if( PINB & ( 1 << PB1 ) )
11
      PORTD ^= ( 1 << PD1 );
12
13
14
    _delay_ms( 100 );
15
  }
16
}

damit du vom Blinken noch was siehst. Ob 1, 2 oder 16 Eingänge spielt 
dabei nicht wirklich eine große Rolle. Das ist für deinen µC immer noch 
Kinderspiel.

: Bearbeitet durch User
von Georg (Gast)


Lesenswert?

Hallo Karl Heinz!

Ah, danke!
Wie geschrieben, aus Mangel der Hardware kann ich noch es nicht live 
testen.
Möchte aber etwas vorarbeiten.

An 8 Eingängen sollen Taster Relais schalten.
An 8 Eingängen die Rückmeldung der Relais.

Um kein neues Thema zu starten:
Weiß jemand wie man Ethersex und Atmega Studio zusammen nutzen kann?

Atmega Studio:
Hier schreibe ich die Applikation für den Atmega644. Ist das aber die 
Firmware?

Ethersex:
Hie kompiliere ich ja auch eine hex Datei.

Ich würde das eine ja mit dem anderen überschreiben, oder?

Danke!

Georg

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.