Forum: Mikrocontroller und Digitale Elektronik Debug Fehler?


von Max (Gast)


Lesenswert?

Hallo, ich bin seit ein paar Tagen dabei ein Programm in AVR Studio 4 zu 
schreiben um anhand eines atmega16 eine IR Diode anzusteuern.

Nun hab ich das Problem dass die Diode permanent sendet, obwohl sie das 
nicht darf (soll ca. nur 200ms lang senden). Im debug Modus des AVR 
Studio bin ich auf Fehlersuche gegangen und auf etwas seltsames 
gestoßen. Zuerst ein Teil des codes:
1
      CLR    temp        ;Timer Register laden
2
      OUT    TCNT0, temp
3
      LDI    temp, 0x9D      ;Output Compare Reg. laden
4
      OUT    OCR0, temp
5
  
6
      LDI    temp, 0b00011001  ;Counter starten. Ein Burst von 30
7
      OUT    TCCR0, temp      ;Impulsen gibt Startsignal
8
    
9
      ;RCALL  W5s
10
      ;RCALL  W5s
11
12
loop:    CPI    c, 0x01
13
      BRNE  loop

Also, ich habe einen Timer mit compare match interrupt definiert, der 
funktioniert in einem ähnlichen Programm tadellos. Aber hier beim 
debuggen, springt der PC sofort nach dem ersten compare match (während 
er sich in der Schleife befindet) automatisch ein paar Befehle zurück 
auf die Zeile "LDI temp, 0b00011001" und löscht das global interrupt 
flag (?????). Dadurch kommt das Programm ins Stocken und es geschieht 
kein interrupt. Ich habe keine Ahnung an was das liegen könnte.

Ich bin am Verzweifeln und bitte dringend um Hilfe!

mfg

Max

von spess53 (Gast)


Lesenswert?

Hi

Poste mal dein gesamte Programm

MfG Spess

von Max (Gast)


Lesenswert?

1
;************************************************************************
2
;* 2. Testprogramm für IR Emitter
3
;* 
4
;* Prozessor:   Atmega16
5
;* Taktfrequenz:12MHz
6
;************************************************************************
7
8
;Vereinbarungsteil
9
10
      .INCLUDE  "m16def.inc"  ;AVR-Definitionsdatei einbinden
11
      .DEF    temp = r16    ;Zwischenspeicher
12
      .DEF    i = r17      ;Zähler
13
      .DEF    c = r18
14
      .DEF    j = r19
15
      .DEF    k = r20
16
17
;Programm-Flash
18
19
      .CSEG             ; was ab hier folgt kommt in den
20
                    ; FlashSpeicher  
21
22
      .ORG  0x0000         ; Beginn des Programmspeichers
23
                                
24
reset:     RJMP  init         ; springe nach 'init'
25
26
      .ORG  0x0014
27
      RJMP  T0_CP
28
29
;Stapel initialisieren (für Unterprogramme bzw. Interrupts)
30
31
init:                   
32
      LDI    temp, HIGH(RAMEND)   ; Information in den Stackpointer laden
33
      OUT    SPH, temp       ;
34
      LDI    temp, LOW(RAMEND)
35
      OUT    SPL, temp
36
37
;Timer Interrupt Mask definieren
38
39
      LDI    temp, 0x02      
40
      OUT    TIMSK, temp
41
42
;Ports definieren
43
44
      LDI    temp,   0xFF    ; Port B als Ausgang
45
      OUT    DDRB,   temp    ;
46
47
;Hauptprogramm 
48
;***************************************  
49
;code 1 senden
50
51
main:    CLR    c          ;alle Register zurücksetzen
52
      CLR    k    
53
      LDI    i, 31        ;Burst auf 30 Impulse
54
      LDI    j, 5        ;Impulszähler auf 5
55
56
      SEI              ;Global Interrupts zulassen
57
58
      CLR    temp        ;Timer Register laden
59
      OUT    TCNT0, temp
60
      LDI    temp, 0x9D      ;Output Compare Reg. laden
61
      OUT    OCR0, temp
62
  
63
      LDI    temp, 0b00011001  ;Counter starten. Ein Burst von 30
64
      OUT    TCCR0, temp      ;Impulsen gibt Startsignal
65
    
66
      ;RCALL  W5s
67
      ;RCALL  W5s
68
69
loop:    CPI    c, 0x01        ;Warte bis code 1 gesendet wurde
70
      BRNE  loop    
71
72
;****************************************
73
;code 2 senden
74
75
main2:    CLR    temp        ;counter stoppen
76
      OUT    TIMSK, temp      
77
      IN    temp, TCCR0      
78
      ANDI  temp, 0b11001000  
79
      OUT    TCCR0, temp      
80
81
      CLR    temp        ;Timer Register laden
82
      OUT    TCNT0, temp
83
      LDI    temp, 0x9D      ;Output Compare Reg. laden
84
      OUT    OCR0, temp
85
86
      ;RCALL  W5s
87
      ;RCALL  W5s
88
89
      CLR    c          ;alle Register zurücksetzen
90
      CLR    k          ;
91
      LDI    j, 7        ;Impulszähler auf 7
92
      LDI    i, 31        ;Burst auf 30 Impulse
93
94
      LDI    temp, 0x02      
95
      OUT    TIMSK, temp
96
97
      LDI    temp, 0b00011001  ;Counter starten. Ein Burst von 30
98
      OUT    TCCR0, temp      ;Impulsen gibt Startsignal
99
100
loop1:    CPI    c, 0x01        ;Warte bis code 2 gesendet wurde
101
      BRNE  loop1
102
103
      CLR    temp        ;counter stoppen
104
      OUT    TIMSK, temp
105
      IN    temp, TCCR0      
106
      ANDI  temp, 0b11001000
107
      OUT    TCCR0, temp
108
109
loop2:    RJMP  loop2        ;Endlosschleife
110
111
;Timer Interrupt Routine
112
;****************************************      
113
114
T0_CP:    PUSH  temp        ;Register retten
115
      IN    temp, SREG
116
      PUSH  temp
117
118
      CPI    k, 0x01        ;
119
      BREQ  changefreq
120
121
      DEC    i          ;Zähler dekrementieren
122
      BRNE  end
123
124
      LDI    temp, 0b00101100  ;Intervall ändern (ca. 9,2ms aus)
125
      OUT    TCCR0, temp
126
      LDI    temp, 0xD8      ;Output Compare Reg. ändern
127
      OUT    OCR0, temp  
128
        
129
      LDI    k, 0x01        ;
130
      DEC    j          ;Wenn x Impulse gesendet dann springe
131
      BRNE  end          ;nach end
132
133
      LDI    c, 0x01        
134
              
135
end:    POP    temp        ;Register wiederherstellen
136
      OUT    SREG, temp
137
      POP    temp
138
      RETI    
139
140
changefreq:  LDI    temp, 0b00011001  ;Schalte um auf Burst
141
      OUT    TCCR0, temp      ;
142
      LDI    temp, 0x9D      ;Output Compare Reg. laden
143
      OUT    OCR0, temp
144
145
      LDI    i, 31        ; Zähler rücksetzen
146
      CLR    k          
147
      RJMP  end
148
149
;************************************************************************
150
W5s:  PUSH r17                     ;nur bei 8 MHz spielt hier keine Rolle
151
    PUSH r18
152
    PUSH r19
153
    PUSH r20
154
155
    LDI r19, 0xC4 
156
    LDI r20, 0x09
157
158
loop_a1:LDI r17, 0xA0
159
    LDI r18, 0x0F
160
    
161
loop_a2:SUBI r17, 1
162
    SBCI r18, 0
163
    
164
    BRNE loop_a2
165
    
166
    SUBI r19, 1
167
    SBCI r20, 0
168
    
169
    BRNE loop_a1
170
171
    POP  r20
172
    POP r19
173
    POP r18
174
    POP r17
175
176
    RET
177
178
.EXIT

von spess53 (Gast)


Lesenswert?

Hi

>      .ORG  0x0014
>      RJMP  T0_CP

Der Sprung zum TIMER0 COMP Interrupt liegt auf Adresse $26.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Nachtrag: Solche Fehler lassen sich leicht vermeiden, in dem du statt 
der Adresse die Konstanten aus der ''m16def.inc' benutzt

->            .org OC0addr

MfG Spess

von Max (Gast)


Lesenswert?

Ahhh danke! Denke das liegt daran dass ich im Datenblatt des mega32 
nachgeschaut habe weil ich fest überzeugt war dass beide uc gleich sind 
abgesehen von den Speicherkapazitäten.

Nochmals vielen Dank.

mfg

Max

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.