AVR Anfängerfrage Timer1

Gast #748875
Lesenswert?

Hallo,

ich bin dabei mir eine Lampensteuerung für ein Zimmer zu programmieren. 
Diese soll mittels eines Taster folgende Funktionen erfüllen:

erstes mal tasten                           - Lampe 1 geht an
zweites mal innerhalb von 2 Sekunden tasten - Lampe 1 und Lampe 2 gehen 
an
zweites mal tasten innerhalb von 6 Sekunden - Lampe 2 geht an
zweites bzw. 3 tasten                       - alles geht aus

Hier mein Programm was leider nicht ganz funktioniert:
1
$regfile = "m8def.dat"                                      'für Mega8
2
$crystal = 4000000
3

4
Config Portd = Output                                       'definiert Portd als Output
5
On Timer1 Isr_von_timer1                                    'verzweige bei Timer1 überlauf zu   Isr_von_Timer1                                              'Timer1 soll schon von 34285 wegzählen
6
Dim A As Byte
7
Config Portb = Input
8
Portb = 1
9
Do
10
If Pinb.0 = 0 Then                                          'wenn Taster gedrückt Lampe 1 und Timer1 wird aktiviert
11
Portd.0 = 1
12
Enable Timer1
13
Enable Interrupts
14
Config Timer1 = Timer , Prescale = 256
15
Timer1 = 34285
16
End If
17
While A = 1                                                 'wird innerhalb von 2 Sekunden der Taster erneut betätigt leuchtet Lampe 2 dazu
18
While A <= 2
19
If Pinb.0 = 0 Then Portd.1 = 1
20
Wend
21
Wend
22
While A = 3                                                 'wird der Taster erst nach 3 Sekunden nach dem ersten Tasten wieder betätigt leuchtet nur Lampe 2
23
While A <= 10
24
If Pinb.0 = 0 Then Portd.1 = 1 : Portd.0 = 0
25
Wend
26
Wend
27
While A > 11                                                ' wird der Taster erst nach 6 Sekunden ein zweites mal betätigt schaltet er alles aus
28
If Pinb.0 = 0 Then
29
Portd.0 = 0
30
Portd.1 = 0
31
Disable Timer1
32
Disable Interrupts
33
A = 0
34
End If
35
Wend
36
Loop
37
End
38

39
Isr_von_timer1:                                             'ISR von Timer1
40
Timer1 = 34285                                              'Timer1 soll wieder von 34285 wegzählen
41
Incr A                                                      'zählt variable A jede sekunde um eins hoch
42
Return
das Problem ist das die Schritte zwar alle richtig abgearbeitet werden 
aber die while-Wend schleifen schalten obwohl der Taster ncht betätigt 
wird.
Wie kann ich dies ändern?
Persönliche Seite #748949
Lesenswert?

Mache es mit einem Endlichen Automaten (state machine).
1
$regfile = "m8def.dat"
2
$crystal = 4000000
3

4
Config Portd = Output
5

6
Config Portb = Input
7
Portb = 1                  ' Pull-Up für PINB.0 aktivieren
8
Config Debounce = 30
9

10
Dim Zeit As Byte
11
Dim Zustand As Byte
12
Dim Taste As Byte
13

14
Zeit = 0
15
Zustand = 0
16
Taste = 0
17

18
'
19
' Zustand  Lampe 1  Lampe 2  Timer1 
20
'    0*      AUS      AUS    AUS
21
'    1       AN       AUS    AN
22
'    2       AUS      AN     AN
23
'    3       AN       AN     AN
24
'
25
' * Startzustand
26
'
27
' Übergänge:
28
' A: 0 -> 1: 1. Tastendruck
29
' B: 1 -> 3: 2. Tastendruck zwischen 0s und 2s
30
' C: 1 -> 2: 2. Tastendruck zwischen 2s und 6s
31
' D: 1 -> 0: 2. Tastendruck nach mehr als 6s
32
' E: 2 -> 0: 3. Tastendruck irgendwann
33
' F: 3 -> 0: 3. Tastendruck irgendwann
34
'
35
'                        Zustand 1
36
'                       /  |  ^  \
37
'                      /   D  A   \
38
'                     /    v  |    \
39
'                    C   Zustand 0  B 
40
'                   /    ^       ^   \
41
'                  /    E         F   \ 
42
'                 v    /           \   v
43
'             Zustand 2             Zustand 3                     
44

45
' Timer1 fürs spätere Laufenlassen einrichten
46
On Timer1 Isr_von_timer1
47
Config Timer1 = Timer , Prescale = 256
48
Enable Interrupts
49

50
DO
51
  DEBOUNCE Pinb.0 , 0 , Entprellen, SUB
52

53
  IF Zustand = 0 THEN
54
    Portd.0 = 0        ' Lampen entsprechend Zustand schalten
55
    Portd.1 = 0
56
    Disable Timer1     ' Stoppuhr aus     
57
    IF Taste = 1 THEN
58
      Zeit = 0         ' Reset Stoppuhr Teil 1
59
      Timer1 = 34285   ' Reset Stoppuhr Teil 2
60
      Enable Timer1    ' Stoppuhr an
61
      Zustand = 1      ' Warten auf die nächste Taste...
62
    END IF
63
  END IF
64

65
  IF Zustand = 1 THEN
66
    Portd.0 = 1
67
    Portd.1 = 0
68
    IF Taste = 2 THEN
69
      IF Zeit < 2 THEN Zustand = 3
70
      ELSEIF Zeit > 6 THEN Zustand = 0
71
      ELSE ' Zeit >= 2 und <= 6
72
        Zustand = 2
73
      END IF 
74
    END IF
75
  End If
76

77
  If Zustand = 2 Then
78
    Portd.0 = 0
79
    Portd.1 = 1
80
    IF Taste = 3 THEN 
81
      Zustand = 0
82
      Taste = 0
83
    END IF
84
  End If
85

86
  If Zustand = 3 Then
87
    Portd.0 = 1
88
    Portd.1 = 1
89
    IF Taste = 3 THEN 
90
      Zustand = 0
91
      Taste = 0
92
    END IF
93
  End If
94

95
LOOP
96
END 
97

98
Isr_von_timer1:   
99
  Timer1 = 34285    ' Timer1 ist übergelaufen jetzt resetten
100
  INCR Zeit         ' Überlauf als Sekunde zählen
101
RETURN
102

103
Entprellen:
104
  INCR Taste 
105
  if Taste > 3 THEN Taste = 1  ' (EDIT) Tasten resetten
106
RETURN
Gast #749643
Lesenswert?

@Sowas (Gast),

bist du auch einer dieser bekloppten Bascom-Hasser? Hast du schon mal 
mit Bascom gearbeitet? Wenn nein kannst du hier auch nicht mitreden. 
Falls du in C Programmierst motzt ja auch keiner oder... Bascom ist eine 
Programmiersprache die besonders für Einsteiger sehr gut geeignet ist, 
man kann damit aber durchaus auch anspruchsvolle Sachen machen. Du 
hängst wohl noch mit dem Vorurteil der 90'er das alles was Basic heißt 
schrott ist...

Sorry @all für die harsche Wortwahl meinerseits aber wenn ich lese wie 
hier Anfänger angeraunzt werden weil sie eine Frage stellen die mit 
Bascom-Programmierung zu tun hat könnte ich kotzen... Soviel zum Thema 
toleranz für andere.......

Alexey (der auch noch gerne in Bascom Proggt!)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren