Forum: Mikrocontroller und Digitale Elektronik Taster als Moduswechsler


von Oldie (Gast)


Lesenswert?

Guten Tag.
Ich möchte einen Taster in meinen Schaltkreis implementieren.
Zu erst mal der bestehende Code
1
#define F_CPU 1000000UL     /* 1MHz */
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
// Defines:
6
#define LED1    (1<<PD5)
7
#define LED2    (1<<PD6)
8
#define Taster1 (1<<PD2) 
9
10
//Variablen für die Zeit
11
volatile unsigned int millisekunden;
12
volatile unsigned int sekunde;
13
volatile unsigned int minute;
14
volatile unsigned int stunde;
15
16
int main(void)
17
{
18
19
  // LED-Pins als Ausgang definieren
20
  DDRD |= LED1 | LED2;
21
  
22
  // LED1 einschalten
23
  PORTD |= LED1;
24
  
25
  
26
  // Timer 1 konfigurieren
27
  TCCR1B = (1<<WGM12);  // CTC Modus
28
  TCCR1B |= (1<<CS11); // Prescaler 8
29
  // ((1000000/8)/1000) = 125
30
  OCR1A = 125-1;
31
  
32
  // Compare Interrupt erlauben
33
  // Compare Interrupt erlauben
34
  TIMSK = (1<<OCIE1A);
35
  
36
  // Global Interrupts aktivieren
37
  sei();
38
  uint8_t isLedBlinking;
39
  
40
    
41
    while( 1 )
42
    {
43
      if( ( stunde == 1 && minute == 3 ) ||
44
      ( stunde == 4 && minute == 10 ) || ( stunde == 5 && minute == 15) ) 
45
      isLedBlinking = 1;  
46
      else
47
      isLedBlinking = 0;
48
      
49
50
      if( isLedBlinking )
51
      {
52
        if( sekunde % 2 == 0 )
53
        PORTD &= LED1;
54
        else
55
        PORTD |= LED2;
56
      }
57
      else
58
      PORTD &= LED1;
59
60
    }      
61
    
62
    
63
  
64
}
65
66
/*
67
Der Compare Interrupt Handler
68
wird aufgerufen, wenn
69
TCNT0 = OCR0A = 125-1
70
ist (125 Schritte), d.h. genau alle 1 ms
71
*/
72
ISR(TIMER1_COMPA_vect)
73
{
74
  millisekunden++;
75
  if(millisekunden == 1000)
76
  {
77
    sekunde++;
78
    millisekunden = 0;
79
    if(sekunde == 60)
80
    {
81
      minute++;
82
      sekunde = 0;
83
    }
84
    if(minute == 60)
85
    {
86
      stunde++;
87
      minute = 0;
88
    }
89
    if(stunde == 24)
90
    {
91
      stunde = 0;
92
    }
93
  }
94
}

Wie man sieht, wird eine LED bei 1h3m, 4h3m, 5h3m sekündlich blinkend 
geschaltet. Ich möchte erreichen, dass ein Taster geschaltet wird, der 
zwischen verschiedenen "Modi" schaltet:
Der Taster betätigt eine Variable (ich weiß, muss entprellt werden).
Wenn taster1 einmal gedrückt == Variable zählt auf 1 hoch.
wenn variable auf 1, dann LED1 blinkt 2 mal und LED2 geht halbstündlich 
in einer minute sekündlich blinkend an.
Wenn taster1 Variable auf 2 (2x gedrückt) LED1 blinkt 3 mal, LED2 geht 
stündlich sekündlich blinkend an.
Wenn taster 1 variable auf 3 (3"") LED1 blinkt 4 mal, LED2 geht 
2stündlich sekündlich an.

Ich hoffe ihr versteht was ich meine, mein problem ist jetzt, wie ich 
das genau anstelle. Ich würde mich über Tipps freuen :-)
Danke!

von Schlumpf (Gast)


Lesenswert?

Oldie schrieb:
> dann LED1 blinkt 2 mal und LED2 geht halbstündlich
> in einer minute sekündlich blinkend an.

Oldie schrieb:
> LED2 geht
> stündlich sekündlich blinkend an.

Oldie schrieb:
> LED2 geht
> 2stündlich sekündlich an.

??????

Oldie schrieb:
> Ich hoffe ihr versteht was ich meine,

Ich befürchte nein...

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Du machst Dir eine Statemachine die Du mit einer Variable durchgehst.
Also Taster einmal gedrückt -> STATE=1, Taster fünfmal gedrückt -> STATE 
= 0 = DEFAULT.
Und je nach aktuellem STATE läßt Du das ganze blinken.

von Oldie (Gast)


Lesenswert?

Okay, ich sehe, es ist schwer zu beschreiben:
Sagen wir, die LEDs sollen einfach nach einer halben Stunde/stündlich 
oder 2 stündlich blinken für eine Minute, je nach status der Variable, 
die durch Tasterdruck definiert wird.
Die Frage ist, wie ich das codemäßig am besten umsetze...

von Oldie (Gast)


Lesenswert?

Ich vermute:
1 . Taster entprellen
2 . Wenn Taster gedrückt: Variable mode = +1
Wenn mode ==1
Led halbstündlich für eine Minute blinken + Led2 2 mal blinken
wenn mode == 2
Led stündlich + Led2 3 mal blinken
Wenn mode == 3
LED alle zwei Stunden eine Minute blinken + Led2 4 mal blinken

überall in jedem fall läuft der timer natürlich

ist das so umsetzbar?
Danke

von m.n. (Gast)


Lesenswert?

Etwas Ähnliches findet sich in der Codesammlung: 
Beitrag "Re: EIN-AUS mit Taster per Interrupt, ATtiny25 o.ä."
Anstatt das PWM-Tastverhältnis zu ändern, muß Du eine Blinkroutine 
schreiben, die dann mit passenden Puls-Pause-Parametern aus einer 
Tabelle 'gefüttert' wird. Ein-/Ausschalten und Entprellen des Tasters 
sind schon vorhanden.

von Karl H. (kbuchegg)


Lesenswert?

Oldie schrieb:
> Ich vermute:
> 1 . Taster entprellen
> 2 . Wenn Taster gedrückt: Variable mode = +1
> Wenn mode ==1
> Led halbstündlich für eine Minute blinken + Led2 2 mal blinken
> wenn mode == 2
> Led stündlich + Led2 3 mal blinken
> Wenn mode == 3
> LED alle zwei Stunden eine Minute blinken + Led2 4 mal blinken

Nein. Das ist eine Beschreibung, wie sich Jugendliche die Welt so 
vorstellen. In einem Atomkraftwerk werden Atome gespalten.
Super ja, nicht unbedingt falsch aber auch nicht sehr hilfreich.

Du hast seit dem letzten mal nichts dazugelernt. Du bist immer noch der 
"mach was für einen gewissen Zeitraum" Philosophie verhaftet.
Was bedeutet denn zb halbstündlich "blinken lassen"?
Es bedeutet, dass du das Blinken einschaltest, wenn die Minuten 0 oder 
30 sind.
1
    wenn mode == 1
2
      wenn minuten == 0 oder minuten == 60
3
        isBlinking = true
4
      andernfalls
5
        isBlinking = false

Aber als erstes brauchst du erst mal eine Tastenerkennung und 
entprellung. Leg dein jetziges Programm zur Seite, such dir im Forum 
Beispiele für Entprellung und arbeite sie durch. Dann schreibst du dein 
eigenes Programm welches die Entprellung benutzt.

Denn bei aller Liebe. Diesmal werde ich dir nicht wieder 90% des Codes 
vorgeben und bei den restlichen 10% muss ich dir 8 mal einsagen, bis du 
es dann endlich hast.

: Bearbeitet durch User
von Oldie (Gast)


Lesenswert?

Karl Heinz schrieb:
> Du hast seit dem letzten mal nichts dazugelernt. Du bist immer noch der
> "mach was für einen gewissen Zeitraum" Philosophie verhaftet.
> Was bedeutet denn zb halbstündlich "blinken lassen"?
> Es bedeutet, dass du das Blinken einschaltest, wenn die Minuten 0 oder
> 30 sind.

"Bei aller Liebe" natürlich habe ich das verstanden, ich bin ja als Kind 
nicht geschlagen worden... Ich wollte es nur erstmal so simpel wie 
möglich ausdrücken, wie es auch gewünscht wurde.

von Oldie (Gast)


Lesenswert?

Ich hätte eine Frage:
ich möchte einfach nur, dass wenn ich den Taster drücke, LED2 
leuchtet...
Sobald Taster nicht mehr gedrückt (ergo keine Verbindung mehr zu Masse), 
soll die LED2 aufhören zu leuchten.

LED1 exisitiert in dem Schaltkreis nicht mehr.
Entprellen kann man hier denke ich erstmal vernachlässigen, oder?
Ich danke wie folgt:
1
 
2
#define LED2    (1<<PD6)
3
int main(void) 
4
{
5
DDRD &= ~(1 << PINB2); // Input definieren
6
PORTD |= 1 << PINB2; 
7
DDRD |= LED2;
8
9
while (1)
10
{
11
if (bit_is_clear(PIND, 2)
12
{ PORTD |= LED2; }
13
}
14
}

Problem: es passiert nichts.. Lässt sich compilen, aber wenn ich dann 
den Taster drücke, passiert nichts

von Uwe (de0508)


Lesenswert?

Hallo,

in der main fehlt eine klammer "}".

Schreibe das man etwas anders und überlege Dir bitte warum:
1
PORTD |= (1 << PINB2);

von Oldie (Gast)


Lesenswert?

Uwe S. schrieb:
> PORTD |= (1 << PINB2);

Also das sagt ja, dass am PortD der PinB2 high voltage geschaltet wird 
(5V) und wenn der Button dann (folgender Code) mit Masse verbindet, wird 
ereignis ausgelöst, oder nicht?

von Oldie (Gast)


Lesenswert?

Oder nicht?ß??????????

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.