Witam,
Niestety ostatnio od kilku miesięcy mam bardzo mało czasu na swoje hobby i zabawę z prockami więc teraz tak z marszu ciężko mi sobie przypomnieć jak dokładnie działałem z tym PowerDown w swoim pilocie ale wkleję poniżej swój kod taki jaki działa do dzisiaj w tym moim pilociku i to bardzo dobrze działa - moż coś to pomoże. Niestety kod jest w C ale postaram się też wkleić to co jest później w asm po kompilacji:
// wyłączenie komparatora analogowego
// nie jest to zbyt konieczne jeśli nie są używane te piny w procesorze
// szczególnie jako wejścia analogowe (tu mogłoby to być pominięte)
ACSR SET (1<<ACD);
// WYŁĄCZENIE WATCHDOG'a - też konieczne tak naprawdę tylko wtedy
// gdy jest on używany (tu mogłoby to być pominięte)
WDTCSR |= (1<<WDCE) | (1<<WDE);
// Turn off WDT
WDTCSR = 0x00;
// ustawienie trybu POWER-DOWN
MCUCR SET ((1<<SM0)|(1<<SM1));
// ustawienie pinu PORTD.2 (INT0) jako wejście
DDRD RESET (1<<2);
// podciągnięcie do 1
PORTD SET (1<<2);
// zezwolenie na przerwania INT0
GIMSK SET (1<<INT0);
// skasowanie flagi wystąpienia przerwania INT0
EIFR SET (1<<INTF0);
while (1)
{
// globalne zezwolenie na przerwania
sei();
// wprowadzenie procesora w tryb POWER-DOWN
sleep_mode();
}
dodane są komentarze więc może one coś wyjaśnią - jak należy postępować przed wprowadzeniem procka w stan śpiączki klinicznej
// wyłączenie komparatora analogowego
// nie jest to zbyt konieczne jeśli nie są używane te piny w procesorze
// szczególnie jako wejścia analogowe (tu mogłoby to być pominięte)
ACSR SET (1<<ACD);
254: 47 9a sbi 0x08, 7 ; 8
// WYŁĄCZENIE WATCHDOG'a - też konieczne tak naprawdę tylko wtedy
// gdy jest on używany (tu mogłoby to być pominięte)
WDTCSR |= (1<<WDCE) | (1<<WDE);
256: 81 b5 in r24, 0x21 ; 33
258: 88 61 ori r24, 0x18 ; 24
25a: 81 bd out 0x21, r24 ; 33
// Turn off WDT
WDTCSR = 0x00;
25c: 11 bc out 0x21, r1 ; 33
// ustawienie trybu POWER-DOWN
MCUCR SET ((1<<SM0)|(1<<SM1));
25e: 85 b7 in r24, 0x35 ; 53
260: 80 65 ori r24, 0x50 ; 80
262: 85 bf out 0x35, r24 ; 53
// ustawienie pinu PORTD.2 (INT0) jako wejście
DDRD RESET (1<<2);
264: 8a 98 cbi 0x11, 2 ; 17
// podciągnięcie do 1
PORTD SET (1<<2);
266: 92 9a sbi 0x12, 2 ; 18
// zezwolenie na przerwania INT0
GIMSK SET (1<<INT0);
268: 8b b7 in r24, 0x3b ; 59
26a: 80 64 ori r24, 0x40 ; 64
26c: 8b bf out 0x3b, r24 ; 59
// skasowanie flagi wystąpienia przerwania INT0
EIFR SET (1<<INTF0);
26e: 8a b7 in r24, 0x3a ; 58
270: 80 64 ori r24, 0x40 ; 64
272: 8a bf out 0x3a, r24 ; 58
while (1)
{
// globalne zezwolenie na przerwania
sei();
274: 78 94 sei
// wprowadzenie procesora w tryb POWER-DOWN
sleep_mode();
276: 85 b7 in r24, 0x35 ; 53
278: 80 62 ori r24, 0x20 ; 32
27a: 85 bf out 0x35, r24 ; 53
27c: 88 95 sleep
27e: 85 b7 in r24, 0x35 ; 53
280: 8f 7d andi r24, 0xDF ; 223
282: 85 bf out 0x35, r24 ; 53
284: f7 cf rjmp .-18 ; 0x274 <main+0x60>
jak pisałem wcześniej wszystko w tym kodzie działa idealnie a pobór prądu spada do - 6uA !!!! więc jest super
potem jeszcze sama procedura przerwania INT1, w której następuje u mnie akurat obsługa klawiszy - i to właśnie też to przerwanie wybudza procka ze śpiączki
SIGNAL(SIG_INT0)
{
// wyłączenie obsługi przerwań
cli();
//
// tylko na czas przerwania INT0 - przestawiony zostaje
// kierunek portów klawiszy. Zostają ustawione jako wejścia
// natomiast pin PORTD.2 (INT0) jako wyjście ze stanem niskim
// dzięki temu działa obsługa klawiszy
//
// ******* KLAWISZE
//
// ustawienie PORTD.2 , 3 , 4 i 5 jako wejścia
K_DDR RESET (KEY1|KEY2|KEY3|KEY4|KEY5);
// podciągnięcie wejść do 1
K_PORT SET (KEY1|KEY2|KEY3|KEY4|KEY5);
// przestawienie PORTD.2 jako wyjście
DDRD SET (1<<2);
// ustawienie stanu niskiego - do obsługi klawiszy
PORTD RESET (1<<2);
********************************************
...... tutaj kod do obeługi klawiszy ...........
********************************************
// przywracamy ustawienia
// ustawienie pinu PORTD.2 (INT0) jako wejście
DDRD RESET (1<<2);
// podciągnięcie do 1
PORTD SET (1<<2);
// ******* KLAWISZE
//
//
// ustawienie PORTD.2 , 3 , 4 i 5 jako wyjścia
K_DDR SET (KEY1|KEY2|KEY3|KEY4|KEY5);
// ustawienie stanu niskiego
K_PORT RESET (KEY1|KEY2|KEY3|KEY4|KEY5);
}
tak na marginesie to jak piszesz czy w asemblerze czy w każdym innym języku to polecem korzystać z nazw bitów i wyraźne ich włączanie / wyłączanie w kodzie - tak jak widać to u mnie - a wtedy o wiele trudniej o dokonanie jakiejś pomyłki czy pomyłek
pozdrawiam i powodzenia