Forum: Mikrocontroller und Digitale Elektronik Pin Change Interrupt beim Attiny2313A


von Reinhard P. (reinhard_p)


Lesenswert?

Hallo,

ich versuche mich seit neuestem mit dem AVR Attiny2313A und habe auch 
schon 2 Projekte zu meiner Zufriedenheit realisieren können. Nun wollte 
ich für meine Modelleisenbahn ein Projekt umsetzen, stoße aber leider 
hier an meine Grenzen.
Folgende Situation gibt es auf der Modelleisenbahn:


--B---//----B---//------------------B---------------//----B---//----R--- 
--
--R---//----R---//------------------R---------------//----R---//----B--- 
--
          S1                    KS                    S2

Wie mann erkennen kann, sind die Polaritäten ganz links und ganz rechts 
vertauscht und würden beim direkten verbinden einen Kurzschluß auslösen. 
Dafür habe ich mir folgendes überlegt: Der Zug fährt z.B von links ein; 
S1 ist potentialfrei am Attiny2313 PINA0 angeschlossen und wechselt von 
H auf L; das startet einen Zähler mit var++; der Zug verläßt S1 und der 
Inhalt von var wird je nach Länge von KS mit z.B 5 multipliziert; der 
Zähler von var läüft mit var-- rückwärts; nun wird mit Hilfe von Relais 
und einem Ausgang des Attiny2313A die Polarität von KS und S2 
umgeschaltet und der ZUG kann ohne Kurzschluß durchfahren.
Das ganze funktioniert, solange ich relativ langsam über die Strecke S1 
fahre, jedoch mit 3/4 bzw. volle Geschwindigkeit nicht mehr. Ich war 
eigentleich immer der Meinung, dass die CPU so schnell ist, dass so 
etwas nicht passieren kann, aber es ist so. Irgendwie habe ich das 
Gefühle, dass die CPU nicht sofort in der Zählerroutine landet, sondern 
irendwo anders rum arbeitet. Somit ist der Zug schon wieder runter von 
S1 bevor der Zähler startet.Jedoch liegt das Problem, wie so oft vor dem 
PC. Hier mal mein Quellcode, bitte nicht steinigen, bin Anfänger!!!

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000UL      // 8 MHz (fuer delay.h)

static int zugfahrt_links=0,zugfahrt_rechts=0;
static unsigned long s1=0,s2=0,ks_links=0,ks_rechts=0;



int main(void)

 {
    DDRA = 0x00;         // Alle Ports von PORTA sind Eingänge
    PINA = 0x03;        // alle Eingänge auf logisch 1
    DDRB |= 0b11100000;  // Port5,PortB6,PortB7 als Ausgang definieren
    PORTB = 0x00;        // PortB alle Ein/Ausgänge auf log 0
    DDRD = 0xff;        // PortD alle Ports sind Ausgänge

                       //  PB5 == s1
           //  PB6 == ks
           //  PB7 ==
    PIND=0x01;
    _delay_ms(4000);     // beim Start einmalig 4 Sekunden warten


    while(1)
      {
  if (PINA == 0x02)
            {
         zugfahrt_links=1;
         s1=0;
         PORTB &= ~_BV(PB5);  // S1 bleibt unverändert
         PORTB &= ~_BV(PB6);  // Kehrschleife bleibt unverändert
         PORTB |= _BV(PB7);   // S2 wird auf S1 Potenzial geschaltet
            }
   if (PINA == 0x01)
            {
               zugfahrt_rechts=1;
         s2=0;
         PORTB &= ~_BV(PB7);  // S2 bleibt unverändert
         PORTB |= _BV(PB6);  // Kehrschleife wird umgeschaltet
         PORTB |= _BV(PB5);   // S1 wird auf S2 Potenzial geschaltet
            }


         while (zugfahrt_links == 1)
            {
        while( PINA == 0x02 )
                 {
         PIND=0x01;       // LED an solange S1 aktiv
         ks_links++;      //so lange ZUg auf s1 hochzählen
                     ks_links=s1*4;  // und Kehrschleife berechnen
      }
         PIND=0x00;                   // LED aus, ks länge ermittelt

   while(ks_links > 0)
                  {
        PIND=0x02;             // LED an solange Zug in KS
              ks_links--;
        if ( ks_links == 0)
          {
            PORTB |= _BV(PB6);   // schalte Kehrschleifenpoten
            PORTB &= ~_BV(PB7);  // schalte S2 Potenzial um
          }
                  }
   PIND=0x00;                  // LED aus, warte aus s2
   while( PINA == 0x01 )      // Zug auf S2
               {
       PORTD=0x01;           // LED an, Kehrschleife gesperrt
       _delay_ms(1000);       // Verzögern wegen Kurzschluß
       PORTB &= ~_BV(PB5);  // S1 auf Start
       PORTB &= ~_BV(PB6);  // Kehrschleife auf Start
       PORTB &= ~_BV(PB7);  // S2 auf Start
             zugfahrt_links=0;     // Variablen zurücksetzen
       s1=0;
       PORTD=0x00;          // LED aus, Kehrschleife frei
       break;               // Schleife verlassen
                   }


            } // Ende while zugfahrt_links=1
       }
    return 0;
 }

Zugfahrt rechts habe ich wegelassen......

Da der Weg mit dem Zähler nicht so richtig funzt, habe ich versucht 
einen Interrupt auzulösen, sobald die Strecke S1 einen Pegelwechsel 
erzeugt. Aber hier gibt es Differenzen im Pinning mit dem im AVR Studio 
4:

GUI Version    4, 19, 0, 730
AVR Simulator    1, 0, 2, 1
ATTINY2313A    1

( mein Compiler avr-gcc (WinAVR 20100110) 4.3.3 )

und dem Datenblatt des Attiny2313A, und zwar speziell beim Pin Change 
Interrupt. Hier gab es wohl beim Attiny2313 nur 8 Ports die den 
Interrupt aulösen konnten, beim Attiny231A sind es 18 Ports. Irgendwie 
blicke ich da nun nicht mehr durch und bitte mal um eure sachkundige 
Hilfe.

Glück auf

Reinhard Pfeiffer

von M. N. (Gast)


Lesenswert?

Hast Du schon etwas über die Entprellung von Tastern gehört/gelesen?
Falls nein, hier ein aktuelles Beispiel :-)
Beitrag "Entprellung von Tastern"

von Reinhard P. (reinhard_p)


Lesenswert?

Hallo,

die Tastenentprellung ist mir schon ein Begriff und ich habe 
hardwareseitig dafür gesorgt, dass die Entprellung gewährleistet ist. 
Gerade bei der Modelleisenbahn ist es von enormer Wichtigkeit, da der 
Rad-Schienenkontakt nicht immer so ist wie er sein soll.
Aber trotzdem Danke für den Denkanstoß.

Glück auf

Reinhard Pfeiffer

von M. N. (Gast)


Lesenswert?

Reinhard P. schrieb:
> die Tastenentprellung ist mir schon ein Begriff und ich habe
> hardwareseitig dafür gesorgt, dass die Entprellung gewährleistet ist.

Gut, dann nehme ich an, dass die Pin-Change-Interrupts ordentlich 
ausgelöst werden, obwohl in Deinem Code nichts davon zu sehen ist. Aber 
sag doch besser, wie Du es gemacht hast.

Um bei der Bahn zu bleiben: aus Deiner Beschreibung verstehe ich nur 
Bahnhof. Den Abkürzungen "B" und "R" würde ich "blau" und "rot" 
zuordnen. "KS" könnte Kurzstrecke sein und "S1" und "S2" sind bekannte 
S-Bahn Linien. Was "Differenzen im Pinning" sein sollen, wer weiß?

Kannst Du vielleicht mit ein bißchen Abstand zu Deinem Problem etwas 
allgemeinverständlicher und ausführlicher formulieren, damit die Sache 
einem nicht Eisenbahner klar wird?

von Reinhard P. (reinhard_p)


Lesenswert?

Hallo,

ich habe eine andere Lösung gefunden, ganz simpel und einfach, ohne 
Zähler, ohne Interrupts, aber mit Attiny2313A. Der braucht nun nur noch 
im richtigen Moment 3 Relais zu schalten und alle sind glücklich.

Danke das du dir die Zeit genommen hast und versucht hast mir zu helfen. 
Falls du noch was über die s1, s2, ks wissen möchtest, lass es mich 
wissen...


Glück auf

Reinhard Pfeiffer

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.