Forum: Mikrocontroller und Digitale Elektronik Problem beim Entprellen/Timer0


von Thomas (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

>Code ist im Anhang

Aber gut versteckt.

MfG Spess

von Thomas (Gast)


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

von spess53 (Gast)


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

von spess53 (Gast)


Angehängte Dateien:

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

von Thomas (Gast)


Lesenswert?

hallo  spess53

danke!

Gruss

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.