AVR - Tny2313 wacht nicht mehr auf

Gast #2404053
Lesenswert?

Hallo Leutz!

Kann mir bitte jemand verraten warum der Attiny nicht mehr aufwacht?
Im Debugger sowie in echt wacht er nicht mehr auf (Studio 5).

1
.include "tn2313def.inc"
2

3
.def  a    = r16
4
.def  pressedcount = r17
5
.def  compare25 = r18
6
.def  compare50 = r19
7
.def  compare75 = r20
8
.def  compare100 = r21
9
.def  loopcount = r22
10
.def  loopings = r23
11
.def  sregsave = r24
12

13

14
.org 0x0000 ;(000B) Sprungmarke PINCHANGE INT1
15
    rjmp reset
16

17

18
.org INT1addr
19
    rjmp INT1_handler  
20

21

22
reset:
23
ldi a, low(RAMEND)   ; Stack initialisieren
24
out SPL, a
25

26
clr a
27
ldi a, (1<<PD3)  ; Pull-UP Widerstand einschalten, Taster active LOW
28
out PORTD, a
29

30
clr a
31
ldi a, (1<<INT1) ; INT1 Interrupt enable
32
out GIMSK, a
33

34
sbi ACSR,ACD ; Analog Comparator disable
35

36

37

38
clr a
39
clr pressedcount
40
clr compare25
41
clr compare50
42
clr compare75
43
clr compare100
44

45
ldi compare25, 0x3F      ;63 reinladen - 25 % Lichtstärke
46
ldi compare50, 0x7F   ;127 reinladen - 50% Lichtstärke
47
ldi compare75, 0xBF   ;191 reinladen - 75% Lichtstärke
48
ldi compare100, 0xFF     ;255 reinladen - 100% Lichtstärke
49

50

51
main:
52
    rcall schlafen   ; Pwr active, pwr down, wait for PIND3
53
    rcall check
54
    ;rcall led
55

56

57

58

59
schlafen: 
60
  clr pressedcount
61
  clr a
62
  ldi a, (0<<PB2) | (0<<PB3) | (0<<PB4) ; Port B Pin 2,3,4 als Ausgang
63
  out DDRB, a
64
  clr a
65
  out OCR1AL, a ; PWM Register loeschen
66
  out OCR1BL, a 
67
  out OCR0A, a  
68
  out TCCR0A, a ; Beide Timer deaktivieren
69
  out TCCR0B, a
70
  out TCCR1A, a
71
  out TCCR1B, a
72
  ldi a, (1<<SM0) | (1<<SM1) | (1<<SE) | (1<<ISC10) | (0<<ISC11) ; Power down, reagiert auf jede Pinaenderung, sleep enable
73
  out MCUCR, a
74
  sei
75
  sleep       ;<<<<<<<<<  ein Sprung auf PIND3 weckt ihn trotzdem nicht auf
76
  
77
  nop  ;Zeit nach dem Sleep sich einzuschwingen (interner Oszi)
78
  nop
79
  nop
80
  nop
81
  nop
82
  nop
83
  nop
84
  rcall check
85

86
INT1_handler:
87
  cli
88
  in sregsave, SREG
89
  inc pressedcount
90
  out SREG, sregsave
91
  sei 
92
  reti

-Nach dem sleep kann ich machen was ich will nix passiert -- aktiv: 
ISC01 (MCUCR), INT1 (GIMSK), SEI (SREG), DDRB auch auf Eingang aber der 
Interrupt würd trotz Ausgang getriggert werden...
-Ein Taster zieht den Pin auf GND, also active LOW config.

- Wenn ich ISC11 und ISC10 komplett lasse (auf 0), also es soll ein 
Interrupt auf LOW getriggert werden, dann springt er kontinuierlich auf 
die INT1 Interruptadresse, dann auf den handler, und nach dem reti 
wieder auf die Interruptadresse.

Auf wunsch schick ich das ganze Programm als Anhang, is etwas länger 
deswegen hab ichs nicht gepostet.
Ist ein 3-channel 4 Stufen Dimmer mit Pwr down und standby mode. -.-
8 Bit Fast PWM ~1kHz

Was habe ich bitte übersehen? Kann mir jemand bitte helfen?
Gast #2404116
Lesenswert?

1) Wo genau setzt du GIMSK in deinem Code?

2) Der Programmcounter läuft nach dem rcall check in main direkt in die 
Funktion schlafen rein.

> reagiert auf jede Pinaenderung
3) Bei manchen AVRs ist das Aufwachen per INT nur bei bestimmten 
Bedingungen möglich (z.B. low level). Sagt das DB zu deinem AVR was dazu
Gast #2404268
Lesenswert?

Hy! Vielen Dank für die schnelle Antwort!

1) steht ganz am anfang in der reset routine unter dem PD3.

2) das verstehe ich leider nicht. wie könnte ich es ändern, dass nach 
dem sleep auf "rjmp check" gesprungen wird? indem dass der interrupt 
ausgelöst wird oder?

3) ja, das geht beim Tny2313. INT1 ist auf jede änderung programmiert. 
(ISC10)

also der program counter zügelt nach und deswegen geht es nicht? muss 
ich da einfach extra sprungmarken einfügen?

vielen dank für die hilfe!
Gast #2404324
Lesenswert?

1) GIMSK
Ah dort habe ich es nicht erwartet.
Ich habe es in der Nähe von MCUCR gesucht.

2) Du brauchst eine saubere Struktur deines Programms z.B.
1
  ; Definitionen
2

3
  ; Initialisierungscode
4

5
mainloop:
6
  ; Unendliche Arbeitsschleife...
7
  rcall schlafen
8
  rcall check
9
  rjmp mainloop
10

11
; #########
12

13
schlafen:
14
  ; Code ...
15
  ret
16

17
; #########
18

19
check:
20
  ; Code ...
21
  ret
22

23
; #########
24

25
INT1_handler:
26
  in sregsave, SREG
27
  inc pressedcount
28
  out SREG, sregsave
29
  reti

Der Aufruf von check in schlafen würde ich nicht machen. Das ist ja 
derzeit doppelt gemoppelt - in main und in schlafen.

Du musst auch überlegen, ob die Aufwachbedingung (INT1) nach dem 
Aufwachen weiterhin anliegt, d.h. ob der AVR dann dauernd im 
INT1_handler rumrennt. Bei einem Level-Interrupt oder bei 
Flanken-Interrupt mit prellenden externen Bauteilen ist das der Fall.

Das kann man beheben, wenn man im INT1_handler nach dem Auftreten des 
ersten INT1 weitere INT1s sperrt (GIMSK). Und später vorm Schlafenlegen 
wieder zulässt. Vorm Zulassen des INT1 aber das ggf. anstehende alte 
INT1-Flag löschen!
Gast #2404472
Lesenswert?

1) :) ja, eig. sollte es ja immer gelten ^^

2) alles klar, ich strukturiere das programm mal anders, und schau was 
passiert. ja, kenne ich, danke für die tipps mit der flag und im 
allgemeinen =) !!!
wenn ich damit fertig bin poste ich es nochmal, kann aber bis morgen 
dauern..
danke !!
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.