Problem beim Entprellen/Timer0

Gast #1256126
Lesenswert?

Sorry das mit dem Anhang hat nicht geklappt.
Hier der Code
1
;Ansteuern der Segmente und des Tasters
2
;PB0-PB7 sind für die Segmente (Ausgang) und PD2 ist für den Taster (Eingang) bestimmt.
3

4
.INCLUDE   "m32def.inc"     ;Deklaration für ATmega32
5
.DEF     status = r16    ;Variable, die überprüft, ob die Initialisierung schon einmal durchgeführt wurde
6
.DEF    zaehler = r17    ;Zählregister
7
.DEF    vergl_reg = r18    ;Register für den Vergleich
8
.DEF    universal_reg = r19  ;Register für Init.,Masken,...
9
.DEF    ms_zaehler = r20  ;Zählt die Zeit für die Entprellung des Tasters
10
.DEF    status_timer0 = r21  ;wenn timer0 Zeit gezählt         hat,nächster überspringen
11
.DEF    wartezeit = r22    ;Zeit zum Entprellen des Tasters
12
.ORG    0x000
13
rjmp initialisierung   ;Nach Reset muss Initialisierung durchgeführt werden
14
.ORG    INT0addr 
15
rjmp interrupt0 
16
.ORG    OVF0addr
17
rjmp timer0_interrup      
18
       
19
;Interrupt initialisieren
20
    initialisierung:
21
      ldi wartezeit,0x04        ;Wartezeit = 1 sek.
22
      ldi zaehler,0x00        ;Zähler auf 0 setzten
23
      ldi  universal_reg,0x3F      ;0 Anzeigen
24
      out PORTA,universal_reg
25
      ldi universal_reg,LOW(RAMEND)  ;Stapel anlegen
26
      out SPL,universal_reg
27
      ldi  universal_reg,HIGH(RAMEND)
28
      out SPH,universal_reg
29
      in   universal_reg,MCUCR      ;altes Steuerregister
30
      cbr  universal_reg,1 << ISC00  ;lösche Bit bei ISC00
31
      sbr  universal_reg,1 << ISC01  ;sezte Bit bei ISC01
32
      out  MCUCR,universal_reg      ;Bei einer fallenden Flanke wird im INT0 ein Interrupt ausgelöst
33
      in  universal_reg,GICR      ;altes Freigaberegister
34
    sbr universal_reg,1 << INT0  ;setze Bit bei INT0
35
    out GICR,universal_reg    ;Interrupt feigegeben
36
   sei        ;alle Interrupts global frei
37

38
;allg. Initialisierung
39
          
40
                                        
41

42
      ldi  zaehler,0x00        ;Zähler für Vergleich, Anfangswert 0
43
          
44
      ldi wartezeit,0xFF
45

46
      ldi universal_reg,0xFF              
47
      out DDRA,universal_reg      ;Port A als Ausgang
48

49
      ldi universal_reg,0x00
50
      out DDRD,universal_reg      ;Port D als Eingang 
51

52
      ldi universal_reg,0x04
53
      out PORTD,universal_reg      ;INT0/PD2 Pull-up aktiviert
54

55
      ldi universal_reg,0x01
56
      out TIMSK,universal_reg      ;Timer/Counter0 Overflow Interrupt Enable
57

58
      ldi universal_reg,0x05
59
      out TCCR0,universal_reg      ;Disable Force Mode, select Normal Mode, no Compare Match Output
60
                      ;Select Prescaler 1024 (CS02..00 = 101)
61
      ldi universal_reg,0x70
62
      out TCNT0,universal_reg      ;Preloader = 111, jetzt startet der timer0
63
;"main"
64

65
    main: 
66
          jmp main                ;Endlosscheife
67
  
68
    timer0_interrup:
69
          push universal_reg
70
          in   universal_reg,SREG
71
          push universal_reg
72
          
73
          inc   ms_zaehler
74
          
75
          pop  universal_reg
76
          out  SREG,universal_reg
77
          pop  universal_reg
78

79
          reti
80

81

82
    warten:    
83
          push universal_reg
84
          in   universal_reg,SREG
85
          push universal_reg
86

87
          cpse wartezeit,ms_zaehler
88
          jmp  warten
89
          
90
                    
91
          pop  universal_reg
92
          out  SREG,universal_reg
93
          pop  universal_reg
94

95

96
          ret           
97
          
98
            
99
;"interrupt0"
100

101
    interrupt0:
102
        ldi ms_zaehler,0x00    ;ms_zähler auf 0 sezten
103
        call warten
104
                        
105
  ;->varible hochzählen
106
                      ;Zeitschritte zählen
107
        inc zaehler        ;Zähler: Register r17 + 1          
108

109
        ldi vergl_reg,0x0A    ;wenn Zähler 10 -> overflow -> Zähler wieder auf 0 setzen
110
      cp  zaehler,vergl_reg      
111
      breq overflow
112
        
113
  ;->Vergleich
114
          
115
      ldi vergl_reg,0x00    ;lade Zahlenwert in Register
116
      cp zaehler,vergl_reg  ;Registervergleich wenn gleich (r17 - Zahl) Z=1
117
      breq set0        ;wenn Z=1 Sprung nach "set_"    
118
        
119
          ldi vergl_reg,0x01
120
          cp zaehler,vergl_reg
121
          breq set1
122
          
123
          ldi vergl_reg,0x02
124
          cp zaehler,vergl_reg
125
          breq set2
126
        
127
          ldi vergl_reg,0x03
128
          cp zaehler,vergl_reg
129
          breq set3
130
        
131
          ldi vergl_reg,0x04
132
          cp zaehler,vergl_reg
133
          breq set4
134
        
135
          ldi vergl_reg,0x05
136
          cp zaehler,vergl_reg
137
          breq set5
138
        
139
          ldi vergl_reg,0x06
140
          cp zaehler,vergl_reg
141
          breq set6
142
          
143
          ldi vergl_reg,0x07
144
          cp zaehler,vergl_reg
145
          breq set7
146
          
147
          ldi vergl_reg,0x08
148
          cp zaehler,vergl_reg
149
          breq set8
150
          
151
          ldi vergl_reg,0x09
152
          cp zaehler,vergl_reg
153
          breq set9
154
  
155
  ;->Sprung nach "main"
156
          reti 
157

158
;Wenn Zähler =10 -> auf -1 setzten
159
    overflow:  ldi zaehler,-0x01
160
        jmp interrupt0
161
          
162
;"set_"
163
;->Maske für PORTA ausgeben
164
;->Sprung nach "interrupt0"    
165
    set0:     
166
          ldi universal_reg,0x3F
167
            out PORTA,universal_reg
168
          reti
169

170
    set1:     
171
          ldi universal_reg,0x06
172
            out PORTA,universal_reg
173
          reti
174

175

176
    set2:     
177
          ldi universal_reg,0x6D
178
            out PORTA,universal_reg
179
          reti
180

181

182
    set3:     
183
          ldi universal_reg,0x4F
184
            out PORTA,universal_reg
185
          reti
186

187

188
    set4:     
189
          ldi universal_reg,0x56
190
            out PORTA,universal_reg
191
          reti
192

193

194
    set5:     
195
          ldi universal_reg,0x5B
196
            out PORTA,universal_reg
197
          reti
198

199

200
    set6:     
201
          ldi universal_reg,0x7B
202
            out PORTA,universal_reg
203
          reti
204

205

206
    set7:     
207
          ldi universal_reg,0x0E
208
            out PORTA,universal_reg
209
          reti
210

211

212
    set8:     
213
          ldi universal_reg,0x7F
214
            out PORTA,universal_reg
215
          reti
216
          
217
    set9:     
218
          ldi universal_reg,0x5F
219
            out PORTA,universal_reg
220
          reti
Gast #1256152
Lesenswert?

Hi

>    warten:
>          push universal_reg
>          in   universal_reg,SREG
>          push universal_reg>

>          cpse wartezeit,ms_zaehler
>          jmp  warten

Nette Methode den Stack vollzubekommen.

>    overflow:  ldi zaehler,-0x01
>        jmp interrupt0

Ähnlicher Unsinn.

Zu deinen Programm kann ich dir nur raten: Gründlich überdenken und neu 
anfangen.
Nur ein paar Tips:
- Interruptroutinen so lang wie nötig und so kurz wie möglich.
- Warteschleifen haben in ISRs nichts zu suche.
- in den Interrupts Flags setzen, die in 'main' abgefragt werden und 
dann
  in Abhängigkeit die entsprechenden Routinen abarbeiten.
....

MfG Spess
Gast #1256169
Lesenswert?

Hi

Im Anhang mal ein kleines Beispiel zur Gestaltung deiner Ausgaberoutine.
Ersetzt alles zwischen:

> ;->Vergleich
> ldi vergl_reg,0x00    ;lade Zahlenwert in Register

und

> set9:
>   ldi universal_reg,0x5F
>     out PORTA,universal_reg
>   reti

Allerdings als Unterprogramm und nicht als ISR.

MfG Spess
Angehängte Dateien:

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