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

[C] obsługa TIMER1 do pomiaru czasu bez przerwania

mototest 19 Lis 2010 11:44 1232 6
  • #1 8762579
    mototest
    Poziom 19  
    WItam

    Mam problem z Timerem1, chcę żeby zliczał impulsy bez użycia przerwania,
    tzn podaję przebieg prostokątny na dowolny pin procesora i T1 ma zliczać ilość taktów w czasie trwania stanu niskiego, czyli mierzyć czas impulsu zerowego, napisałem poniższy listing i wyświetla głupoty (około 13000), podaję 2kHz czyli T1 powinien zliczyć do 2000 bo okres jest 500us co daje 250us na stan niski i przy prescale 1 i kwarcu 8Mhz (0.125us/takt) daje 250us/0.125us = 2000, co jest źle?
    
    uint16_t czas;
    DDRB &= 0b11111110;
    TCCR1A = 0;
    TCCR1B |= _BV(CS10);//start timer z prescale 1
    
     for(;;) 
     {
      
    
    while(bit_is_set(PINB,0)) //czekaj aż skończy się stan H
    {}
    // początek stanu L
    TCNT1=0;
    while(bit_is_clear(PINB,0)) //czekaj aż skończy się stan L
    {}  
    czas=TCNT1;
    lcd_goto(0);
    lcd_puts("T1=");
    itoa(czas, dana, 10);
    lcd_puts(dana);
    _delay_ms(500);  
    
     } 
  • #2 8762680
    hotdog
    Poziom 26  
    mi to wygląda dobrze. Obliczenia trafne, program też ok...

    Rozumiem że "dana" jest zadeklarowana gdzieś wcześniej. Sprawdz dla pewności czy jak napiszesz
    itoa(2000, dana, 10);
    lcd_puts(dana);
    Czy to wyświetli Tobie na LCD 2000 poprawnie.

    Poza tym z czego masz generator? Może on daje ciała? Może masz coś z fusami źle?
    Pozdro.
  • #3 8762696
    mototest
    Poziom 19  
    char dana [16];

    kurcze, zaczęło działać, nie wiem dlaczego
  • #4 8762742
    hotdog
    Poziom 26  
    <rotfl> może wcześniej wgrywałeś ten sam soft, albo kompilowałeś te same nie zapisane pliki. Takie jaja często wychodziło w AVR Studio.
  • #5 8763011
    mototest
    Poziom 19  
    mam jeszcze teoretyczne pytanie, jak mierzę ten czas np. dla 2kHz , widzę na oscyloskopie i generatorze ,że jest dokładnie 2kHz a procek pierzy 2030 taktów T1
    czyli spóźnia się o 30 taktów= 3.75us ,dla 1kHz 15 taktów, dlaczego tak dużo ?
  • #6 8763169
    hotdog
    Poziom 26  
    Pamiętaj że to procesor 8 bitowy i jak wykorzystujesz timer 16-biotwy, to operacje na rejestrze trwają kilka cykli. Odrobinę dokładniej byś miał jak zrobił to tak:

    uint16_t czas;
    DDRB &= 0b11111110;
    TCCR1A = 0;
    //TCCR1B |= _BV(CS10);//Nie włączaj tutaj timera
    
    TCNT1 = 0;
    
     for(;;)
     { 
    while(bit_is_set(PINB,0)) //czekaj aż skończy się stan H
    {}
    // początek stanu L
    TCCR1B |= _BV(CS10); //włącz timer
    while(bit_is_clear(PINB,0)) //czekaj aż skończy się stan L
    {} 
    TCCR1B &= ~_BV(CS10); //zatrzymaj timer
    czas=TCNT1;
    lcd_goto(0);
    lcd_puts("T1=");
    itoa(czas, dana, 10);
    lcd_puts(dana);
    TCNT1 = 0;
    _delay_ms(500); 
    
     } 


    W ten sposób pomijasz instrukcję na zmiennych 16-bitowych w sekcji krytycznej. Poślizg będzie dokładnie 4 cykle w tym przypadku.


    No a tak poza tym, to masz błąd około 1,5%? Wydaje mi się że mniej lub bardziej się to mieści w błędzie odczytu itd.
    Oscyloskop analogowy ma dosyć duży błąd odczytu. Więc może generator nie jest dokładny.
  • #7 8763187
    mototest
    Poziom 19  
    ok, dzięki wszystko jasne
REKLAMA