Problem beim Entprellen/Timer0

Gast #1256120
Hallo,

Mein Assemblercode, der eine 7-Semgente-Anzeige pro Tastendruck um 1 
erhöht funktioniert soweit gut.
Als ich dann den Timer0 einbaute, um den Taster zu entprellen, 
funktionierte gar nichts mehr.
Hat jemand eine Idee woran das liegen kann?

Code ist im Anhang

Gruss
Gast #1256126
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
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
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

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.