logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8][C] nie działa wybudzanie z powerdown

_Arecki_ 22 Sty 2010 08:49 2665 8
REKLAMA
  • #1 7572535
    _Arecki_
    Poziom 15  
    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.

    
    #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
  • REKLAMA
  • #2 7576661
    asembler
    Poziom 32  
    Qybudzanie tylko niskim poziomem na wejsci a co długosci trwania to PDF
  • REKLAMA
  • #3 7578238
    _Arecki_
    Poziom 15  
    Wydaje mi się, że sygnał, który używam do wybudzania jest prawidłowy.
    Tak jak napisałem przed uśpieniem procka ustawiam INT1 na wyzwalanie poziomem niskim, a tylko do pracy używam wyzwalania zboczem.
    Sygnał podawany na INT1 to sygnał zegarowy, więc jego czas trwania poziomu niskiego jest stały, więc skoro czasami się wybudza, to uważam, że jest prawidłowy (wystarczająco długi za każdym razem).
  • REKLAMA
  • Pomocny post
    #4 7578271
    asembler
    Poziom 32  
    To sprobuj wybudzac recznie a nie za pomoaca CLK i zobaczysz czy przyczyną jest długosc sygnalu '0". Kiedys mialempodobny problem nie wnikajac w szczegóły dale diode i kondensator na wejscie INT1 i osiagnąlem 100% wybudzen oczywiscie pod warunkie ze to wejscie tylko uzywasz do wybudzen.
    Zwróc uwagę ze kazdy procesor startuje w okreslonym czasie po wybudzeniu i trwa to 256, 1024 lub 16k cykli tablica 5 PDF atmega8 i jeseli w tym czasie zaniknie sygnał wybudzajacy to moze nie dojsc do wybudzenia (a może sie myle?).

    Moze wystarczy odpowiedniou fuse ustawic? SUTn
  • #5 7579416
    _Arecki_
    Poziom 15  
    Spróbowałem po nieudanej próbie wybudzenia sygnałem CLK zrobić to ręcznie i nie mogłem. Mimo zwarcia INT1 do masy procek nie wstawał :-/
    Więc chyba to jest jakiś problem w samym procku.

    Jeśli to ma znaczenie to używam kwarca 16MHz w tej atmedze, bo 8MHz był za wolny. Ogranicza to manewry z czasem wstania z uśpienia do 16K CK.
  • #6 7579882
    asembler
    Poziom 32  
    To juz nie wiem moze procek uszkodzony?
    Wymien i napisz czy pomogło ale raczej to program bedzie.
  • REKLAMA
  • #7 7581745
    _Arecki_
    Poziom 15  
    To nie wina procka, bo testowałem na kilku sztukach i jest tak samo.
    Spróbuję jeszcze z tymi ustawieniami SUT, ale nie wiem czy to pomoże.
  • #8 7582233
    asembler
    Poziom 32  
    Patrzylem na swoj program pilota uniwersalnego w którym stosuje power down i tam oprocz ustawienia wybudzania ma jeszcze ustawione aktywne przerwanie zewnetrzne i oczywiscie napisaną obsluge przerwania.

    Dodano po 2 [minuty]:

    moze zamiast zerowac pojedynczy bit w MCUCR wpisz cała wartosc do tego rejestru, gdyz nie widze gdzie ustawiasz ISC11, a jezeli zakladasz ze tam jest zero to sprawdz czy faktycznie.
    Spróbuj dac opoznienie okolo 100ms po rozkazie sleep dla próby i napisz co sie dzieje
  • #9 7599477
    _Arecki_
    Poziom 15  
    Dzięki asembler, po serii testów wydaje się, że działa.
    Pomogła zmiana ustawienia CKSEL0/SUT.
    Mimo, że dla 16MHz kwarca ustawienie "Start-up Time from Power-down and Power-save" poniżej 16K CK nie jest zalecane to w moim przypadku to pomogło i wszystko działa.
REKLAMA