Forum: Mikrocontroller und Digitale Elektronik Interrupt anpassen (Rodeo 7 Segment)


von Nino K. (lnino)


Lesenswert?

Hi an alle,

ich habe einen ATmega168 und eine 7 Segment Anzeige. Ich habe den Code 
so geschrieben, dass die 7 Segment Anzeige sich immer im Kreis dreht. 
(Hauptprogramm). Sobald ich einen Button drücke(Interrupt), soll die 7 
Segment Anzeige an jener Stelle stehen bleiben, an welcher Sie beim 
Drücken des Tasters war. Ich gebe einfach jedem Segment eine Zahl und 
speichere es zwischen um es danach wieder korrekt ausgeben zu können.

Soweit funktioniert es auch. Nur stört mich an der Sache, dass nach dem 
der Interrupt passiert ist, wieder an die Stelle in der Main Funktion 
zurückgekehrt wird an welcher abgebrochen wurde. Dies ist völlig normal 
und auch so gedacht. Das ist mir klar. Aber wie kann ich in meinem 
Codebeispiel dies entweder unterbinden, bzw. den Code umschreiben, damit 
man es nicht sieht, oder es einem nicht auffällt.

Beispiel:

Ich drücke den Button an der Stelle des Segments V. Dann merke ich mir 
mit der Variable den Wert des Segments um es später anzuzeigen. Nun wird 
wieder in die Main Funktion gesprungen an die Stelle an welcher 
unterbrochen wurde. Nun wird das Spinning der 7 Segment Anzeige 
fortgesetzt und somit die restlichen Segmente W,X,Y,Z angezeigt bzw. 
fertig gespinnt. Erst jetzt wird das zuvor gespeicherte Segment welches 
per Tastendruck ermittelt wurde angezeigt.

Also lange Rede kurzer Sinn. Die 7 Segment Anzeige soll nach dem Drücken 
des Tasters sich nicht bis zum Ende weiterdrehen, sondern sofort das 
Element anzeigen bei welchem gedrückt wurde.

Ich weiß der Code ist quick and dirty. :-) Aber funktionell.

Danke für Eure Unterstützung.
1
    int main() {
2
3
    DDRC &= ~(1<<PC5); // PC5 to input
4
    PORTC |= (1<<PC5); // pull up resistor
5
6
    PCICR |= (1<<PCIE1);
7
    PCMSK1 |= (1<<PCINT13);
8
9
    sei();
10
  
11
  init_seg();
12
13
    while(1) {
14
  
15
    if (button_count == 0)
16
    {
17
      spinning_left(40);
18
    }
19
    
20
    else if (button_count == 1)
21
    {
22
      display_stopped_line(level_left, 400);
23
    }
24
    }
25
26
 }
27
    ISR(PCINT1_vect) {
28
  
29
  if (debounce(&PINC, PC5))
30
    {  
31
    level_left = spinning_count;
32
    button_count++;
33
  }
34
}
35
36
void spinning_left(int speed) {
37
    spinning_count=0;
38
  segment('U',speed);
39
    spinning_count=1;
40
  segment('V',speed);
41
    spinning_count=2;
42
  segment('W',speed);
43
    spinning_count=3;
44
  segment('X',speed);
45
    spinning_count=4;
46
  segment('Y',speed);
47
    spinning_count=5;
48
  segment('Z',speed);
49
    spinning_count=6;
50
}

von Hubert G. (hubertg)


Lesenswert?

In deiner ISR setzt du ein Bit und beim nächsten Einsprung löscht du es 
wieder.
Im main springst du abhängig ob das Bit gesetzt ist oder nicht in die 
Funktion Anzeige oder Spin.

von Nino K. (lnino)


Lesenswert?

Ist dies ein spezielles Register?

Wie würde das angepasst an meinen Code aussehen?
Ich kann mir das grad nicht vorstellen.

von Hubert G. (hubertg)


Lesenswert?

Du hast nicht den ganzen Code gepostet und nichts kommentiert.
Den Zähler in eine eigene Funktion, bei Tastendruck eine feste Zahl, 
Zähler stoppt, Segmentzuordnung in einer switch -case Funktion in der 
die feste Zahl nicht vorkommt. Anzeige des Segments.
Bei neuerlichem Tastedruck, Bit löschen, Zähler starten.

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.