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: Timer0 z kwarcem zegarkowym w trybie asynchronicznym nie działa

rmk 20 Maj 2009 16:45 2354 7
REKLAMA
  • #1 6553183
    rmk
    Poziom 12  
    Posty: 35
    Pomógł: 3
    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  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    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  
    Posty: 35
    Pomógł: 3
    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  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    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)
  • #5 6555648
    megaman123
    Poziom 13  
    Posty: 121
    Pomógł: 2
    "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;
  • REKLAMA
  • #6 6555858
    kemot55
    Poziom 31  
    Posty: 1304
    Pomógł: 183
    Ocena: 146
    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  
    Posty: 35
    Pomógł: 3
    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  
    Posty: 35
    Pomógł: 3
    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!

Podsumowanie tematu

✨ Dyskusja dotyczy problemów z uruchomieniem Timera0 w mikrokontrolerze ATmega128 w trybie asynchronicznym z kwarcem zegarkowym 32,768 kHz. Użytkownik próbował inicjalizować Timer0 zgodnie z dokumentacją Atmegi, jednak rejestr ASSR nie zachowywał się zgodnie z oczekiwaniami, a zapis do TCNT0 po ustawieniu bitu AS0 był niemożliwy. Wskazano konieczność testowania flag Update Busy w ASSR oraz poprawnego czyszczenia flag przerwań przez wpisanie jedynki. Sugerowano, że problem może wynikać z braku oscylacji kwarcu lub błędnej inicjalizacji rejestrów. Przykłady działającej konfiguracji asynchronicznego timera podano dla ATmega32 i ATmega169, gdzie używany był Timer2 z odpowiednim ustawieniem ASSR i TCCR2. Po poprawnym zamontowaniu kwarcu Timer0 zaczął działać, lecz pojawił się problem z resetowaniem programu po wyjściu z przerwania. Ostatecznie problem okazał się leżeć w uszkodzeniu płytki lub procesora, gdyż na innej płytce z ATmega128 Timer0 działał poprawnie. Podano przykładowy kod inicjalizacji Timera0 w trybie asynchronicznym z preskalerem 128, z uwzględnieniem oczekiwania na wyzerowanie flag ASSR.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA