04-07-2019, 21:35
(Ten post był ostatnio modyfikowany: 04-07-2019, 21:43 przez Robson Kerman.)
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.
2) Funkcja wyłączjąca Timer1.
3) Funkcja obsługi przerwania od porównania.
No i kilka globalnych zmiennych:
bool flaga = true;
volatile byte licznik;
W funkcji loop() w warunku if (distance <= && distance >= 0), należy wpisać:
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:
Należy w warunku:
Dopisać:
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ć.
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.