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

ATmega128 i Timer0 na 32,7kHz

rmk 20 Maj 2009 16:45 2288 7
REKLAMA
  • #1 6553183
    rmk
    Poziom 12  
    Witam.
    Mam problem. Mianowicie próbuje zmusić Timer0 do działania z kwarcem zegarkowym (w trybie asynchronicznym). Używając głównego kwarcu Timer0 działa.
    Poniżej fragment kodu odpowiedzialny za inicjacje timera:
    
    TCNT0 = timer0; // ustawienie wartosci początkowej
    ASSR |= (1<<AS0);//wlaczenie trybu asynchronicznego
    TIMSK |= (1<<TOIE0);
    TCCR0 |= (1<<CS00); //ustawienie preskalera
    sei(); //wlaczenie przerwan
    

    Próbowałem zrobic to wg noty atmegi ale tez nie działa. Zmieniałem kolejność poleceń, wpis do TCNT0 po ustawieniu bitu AS0 jest nie mozliwy. Kiedy pierwszy raz ustawiałem tryb asynchroniczny mogłem zapisać wartość początkową do TCNT0, ale po następnym razie juz sie nie dało. W rejestrze ASSR powinne się same wyzerować bity poza AS0 co u mnie się nie dzieje (z wyjątkiem pierwszego razu).
    Używam JTAG-a więc mam podgląd do rejestrów, stąd wiem co się w nich dzieje (tak, wiem, nie zawsze dobrze pokazuje ale to inna sprawa)
    Czy ktoś wie jak to rozwiązać albo nakieruje na właściwą ścieżkę?
  • REKLAMA
  • #2 6553410
    BoskiDialer
    Poziom 34  
    Nota atmela mówi, że jeśli timer pracuje w trybie asynchronicznym, to należy testować flagi Update Busy (3 flagi) w ASSR, po tym należy wyzerować flagę przerwania.
  • REKLAMA
  • #3 6553927
    rmk
    Poziom 12  
    Testować czyli odczytywać stan? Bo one się nie zmieniają... :/
    TIMSK &=~((1<<TOIE0)|(1<<OCIE0));   //wylaczenie przerwan
       ASSR |= (1<<AS0);                //wlaczenie trybu asynchronicznego
       TCNT0 = timer0;
       TCCR0 = 0x05;                   //ustawienie preskalera na 128
       while(ASSR&0x07);  
       TIFR &=~((1<<OCF0)|(1<<TOV0)); //czysczenie flag przerwan           
       TIMSK |= (1<<TOIE0); 

    No i się tak kręci w while'u...
    Ktoś ma jakiś pomysł, żeby to rozwiązać? Może ktoś ustawiał RTC na innej atmedze i mu działał?
  • #4 6554267
    BoskiDialer
    Poziom 34  
    Jeśli się kręci w while'u, to może kwarc który ma taktować timer nie rusza?
    ps. możesz w miarę możliwości inicjalizować timer (ASSR) przez przypisania, a nie ustawianie bitów? Ustawienie bitów wymaga odczytania wartości rejestru, a timer przy pracy asynchronicznej może się z tym kłócić (nie doczytałem do końca).
    ps2. Flagi przerwań kasuje się przez wpisanie w odpowiednie miejsce jedynki (proste skasowanie mogło by spowodować skasowanie innych flag a więc utratę przerwania)
  • REKLAMA
  • #5 6555648
    megaman123
    Poziom 13  
    "Ktoś ma jakiś pomysł, żeby to rozwiązać? Może ktoś ustawiał RTC na innej atmedze i mu działał?"

    Kiedyś robiłem na Atmega32 , i działało . Rożnica taka , że w A32 timer pracujący z oscylatorem zewnętrznym to Timer2

    ASSR = 1<<AS2;
    TCCR2 = 1<<CS22 | 1<<CS20;
    TIMSK = 1<<TOIE2;
  • #6 6555858
    kemot55
    Poziom 31  
    Działające rozwiązanie dla MEGA169:

    
    TCCR2A = (1<<CS22) | (1<<CS20); 
    ASSR = (1<<AS2);
    TCNT2=0;
    while(ASSR&0x07); //uwaga!!!
    TIFR2=TIFR2&0xFE;
    TIMSK2 = (1<<TOIE2);
    


    Przy takiej inicjalizacji brak zegara 32kHz spowoduje zablokowanie dalszego przetwarzania programu.
  • REKLAMA
  • #7 6556734
    rmk
    Poziom 12  
    OK. Źle był zamontowany kwarc. Poprawiłem go i działa. Prawie... Bo teraz wchodzi do przerwania ale po wyjściu z niego program jakby sie resetował i zaczyna od początku (ustawianie rejestrów, itd.). Nie wiem czemu tak jest, bo jak wpisze jakąkolwiek wartość do TCNT0 i Timer działa w trybie normalnym to działa poprawnie.
  • #8 6826394
    rmk
    Poziom 12  
    Troche długo mnie nie było ale miałem parę spraw na głowie.
    Co do tego Timera to ostatnio znów walczyłem i konfiguracja jest w porządku. Wina leży najprawdopodobniej gdzieś na płytce (bądź w procesorze), bo gdy podpiąłem kwarc do innej płytki z atmega128 to Timer działał bez zarzutu. Tak więc temat zamknięty.
    Dzięki wszystkim za pomoc!
    Pozdrawiam!

    P.S. Może jeszcze dla tych co też będą mieć problemy z timerem 0 w trybie asynchronicznym w atmedze 128 podam kod:
    void T0_init(void)
    {   
       TIMSK &=~((1<<TOIE0)|(1<<OCIE0));   //Disable TC0 interrupt
       ASSR |= (1<<AS0);                //set Timer/Counter0 to be asynchronous from the CPU clock with a second external clock(32,768kHz)driving it.
       TCNT0 = 0x00;
       TCCR0 = 0x05;                   //prescale the timer to be clock source 128 to make it exactly 1 second for every overflow to occur
       while(ASSR&0x07);                //Wait until TC0 is updated
       TIMSK |= (1<<TOIE0);             //set 8-bit Timer/Counter0 Overflow Interrupt Enable
    }


    Pozdrawiam!
REKLAMA