Forum: Mikrocontroller und Digitale Elektronik Tastendruck wird nicht erkannt


von Markus N. (k3hlim)


Lesenswert?

Hallo Leute,

ich bin zur Zeit mit µCs am experimentieren und noch ziemlich am Anfang. 
Zur Tastenentprellung habe ich den Code von 
'http://rn-wissen.de/wiki/index.php/Taster-Abfrage_in_C'; verwendet und 
soweit es mein Kentnissstand vermag angepasst.

Die Taster schalten in Abhängigkeit vom Zustand (an/aus) und evtl. noch 
einer weiteren Bedingung Relais über Transitoren.

Wenn ich die Taster über if-Abfragen und _delay-Verzögerung abfrage, 
werden die Ausgänge auch geschaltet, nur mit dem angegebenen Code 
funktioniert nicht alles, soll heißen, case 2 reagiert, der Rest jedoch 
nicht.

Hardware habe ich schon überprüft und scheint in Ordnung zu sein.

1
#define HAUPTPROGRAMM
2
3
#include "Deklaration.h"
4
#include "taster.h"
5
6
7
//  Tasterabfrage
8
9
/* 
10
 * Die Taster-Ports sind hartcodiert:
11
 * #0 --> PortC.2   (Taster Beleuchtung Radio)
12
 * #1 --> PortC.3   (Taster Beleuchtung Endstufe)
13
 * #2 --> PortC.4   (Taster Trennrelais)
14
 * #3 --> PortC.5   (Taster Anlage)
15
 */
16
17
/* Bei 8MHz Grundtakt läuft Timer0 alle 32µs über.
18
 * Um auf rund 10ms zu kommen, rufen wir get_taster nur
19
 * jedes 313. mal auf. */
20
SIGNAL (SIG_OVERFLOW0)
21
{
22
    static unsigned int count_ovl0;
23
    unsigned int ovl0 = count_ovl0+1;
24
25
    if (ovl0 >= 313)
26
    {
27
        get_taster (0, PINC & (1<<PC2));
28
        get_taster (1, PINC & (1<<PC3));
29
        get_taster (2, PINC & (1<<PC4));
30
        get_taster (3, PINC & (1<<PC5));
31
        
32
        ovl0 = 0;
33
    }
34
35
    count_ovl0 = ovl0;
36
}
37
38
void ioinit()
39
{
40
    /* Taster sind Input (default nach RESET) */
41
    /* Bei LOW-aktiven an den Tastern die PullUps aktivieren, bei HIGH-aktiven nicht */
42
    #if TASTER_LEVEL
43
        ;
44
    #else
45
        PORTC |= 1 << PC2;
46
        PORTC |= 1 << PC3;
47
        PORTC |= 1 << PC4;
48
        PORTC |= 1 << PC5;
49
    #endif
50
51
    /* Timer0 ohne Prescaler starten */
52
    TCCR0 |= (0<<CS02) | (0<<CS01) | (1<<CS00);
53
 
54
    /* Timer0-Overflow-Interrupt aktivieren */
55
    TIMSK |= (1<<TOIE0);
56
}
57
58
int main (void) {            // Beginn des Programms
59
60
 DDRB   |=  (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) | (1<<PB5); 
61
 PORTB  |=  (0<<PB0) | (0<<PB1) | (0<<PB2) | (0<<PB3) | (0<<PB4) | (0<<PB5); 
62
63
 DDRC   |=  (0<<PC0) | (0<<PC1) | (0<<PC2) | (0<<PC3) | (0<<PC4) | (0<<PC5);
64
 PORTC  |=  (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5); 
65
66
 DDRD   |=  (0<<PD0) | (0<<PD1) | (0<<PD2);
67
 PORTD  |=  (1<<PD0) | (1<<PD1) | (1<<PD2);
68
69
// Interrupts freigeben
70
 
71
    sei();
72
 
73
// Variablen initialisieren
74
75
    St.Anlage  =  0;
76
    St.Licht   =  0;
77
78
79
    ioinit();
80
 
81
    /* Taster konfigurieren (#define NUM_TASTER 4 in taster.h) */
82
    tasten[0].mode = TM_SHORT;
83
    tasten[1].mode = TM_SHORT;
84
    tasten[2].mode = TM_SHORT;
85
    tasten[3].mode = TM_SHORT;
86
87
88
// Endlose Hauptschleife
89
 
90
    while (1)
91
     {
92
93
    signed char tast = taster;
94
95
96
    switch (tast)
97
     {
98
99
       default:
100
101
       case NO_TASTER: break;
102
103
       case 0:
104
        {
105
          if (St.Anlage == 1)
106
           {
107
             if (St.Licht == 0)
108
              {
109
                PORTB  |=  (1<<PB5);
110
                St.Licht = 1;
111
              }
112
             else
113
              {
114
                PORTB  &= ~(1<<PB5);
115
                St.Licht = 0;
116
              }
117
           }
118
          
119
          else
120
           {
121
             PORTB  &= ~(1<<PB5);
122
             St.Licht = 0;
123
           }
124
        }
125
        break;
126
127
       case 1:
128
        {
129
        }
130
        break;
131
132
       case 2:
133
        {
134
          if (St.Relais == 0)
135
           {
136
             if (bit_is_clear (PIND,0))
137
              {
138
                PORTB  |=  (1<<PB4);
139
                St.Relais  =  1;
140
              }
141
           }
142
        }
143
        break;
144
145
       case 3:
146
        {
147
          if (St.Anlage == 0)
148
           {
149
             PORTB  |=  (1<<PB0);
150
             St.Anlage = 1;
151
           }
152
          else
153
           {
154
             PORTB  &=  ~(1<<PB0);
155
             St.Anlage = 0;
156
           }
157
        }
158
        break;
159
     }
160
161
     if (tast != NO_TASTER)
162
         taster = NO_TASTER;
163
164
165
// Steuerung Trennrelais
166
      
167
    if (St.Relais == 0)
168
     {
169
       if (bit_is_clear (PIND,1))
170
        {
171
          _delay_ms (1000);
172
          if (bit_is_clear (PIND,1))
173
           {
174
             PORTB  |=  (1<<PB4);
175
             St.Relais  =  1;
176
           }
177
        }
178
     }
179
180
    if (St.Relais == 1)
181
     {
182
       if (bit_is_set (PIND,1) && bit_is_set (PIND,0))
183
        {
184
          _delay_ms (100);
185
          if (bit_is_set (PIND,1) && bit_is_set (PIND,0))
186
           {
187
             PORTB  &= ~(1<<PB4);
188
             St.Relais  =  0;
189
           }
190
        }
191
     }
192
193
194
// Abfrage Lichtschalter
195
196
     if (bit_is_clear (PIND,2))
197
      {
198
        _delay_ms (100);
199
        if (bit_is_clear (PIND,2))
200
         {
201
           St.Licht  =  1;
202
         }
203
      }
204
205
     if (bit_is_set (PIND,2))
206
      {
207
        _delay_ms (100);
208
        if (bit_is_set (PIND,2))
209
         {
210
           St.Licht  =  0;
211
         }
212
      }   
213
     
214
215
     }                                              // Ende Hauptschleife
216
217
}                                                   // Ende main()

: Bearbeitet durch User
von Mark R. (stevestrong)


Lesenswert?

Bitte die Funktionalität der zwei Variabeln "St.Relais" und "St.Anlage" 
prüfen.

von Markus N. (k3hlim)


Lesenswert?

Die Variablen funktionieren ja, wenn ich anstatt der Tastenentprellung 
die Entprellung nur über if-Abfrage und _delay mache, ebenfalls mit den 
Variablen als Status ob gerade aktiv oder inakiv, werden die 
entsprechenden Ausgänge ja geschaltet.

Also als Beispiel für case3:
1
if (bit_is_clear (PINC,5))
2
 {
3
  _delay_ms (10);
4
  if (bit_is_clear (PINC,5))
5
   {
6
    if (St.Anlage == 0)
7
     {
8
      PORTB  |=  (1<<PB0);
9
      St.Anlage = 1;
10
     }
11
    else
12
     {
13
      PORTB  &= ~(1<<PB0);
14
      ST.Anlage = 0;
15
     }
16
   }
17
 }

Wenn ich das so mache, wird PB0 geschaltet, allerdings würde ich die 
Tasterabfrage gerne mit dem anderen Code realisieren und vor allem 
verstehen, warum eine Abfrage funktioniert und die andere 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.