Forum: Mikrocontroller und Digitale Elektronik ASM Inkrement Fehler


von Matthias (Gast)


Lesenswert?

Hallo zusammen,

ich stehe auf dem Schlauch und weiss echt nicht mehr weiter. Ich habe 
ein kleines ASM Programm für einen Attiny10 geschrieben. Soll einfach 
bei Tastendruck den PWM ändern. Der erste Tastendruck funktioniert auch. 
Erster Wert wird gesetzt. Jetzt kommt der Fehler, wiederholtes Drücken 
führt zu keiner Änderung. Hab schon überprüft ob in den Interrupt 
gesprungen wird und in die SetzFunktion, wird alles korrekt ausgeführt. 
Ich habe dann festgestellt das pstate durch wiederholtes Aufrufen nicht 
geändert wird, es hat immer den Anfrangswert. Im AVR Studio mit 
Simulator funktioniert das ganze, nur auf dem Tiny selber nicht. Ich 
weiss echt nicht mehr was es sein könnte.
Jemand einen Ahnung woran das liegen kann?
1
.include "tn10def.inc"
2
.def temp = r18
3
.def temp1 = r17
4
.def pstate = r16
5
.def voltproof = r19
6
7
.org 0x000
8
rjmp main            ; Reset Handler
9
10
.org INT0addr
11
rjmp int0_handler    ; IRQ0 Handler
12
13
.org OVF0addr
14
rjmp    timer0_overflow       ; Timer Overflow Handler
15
16
main:
17
  ldi      temp, HIGH(RAMEND)     ; Stackpointer initialisieren
18
  out      SPH, temp
19
  ldi      temp, LOW(RAMEND)
20
  out      SPL, temp
21
22
  //Ausgangspin für PWM
23
  ldi temp, (1<<DDB0) | (1<<DDB1);
24
  out DDRB , temp
25
26
  //Ausgangspin Pullup für PWM
27
  ldi temp, (1<<PUEB0);
28
  out PUEB , temp
29
30
  ;INTO Interrupt einstellen LowLevel Interrupt
31
  ldi temp, (1<<ISC01); INT0 und INT1 auf fallende Flanke konfigurieren
32
  out EICRA , temp
33
  ldi temp, (1<<INT0)
34
  out EIMSK, temp
35
36
  ;Pullup INT0
37
  ldi temp, (1<<PUEB2);
38
  out PUEB, temp
39
40
  ;Variablen nullen
41
  ldi pstate, 0
42
43
  ;ADC init
44
  ldi     temp, (1<<ADEN)
45
  out     ADCSRA, temp
46
  ;Interrupts an
47
  sei
48
mainloop:
49
  rjmp mainloop
50
51
timer0_overflow:
52
  reti
53
54
;Interrupt durch Taster
55
;in pstate
56
int0_handler:
57
  ;Interrupts aus
58
  cli
59
  inc pstate
60
  start_vergleich:
61
    cpi     pstate,1
62
    brne    zweig_0
63
    //10%
64
    ldi temp1, 21
65
    rjmp    ende_vergleich
66
  zweig_0:
67
    cpi     pstate,2
68
    brne    zweig_1
69
    //25%
70
    ldi temp1, 63
71
    rjmp    ende_vergleich
72
  zweig_1:
73
    cpi     pstate,3
74
    brne    zweig_2
75
    //50%
76
    ldi temp1, 127
77
    rjmp    ende_vergleich
78
  zweig_2:
79
    cpi     pstate,4
80
    brne    zweig_3
81
    //75%
82
    ldi temp1, 192
83
    rjmp    ende_vergleich
84
  zweig_3:
85
    cpi     pstate,5
86
    brne    kein_Treffer
87
    //100%
88
    ldi temp1, 255
89
    rjmp    ende_vergleich
90
  kein_Treffer:
91
    ldi temp1, 0
92
    ldi pstate, 0
93
  ende_vergleich:
94
95
  rcall setpwm;setzen der pwm mit dem in temp1 gespeicherten wert
96
  ;Interrupts an
97
  sei
98
  reti ;Return aus Interrupt
99
100
;setzen der pwm mit dem wert aus temp1
101
;in:temp1
102
setpwm:
103
  ;Ausschalten zum ändern
104
  ldi temp, 0;
105
  out TCCR0A, temp
106
  out TCCR0B, temp
107
108
  out OCR0AL, temp1
109
  
110
  cpi     pstate,0
111
  BREQ    no_ea_pwm
112
  ;Einschalten
113
  ldi temp, (1<<OCIE0A)
114
  out TIMSK0 , temp
115
  ldi temp, (1<<COM0A1) | (1<<WGM00); FastPWN auf ChA, Clock/128 = 500Hz
116
  out TCCR0A, temp
117
  ldi temp, (1<<WGM02) | (1 << CS01); FastPWN auf ChA, Clock/128 = 500Hz
118
  out TCCR0B, temp
119
  no_ea_pwm:
120
  ret

von Spess53 (Gast)


Lesenswert?

Hi

Ein Taster am Interruptpin ist eine dumme Idee. Sieh dir mal die 
Entprellroutinen 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten
an.

MfG Spess

von Matthias (Gast)


Lesenswert?

Der Taster ist soweit schon hardwareseitig entprellt. Aber das ist 
schließlich nicht mein Problem.

mfg Matthias

von Sascha W. (sascha-w)


Lesenswert?

Matthias schrieb:
> Der Taster ist soweit schon hardwareseitig entprellt.
Wie?
> Aber das ist
> schließlich nicht mein Problem.
dass kann man so nicht sagen, prellt der Taster, so wird pstate in 
kurzer Zeit mehrmals erhöht. Mach doch testweise mal eine delay-Scheife 
rein.


UND
1) Ein cli am Anfang einer ISR, und ein sei vorm Ende kannst du dir 
sparen, mit dem Eintritt in die ISR sind weitere INT's sowiso gesperrt.

2) Wenn du nur die PWM verstellen willst, dann schalte sie nicht erst 
jedesmal vorher aus.

Sascha

von Stefan E. (sternst)


Lesenswert?

1
rjmp main            ; Reset Handler
2
3
.org INT0addr
4
rjmp int0_handler    ; IRQ0 Handler
5
6
.org OVF0addr
7
rjmp    timer0_overflow       ; Timer Overflow Handler
8
9
main:
10
...
11
...
12
  ldi temp, (1<<OCIE0A)
13
  out TIMSK0 , temp
Das ist die Ursache deines Problems.

von Matthias (Gast)


Lesenswert?

Oh ja, danke das war wirklich mein Problem.

von Matthias (Gast)


Lesenswert?

@ Sascha:
hab deinen Tipp gerade ausprobiert, leider geht das scheinbar nicht mit 
dem AVR Studio Simulator. Das geht dort nur wenn ich vor dem Setzen 
ausschalte und danach wieder einschalte.

mfg Matthias

Sascha Weber schrieb:
> 2) Wenn du nur die PWM verstellen willst, dann schalte sie nicht erst
> jedesmal vorher aus.

von amateur (Gast)


Lesenswert?

Deine ISR ist ein klassisches Beispiel dafür wie man es nicht machen 
soll.

Nicht nur, dass man keine Tasten in einer ISR abfragen soll. Auch kann 
es in 99,994% bis 100% aller Fälle nicht schaden, das eine oder andere 
Register zu sichern. Und wenn's nur der aktuelle Status ist.

von Karl H. (kbuchegg)


Lesenswert?

und ein cli/sei in einer ISR ist auch nichts was man selber machen will.

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.