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

dziwne zachowanie timera (CTC)

leo1 09 Paź 2009 19:25 1302 5
REKLAMA
  • #1 7108662
    leo1
    Poziom 14  
    Witam.
    Uczę sie programować timery na atmega8 w c++. Robie to z pomocą kursu: http://wkretak.pl/readarticle.php?article_id=3 i noty katalogowej oczywiście.
    Napisałem coś takiego i działa zakomicie:
    #define F_CPU 4000000L
    #include <avr/io.h>
    
    int main (void)
    {
    DDRD |= (1 << 7);
    TCCR1B |= (1 << WGM12);
    OCR1A = 15625;
    TCCR1B |= (1 << CS12);
    
    while(1)
    {
    
    if (TIFR &(1<< OCF1A))
    {
    PORTD ^= (1 << 7); // Zmień stan diody LED
    TIFR=(1<<OCF1A); 
    }
    }
    }

    efekt: dioda zapala i gaśnie co sekundę

    Przeczytałem, że istnieje jeszcze jeden kanał "B", lecz gdy zamieniam wszystko na:OCR1B, OCF1B, to dioda się zapali ale już nie zgaśnie. Co dziwniejsze, gdy zamienię tylko:OCR1A, OCF1B, to układ działa jak pierwotnie, a chyba nie powinien, bo nie podaje wartości OCR1B.

    Jest ktoś kto może mi wytłumaczyć tą zagadkę?
  • REKLAMA
  • #2 7108992
    ZbeeGin
    Poziom 39  
    Odpowiedź jest prosta i można ją wyczytać nawet z tabelki ustawień WGM1x: Tryb CTC wykorzystuje m.in. OCR1A do ustalenia wartości TOP licznika TCNT1, czego OCR1B nie potrafi zrobić samodzielnie.

    Jeśli chcesz skorzystać z obu przerwań OCR w wybranym przez Ciebie trybie CTC, to OCR1A i tak musisz ustawić tak jak obecnie by "skrócić" licznik. Natomiast OCR1B musi mieć wartość MNIEJSZĄ niż OCR1A by mieć wogóle szansę na zgłoszenie swojego przerwania. Przy większej licznik nie ma szans tam nawet doliczyć!

    Jest jeszcze jeden tryb CTC liccznika TIMER1, o którym przypomniał Mi kolega zumek. Zatem wnikliwe czytanie noty katalogowej to Twoje zadanie na najbliższe dni.
  • REKLAMA
  • #3 7110377
    leo1
    Poziom 14  
    Poprawiłem kod:
    
    #define F_CPU 4000000L
    #include <avr/io.h>
    
    int main (void)
    {
    DDRD |= (1 << 7); 
    DDRD |= (1 << 6);
    TCCR1B |= (1 << WGM12);
    OCR1A = 15625;
    OCR1B = 500;
    TCCR1B |= (1 << CS12);
    
    while(1)
    {
    
    if (TIFR &(1<< OCF1A))
    {
    PORTD ^= (1 << 7); // Zmień stan diody LED
    TIFR=(1<<OCF1A); 
    }
    if (TIFR &(1<< OCF1B))
    {
    PORTD ^= (1 << 6); // Zmień stan diody LED
    TIFR=(1<<OCF1B); 
    }
    }
    }

    Jeśli dobrze zrozumiałem to teraz powinienem otrzymać diode B, która ma okres ok 30 razy większy od tej A,jednak zapalają się one na zmiane zgodnie z okresem tej A (ok 2 s).
    O co moży tym razem chodzić?
  • REKLAMA
  • #4 7110493
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #5 7111168
    ZbeeGin
    Poziom 39  
    leo1 napisał:
    Jeśli dobrze zrozumiałem to teraz powinienem otrzymać diode B, która ma okres ok 30 razy większy od tej A,jednak zapalają się one na zmiane zgodnie z okresem tej A (ok 2 s).

    Nie zrozumiałeś.

    leo1 napisał:
    O co może tym razem chodzić?

    O niezastosowanie się do wskazówki końcowej, mówiącej o lekturze noty katalogowej.
  • #6 7118224
    leo1
    Poziom 14  
    ZbeeGin < Bardzo dziekuje za pomoc w zrozumieniu zagadnienia, ale może masz tę notę w języku polskim, gdyż mój angielski "techniczny" nie jest imponujący.
REKLAMA