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

[Atmega16][C]Timery w atmedze

lemos 03 Maj 2010 12:34 2625 13
REKLAMA
  • #1 8029319
    lemos
    Poziom 17  
    Witam,
    jestem początkujący w temacie mikrokontrolerów.
    Mam taki problem do rozwiązania a nie za bardzo rozumiem te timery.
    Mianowicie chodzi o to aby wykonać pewną akcję gdy pojawią się sygnały 1 na dwóch wejściach PB1 i PB2 jednocześnie i będą one aktywne przez 3 sek. Jeśli choć jeden sygnał zniknie przed upływem tych 3 sek to timer ma się zerować i przy następnej sytuacji PB1 i PB2 =1 zacząć liczyć od początku. Ma to działać na zasadzie opóźnionego załączenia.
    Pozdrawiam serdecznie
  • REKLAMA
  • #2 8029486
    GienekS
    Poziom 32  
    Ja do takich celów napisałem taką funkcję
    /**********************************************************************/
    /* Funkcja ustawia wszystkie wskazniki M_Byl* i M_Jest */
    
    void Zmiana_Kxx (void)
    {
    u08 i, roznica;
    
    	for (i=0; i<ILOSC_IO; i++)
    	{
    	 roznica   = (I[i] & ~M_Old[i]) + (~I[i] & M_Old[i]);
    	 M_Jest[i] = I[i] & roznica;
    	 M_Byl[i]  = M_Old[i] & roznica;
    	 M_Old[i]  = I[i];
    	}
    }
    
    Tablice M_Jest i M_Byl są bitami pojawiania się i zanikania sygnałów, które chcemy zweryfikować. Stany statyczne są proste do diagnozowania. Natomiast wykrywanie zbocz sygnałów ta funkcja załatwia. Jak nie trudno zauważyć bity w tablicach M_Jest i M_Byl trwają tylko jedno wywołanie funkcji, przy następnym odpowiedni bit są zerowany.
    Tablica I[i] to kopia rejestrów wejściowych portów procesora, które musimy diagnozować.
  • Pomocny post
    #3 8029510
    tadzik85
    Poziom 38  
    Po wykryciu obecności obu sygnałów startujesz (lub zerujesz) timer po odczekaniu 3 sec w przerwaniu ponownie sprawdzasz stan wejść i wykonujesz odpowiednią akcję, ewentualnie ustawiasz flagę i w pętli głównej realizujesz obsługę zdarzenia
  • REKLAMA
  • #4 8029627
    lemos
    Poziom 17  
    Witam, no właśnie staruje timer ale jak ? i jak go stopuję? a najważniejsze to jak ustawić aby po wystartowaniu timera wygenerował on przerwanie po czasie 3 sek.
    Pozdrawiam
  • #5 8029640
    tadzik85
    Poziom 38  
    Start i stop realizowany jest przez wybór preskalera. Aby uzyskać 3 s musisz przeliczyć dla twojej wartości ilość potrzebnych taktów dla 3 sekund wybrać preskaler i odpowiedni wartość początkową licznika. Zalecam dokumentację.
  • #6 8029671
    lemos
    Poziom 17  
    Witam,
    a mógłbyś podrzucić jakiś przykładowy kod jak to ustawić, kwarc to 8MHz.
    Pozdrawiam
  • REKLAMA
  • #7 8029694
    tadzik85
    Poziom 38  
    Dla 8Mhz przy preskalerze 256 potrzebujesz 31250. Możesz wykorzystać np tryb CTC. Rejestr licznika zerujesz. COMPA ustawiasz na 31250. Preskaler wybierasz na 256 (timer startuje natychmiast). Włączasz przerwanie COMPA.

    Oczywiście mowa tu o liczniku 16-bitowym.

    Tu masz wszystko ładnie wyjaśnione.
  • #8 8029787
    landy13
    Poziom 31  
    tadzik85 napisał:
    Dla 8Mhz przy preskalerze 256 potrzebujesz 31250. Możesz wykorzystać np tryb CTC. Rejestr licznika zerujesz. COMPA ustawiasz na 31250. Preskaler wybierasz na 256 (timer startuje natychmiast). Włączasz przerwanie COMPA.

    Oczywiście mowa tu o liczniku 16-bitowym.

    Tu masz wszystko ładnie wyjaśnione.
    Podane ustawienia odliczają jedną sekundę. Dla trzech sekund preskaler 256 nie wystarczy - musi być 1024.
  • #9 8029791
    tadzik85
    Poziom 38  
    Sorry mój błąd. Ostatnio dużo 1sec odmierzałem stad pomyłka. Ale nie zobaczy link i przejrzy dział FAQ pod-forum AVR.
  • REKLAMA
  • #11 8030175
    lemos
    Poziom 17  
    Witam,
    dziękuję bardzo za cenne wskazówki jak rozwiązać mój problem. Stworzyłem kod i proszę o sprawdzenie czy takie coś ma szansę zadziałać.
    Pozdrawiam serdecznie

    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    
    
    ISR(TIMER1_COMPA_vect)
    {
    
    
    ///dowolna akcja
    
    
    }
    
    
    int main (void)
    {
    
    TCCR1B |= (1 << WGM12); // Ustawia timer w tryb CTC
    OCR1A = 31250; // Ustawia wartość pożądaną na 1Hz dla preskalera 1024
    TIMSK |= (1 << OCIE1A); // Zezwolenie na przerwania dla CTC
    sei(); // Zezwolenie na globalne przerwania
    
    
    while(1)
    {
    
    
    if(bit_is_set(PINB, 2) & bit_is_set(PINB, 3))
    
    {
    
    TCCR1B |= (1<<CS10)|(1<<CS12); //preskaler 1024, załączenie timera
    
    }
    
    else
    {
    
    TCCR1B &= ~((1<<CS10)|(1<<CS12));   // Wylaczenie timera1 
    
    TCNT1 = 0; //wyzerowanie licznika nie wiem czy potrzebne
    
    }
    
    
    }
    
    
    }
    
  • Pomocny post
    #12 8030196
    tadzik85
    Poziom 38  
    Wygląda w porządku. Na razie jest tak ze oba przyciski musisz mieć przyciśnięte przez min3sec i wówczas wywołana zostanie akcja.

    Dodano po 1 [minuty]:

    A to zerowanie jest konieczne
  • #13 8030325
    landy13
    Poziom 31  
    A częstotliwość będzie wynosić 0,25Hz a nie 1Hz.
  • #14 8030326
    lemos
    Poziom 17  
    Witam,
    i właśnie o to chodzi :). Teraz tylko przetestuje na gotowym układzie. Do tej pory robiłem to delay_ms ale to mi blokowało procesor i nie były wykonywane inne czynności.

    Sorki tam jest błąd w komentarzu nie miało być 1Hz tylko 3sek.

    Wielkie dzięki za pomoc i pozdrawiam
REKLAMA