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

ATMEGA8, problem z przerwaniem (dzielnikiem f)

meninio 24 Kwi 2009 12:55 3128 20
REKLAMA
  • #1 6451348
    meninio
    Poziom 10  
    Witam serdecznie.
    Próbuję zrobić dzielnik częstotliwość na amtega8. Taktowanie 1 MHz.
    Narazie tak dla treningu robię sobie podział na 2.
    Sygnał podaję na INT0. I nawet mi to fajnie dzieli....ale jak częstotliwość dam powyżej 18kHz. To już nie dzieli..tzn dzieli ale częstotliwośc na wyjściu ustala się w granicach 9kHz i dalej nie idzie. Np. na wejścio INT0 dam 40kHz to na wyjściu dalej mam około 9kHz.
    Oto kod:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define INTO_rising MCUCR = (1<<ISC01) | (1<<ISC00) ; GICR = (1<<INT0) ;
    
    int a=0;
    
    SIGNAL (SIG_INTERRUPT0)
    {
    	a++;
    	if (a == 1 ) PORTD=0x01;
    	if (a == 2 ) { PORTD=0x00; a=0;}
    	
    }
    
    int main (void)
    {
       DDRD = 0x03
       INTO_rising;
       sei();
       while(1) {}
       return(0);
    } 
    


    Problem może tkwić w sprzęcie czy w programie?
  • REKLAMA
  • #2 6451369
    _Robak_
    Poziom 33  
    Jak bys zobaczyl ile trwa wejscie do procedury obslugi przerwania i wyjscie to bys sie nie zdziwl. Z tego co pamietam to taka operacja w przypadku timera zajmuje okolo 100 cykli teraz podziel 1MHz na 100 i wyjdzie ci 10KHz. Wiec calkiem podobna wartosc do twojej ;) Takze wykorzystaj asma a dobijesz do 40KHz spokojnie.

    EDIT: Cos mnie sie pomieszalo albo co z tymi 100 :) przerwanie z licznika trwa 28 cykli w tym jeden nop ktory trwa 3 cykle.

    EDIT2: No wiec dokonalem analizy ;) Dolozylem do przerwania z timera
     a++; 
       if (a == 1 ) PORTD=0x01; 
       if (a == 2 ) { PORTD=0x00; a=0;

    I czas na pelne obsluzenie tego przerwania wynosi dokladnie 53 cykle. Takze maksymalna czestotliwosc jaka mozesz obsluzyc przy pomocy tego programu to 1000000Hz/53=18.868KHz.
    Mam nadzieje ze wyjkasnilem wszystko ;) Oczywiscie prosciej, zamiast przesiadac sie na asm, dac kwarc 16MHz ;)
  • #3 6451481
    meninio
    Poziom 10  
    No to rozwiałeś moje wątpliwości. Tak myślałem, ale chciałem się upewnić.

    A ta częstotliwość, którą policzyłeś to rzeczywiście tak doświadczalnie wychodzi:)

    Dlatego zrobiłem wcześniej jeszcze jedna wersję.
    Zliczam impulsy na wejściu T0.

    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    #define Timer0_Start TCCR0 = (1 << CS02) |(1<< CS01) | (1 << CS00); 
    
    int main (void)
    {
       DDRD = 0x03;   // portu D to wyjścia
       Timer0_Start;
       while(1)
       {
    		if(TCNT0 == 1) PORTD=0x01;
    		if(TCNT0 == 2) 
    		{
    			PORTD=0x00;
    			TCNT0=0;
    		}
       }
       return(0);
    } 


    No i to nawet też sobie dzieli.
    Ale jak dam wyższe częstotliwości, powiedzmy 60kHz to ten prostokąt na wyjściu jakby na każdym zboczu miał jakby histerezę...i to porządną.
    Jeśli dam przykładowo na wejściu 10kHz to tę histerezę też widać, ale oczywiście jest mniejsza...

    To też winna sprzętu ??

    Tutaj daje przykład dla fwe=60kHz, fwy=30kHz ale.. sami zobaczccie:
    ATMEGA8, problem z przerwaniem (dzielnikiem f)
  • #4 6451499
    _Robak_
    Poziom 33  
    Powyzej tej f nie bedzie ci dzialac, b sygnal wejsciowy swoje a przerwania swoje. Po prostu sie to rozjezdza.
  • #5 6451529
    meninio
    Poziom 10  
    Ale w tym drugim wariancie nie korzystam z przerwań tylko z timera.
  • #6 6451624
    _Robak_
    Poziom 33  
    No ok, ale w tym kodzie jesli dobrze widze to timer sobie leci i to wszystko, nigdzie nic nie zliczasz czy tym podobne cuda. Swoja droga taki warunek if TCNT==1 jest bez sensu, bo mozesz akurat nie trafic.
  • #7 6451699
    meninio
    Poziom 10  
    Jak nie zliczam?? Przecież w rejestrze TCNT0 zapisywane są zliczane impulsy na wejściu T0...czy nie?
  • REKLAMA
  • #8 6451737
    Konto nie istnieje
    Poziom 1  
  • #9 6451739
    _Robak_
    Poziom 33  
    Ajj przepraszam, ustawienie wszystkich cs ustawia w tryb countera. W kazdym razie tak jak pisalem nie powinienes uzywac takiego porownania. Mozesz trafic trafic ze tcnt bedzie juz rowne 3 i ci sie program rozjedzie.
  • #10 6451811
    meninio
    Poziom 10  
    atom1477 napisał:
    Tak, ale sprawdzanie stanu TCNT0, czyli w zasadzie dzielenie, realizujesz programowo.
    Sprawdzanie stanu tak jak zrobiłeś jest totalnie bez sensu.


    To jak to sensowniej zrobić panowie?
  • #11 6451820
    _Robak_
    Poziom 33  
    Na przerwaniu zewnetrznym!
  • #12 6451859
    meninio
    Poziom 10  
    No to przecież już gadaliśmy o tym...ale udało się tylko przy taktowaniu 1MHz uzyskać dzielnie przez 2 maksymalnie przy 18kHz sygnału wejściowego. Rozumiem, że przy taktowaniu 16MHz będzie to 16*18kHz=288kHz.
    Mnie jednak interesuje większa częstotliwość do podziału, powiedzmy koło 2MHz... (im więcej tym lepiej)
    I dlatego myślałem że na Timerze będzie to lepiej chodziło...
    Jest w ogóle sens bawić się tym na procku, czy od razu przejść na szybkie liczniki np.74ls163??
  • REKLAMA
  • #13 6452316
    _Robak_
    Poziom 33  
    A nie latwiej zrobic na przerzutnikach cos takiego? 2MHz to sporo jak na AVRka i takiej f nie osiagniesz raczej.
  • REKLAMA
  • #14 6452379
    meninio
    Poziom 10  
    No tylko że podział musi być dowolny, tzn nie na stałe 2. Ma być zmieniany z klawiatury. Dlatego myslałem, że uda mi się prockiem zrobić jedno i drugie, ale chyba jednak podział będę wybierał prockiem, a samo dzielenie robił na licznikach
  • #15 6452727
    Konto nie istnieje
    Poziom 1  
  • #16 6453165
    meninio
    Poziom 10  
    No ale w tym trybie nie mogę dzielić przez liczby nieparzyste - tak wynika ze wzoru, więc to odpada.
  • #17 6453343
    Konto nie istnieje
    Poziom 1  
  • #18 6454578
    meninio
    Poziom 10  
    No to powiedz mi co mam wpisać do rejestru OCR1A, żeby podzielić przez 5, skoro jest taki wzór: fout=fio/(2N(1+OCR1A)) dla N=1.
  • #19 6454651
    Konto nie istnieje
    Poziom 1  
  • #20 6454760
    meninio
    Poziom 10  
    oki rozumiem
  • #21 6454773
    Konto nie istnieje
    Poziom 1  
REKLAMA