Męczę się z tym już chyba z tydzień i nie mogę dojść co jest nie tak, może za długo gapię się w ten kod :-/
Mam urządzenie, które komunikuje się z atmegą, sygnały CLK i DATA podłączam sobie do wejść INT0 i INT1. W sumie to wymagane jest CLK <-> INT1, reszta to zaszłość ...
Wprowadzam atmegę w tryb powerdown i czasami nie chce się ona wybudzić. Jakieś 1 na 10-20 przypadków nie działa wybudzanie.
Może to być spowodowane jakimś hazardem, albo czymś, bo używam wybudzania poziomem 0 na INT1, a normalnie do pracy używam zboczy na INT1. Przypuszczam, że zanim pójdzie spać to INT1 jest źle ustawione.
Poniżej fragment kodu.
Próbowałem już różne wersje w procedurze sleep.
Zacząłem od prostego
Ale wyczytałem w sleep.h, że mogą pojawiać się problemy (hazardy) w pewnych sytuacjach, to zmieniłem na bardziej krokowy sposób włączania sleepa, ale problem pozostał.
Czy ktoś ma jakiś pomysł jak manipulować ustawieniem INT1, aby wybudzanie ze sleep działało zawsze?
Jeszcze jedno, problem ten występuje nawet jeśli w momencie wchodzenia do procedury sleep, przerwanie z INT1 nie jest wywoływane (brak sygnałów na wejściu INT1), więc nie ma tam jakiegoś problemu, że to przerwanie "zakłóca" pracę tej procedury.
inventco.eu - temat poprawiłem, regulamin p.11.1
Mam urządzenie, które komunikuje się z atmegą, sygnały CLK i DATA podłączam sobie do wejść INT0 i INT1. W sumie to wymagane jest CLK <-> INT1, reszta to zaszłość ...
Wprowadzam atmegę w tryb powerdown i czasami nie chce się ona wybudzić. Jakieś 1 na 10-20 przypadków nie działa wybudzanie.
Może to być spowodowane jakimś hazardem, albo czymś, bo używam wybudzania poziomem 0 na INT1, a normalnie do pracy używam zboczy na INT1. Przypuszczam, że zanim pójdzie spać to INT1 jest źle ustawione.
Poniżej fragment kodu.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
void init_extint1()
{
sbi(GICR, INT1); // Enable INT1 External Interrupt
sbi(MCUCR, ISC10); // Any logical change Triggered INT1
}
// External Interrupt 1 ISR == CLOCK ==
SIGNAL(SIG_INTERRUPT1)
{
Tu jest jakaś procedura, która tylko sprawdza stan na wejściu PD2 i włącza timer
}
int main()
{
init_extint1(); // Init External ISR1
sei(); // Enable Interrupts
while (1)
{
// sleep procedure
if (bit_is_clear(IGNITION_IN_PORT, IGNITION_PIN) && // if engine is off and
bit_is_set(POWER_IN_PORT, POWER_PIN)) // power is set off
{
cli();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cbi(MCUCR, ISC10); // set INT1 trigerred LOW level to wake up
sleep_enable();
sei();
sleep_cpu(); // go sleep
sbi(MCUCR, ISC10); // restore INT1 setting after wake up (any logical change Triggered INT1)
sleep_disable();
sei();
}
Ciąg dalszy...
}
Próbowałem już różne wersje w procedurze sleep.
Zacząłem od prostego
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
Ale wyczytałem w sleep.h, że mogą pojawiać się problemy (hazardy) w pewnych sytuacjach, to zmieniłem na bardziej krokowy sposób włączania sleepa, ale problem pozostał.
Czy ktoś ma jakiś pomysł jak manipulować ustawieniem INT1, aby wybudzanie ze sleep działało zawsze?
Jeszcze jedno, problem ten występuje nawet jeśli w momencie wchodzenia do procedury sleep, przerwanie z INT1 nie jest wywoływane (brak sygnałów na wejściu INT1), więc nie ma tam jakiegoś problemu, że to przerwanie "zakłóca" pracę tej procedury.
inventco.eu - temat poprawiłem, regulamin p.11.1