• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Jak ustawić funkcje czasu wyjścia na określony i off
#14
Zasadniczo, to można sobie pomieszać styl arduinowy ze stylem AVR-GCC.
Oczywiście te nazwy, to wytwór własny.

Potrzebne nam będą:

1) Funkcja włączająca Timer1.
Kod:
void timerStart()
{
    PRR &= ~(1 << PRTIM1);
    TCCR1A = (1 << WGM11); 
    TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS12) | (1 << CS10);
    ICR1   = 46875;
    TIMSK1 = 1 << OCIE1B;
    flaga = false;
    digitalWrite(Elektrozawor, HIGH);
}

2) Funkcja wyłączjąca Timer1.
Kod:
void timerStop()
{
    TCCR1B = (0 << CS12) | (0 << CS11) | (0 << CS10);
    digitalWrite(Elektrozawor, LOW);
}

3) Funkcja obsługi przerwania od porównania.
Kod:
ISR(TIMER1_COMPB_vect)
{    licznik++;
    if (licznik==2)
    {
    licznik = 0;
    timerStop();
    }
}

No i kilka globalnych zmiennych:

bool flaga = true;
volatile byte licznik;

W funkcji loop() w warunku if (distance <=  && distance >= 0), należy wpisać:
Kod:
if (flaga) timerStart();

Oczywiście zamiast tego wszystkiego, co obsługuje włączenie elektrozaworu, czyli wywal digitalWrite(Elektrozawor, HIGH);
Funkja timerStart() uruchamia nasz Timer1 w trybie Fast PWM, z preskalerem 1024.
Zezwala na przerwania od porównania i ustawia pin elektrozaworu na HIGH.
Licznik liczy 46875 tiknięć, co jak mi się wydaje, oznacza że minęły 3 sekundy.
Do sześciu sekund się nie da, ponieważ ICR1 może wynosić najwyżej 65535 (10bit).
Jest tam jeszcze reset flagi, co znaczy że do puki jej nie ustawimy, warunek z funkcji loop() się nie spełni i nie załączy nam liczenia czasu od nowa.
Gdy miną 3 sekundy, wyzwolone zostanie przerwanie.
Funkcja go obsługująca doda wtedy 1 do zmiennej licznik.
Następne przerwanie spowoduje spełnienie warunku if (licznik==2), czyli zerujemy licznik i wywołujemy funkcję timerStop(), która wyłącza źródło taktowania dla Timera1, oraz ustawia pin elektrozaworu na LOW.
Aby zresetować flagę zezwalającą na następne spełnienie warunku:
Kod:
if (distance <= 10 && distance >= 0) {

        if (flaga) timerStart();
        
    }


Należy w warunku:

Kod:
else
  {
    digitalWrite(Red, LOW);
    digitalWrite(Green, HIGH);
    digitalWrite(Elektrozawor, LOW);
    delay(300);
  }

Dopisać:

Kod:
flaga = true;

No i jeszcze takie pytanie:
Po co są te delaye? Wywal to w diabły!

A cha i jeszcze taka mała dygresja:
Na granicy dystansu jaki sobie tam obrałeś, elektrozawór będzie miał, jak by to określić, jakby trzaski. Coś w stylu drgań styków w przełącznikach, więc powinieneś się tym zająć.

Oczywiście powyższe funkcje, to taki mój szybki research w tym kierunku, więc należy to traktować z pewnym dystansem. Trzeba wziąć manuala do ręki i porządnie sobie wszystko zaplanować, bo nie wiem czy Fast PWM to będzie odpowiedni tryb.
No i można zamiast zliczać programowo do dwóch, wyzwalać sprzętowy licznik i całkowicie odciąć się od rdzenia i stosu.
Ale już mi się nie chciało grzebać, chociaż jeśli masz ochotę ta to rozwiązanie, to mogę coś naskrobać.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Wiadomości w tym wątku
RE: Jak ustawić funkcje czasu wyjścia na określony i off - przez Robson Kerman - 04-07-2019, 21:35

Skocz do:


Przeglądający: 1 gości