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

Timer/Counter0, przerwanie po przepełnieniu

boohoo 20 Lut 2009 17:54 1467 5
REKLAMA
  • #1 6179215
    boohoo
    Poziom 12  
    Witam,

    Napisałem program, gdzie po przepełnieniu generowane jest przerwanie. Poniżej kod:

    
    #include <avr\io.h>
    #include <avr\delay.h>
    #include <avr\signal.h>
    #include <avr\interrupt.h>
    
    #define D1 0
    #define D2 1
    #define D3 1
    #define BUZZ 0
    
    #define TSOP1 5
    #define SW1 3
    #define SW2 2
    
    
    uint16_t k=0;
    
    int main(void)
    {
    DDRA=1<<D1 | 1<<D2;
    DDRD=1<<D3 | 1<<BUZZ;
    
    
    TCCR0B |= 1 << CS00;	
    TIMSK |= 1 << TOIE0;
    //TCNT0 = 0x0;
    
    sei();                
    
    
    while(1);
    
    return 0;
    }
    /////////////////////////////////////////////////
    SIGNAL (SIG_TIMER0_OVF) 
    {
    //TCNT0 = 0x0;
    k++;
    if(k==30000)
     {
            PORTA = 1 << D1 | 1 << D2;
     }
    if(k==60000)
     {
            PORTA = 0x0;
    	k=0;
     }
    }
    


    fclk=1MHz
    licznik 8bitowy

    Wykonałem obliczenia:
    256/1000000=0.256ms (co taki czas generowane jest przerwanie)

    Żeby sprawdzić, czy rzeczywiście tak jest, co 30000 wywołania zapalam diody, po kolejnych 30000 gaszę je. Wg obliczeń dioda powinna być włączona przez 7.68s i przy powyższym kodzie tak to mniej więcej wygląda, gdy mierzę stoperem. Problem pojawia się, gdy odkomentuję wpis do rejestru TCNT0. Wtedy czas wydłuża się do ok 9.2s.

    Byłbym wdzięczny za wskazówki, co robię nie tak, dlaczego tak się dzieje. Dodam, że od bardzo niedawna mam styczność z uC, więc nie wszystkie rzeczy są dla mnie oczywiste.
  • REKLAMA
  • #2 6179253
    Freddie Chopin
    Specjalista - Mikrokontrolery
    zanim uklad dojdzie do twojej liniki pare cykli mija (zachowanie rejestrow, sama reakcja na przerwanie) - powiedzialbym ze tak z 10-20 cykli, wiec nie dziw sie... w momencie w ktorym zerujesz ten rejestr ma on juz jakas tam wartosc i tyle - cala filozofia.

    4\/3!!
  • REKLAMA
  • #3 6179293
    boohoo
    Poziom 12  
    Rozumiem... Docelowo zależy mi na generowaniu impulsów z częstotliwością 36kHz, z którą nadawałaby dioda nadawcza IR, żeby móc wykorzystać odbiornik podczerwieni TSOP1736.
    Chciałem ustawić TCNT0 na 228, dzięki czemu otrzymałbym ok. 35.714kHz. Tylko wychodzi na to, że wcale tak nie będzie...

    Macie może konkretne pomysły, jak uzyskać w praktyce te 36kHz?
  • REKLAMA
  • #4 6179347
    krzemowy
    Poziom 19  
    Skąd wziąłeś te 228 wpisywane do TCNT0? Mi wychodzi jak w pysk strzelił 28. A i to w sumie nie jest poprawna wartość bo 28 cykli trwa okres przebiegu 36kHz, pojedynczy stan okresu trwa połowę z tego(przy założeniu wypełnienia 50%).

    Hint - użyj trybu CTC. Programowo przepisując w przerwaniu rejestr licznika tak dużej częstotliwości przy tak małym kwarcu nie uzyskasz, ogólnie mówiąc nie jest to dobra metoda bo generowany przebieg będzie zawsze mniej lub bardziej opóźniony.
  • REKLAMA
  • #5 6179356
    ks_fenix
    Poziom 23  
    W praktyce działa to tak, że większość odbiorników na 36kHz odbiera w przedziale 34-38kHz, a nawet więcej bez znaczących strat
  • #6 6183502
    boohoo
    Poziom 12  
    Dzięki za odpowiedzi. Problem rozwiązany. Na razie, na czas zaznajomienia się z trybem CTC, wykorzystuję pierwotny pomysł. Konieczna była zmiana Fusebitów, bo fclk=1MHz, to za mało. Wyłączyłem więc wewnętrzny dzielnik, dzięki czemu mam fclk=8MHz. Wyliczyłem wartość, którą trzeba wpisać do TCNT0 biorąc poprawkę na te "gubione" cykle, wspomniane przez Freddiego. Poprawkę tą dobrałem doświadczalnie mierząc stoperem czas świecenia diody i porównując z wartością teoretyczną. Dzięki temu mogę generować sygnał z f=36,036kHz +/- 300Hz

    Wszystko działa jak należy.
    Pozdrawiam
REKLAMA