Skocz do zawartości

[atmega8][C] Jak generować jeden impuls?


yogu$

Pomocna odpowiedź

Witam

Pracuję nad projektem, który wymaga bardzo krótkich czasów sygnałów, rzędu kilkudziesięciu ms. Opracowałem program, który co prawda poprawnie wysyła impuls, jednak jest on "bezpieczny" tylko dla długich czasów sygnałów. W moim przypadku istnieje duże ryzyko, że guzik zostanie przyciśnięty dłużej i urządzenie się wykrzaczy, bo sygnał był wysyłany za długo. Podsumowując: sygnał na wyjściu ma być zawsze taki sam, rzędu kilkudziesięciu milisekund, nie ważne jak długo będzie się wciskać guzik. Po puszczeniu guzika i jego ponownym wciśnięciu cykl ma zacząć się od nowa.

Zaznaczam, że jestem (mocno) początkującym w dziedzinie AVR i programowaniu ogólnie, dlatego też proszę o jak najbardziej łopatologiczne tłumaczenie. Może da się oprzeć program jedynie na delay'ach...

Moich bazgrołów nie ma sensu tu zamieszczać, więc dam jedynie szkielet (działający) mojego programu który chciałbym rozbudować z Waszą pomocą.

#include <avr/io.h>
#include <util/delay.h>

#define F_CPU 1000000

int main(void)
{
  DDRB = 0; // guzik - wejscie
  DDRC = 0xFF; // dioda - wyjscie

  PORTB |= _BV(0); 
  PORTC |= _BV(0);  // dioda zgaszona
  for(;;)
     {
        if(bit_is_clear(PINB, 0))
           {
              PORTC &= ~(_BV(0));   //  dioda zapalona
              _delay_ms(2500);
              PORTC |= _BV(0);  // dioda zgaszona
           }
     }
return 0;
} 
Link do komentarza
Share on other sites

Jak masz przycisk podłączony, naciśniecie ściąga do + czy do masy (-) ?

Ja bym spróbował zmienić kod:

 
              PORTC &= ~(_BV(0));   //  dioda zapalona 
              _delay_ms(2500); 
              PORTC |= _BV(0);  // dioda zgaszona 

na:

PORTC &=~(_BV(0));
_delay_ms(czas_w_ms); 
PORTC |= _BV(0);   
_delay_ms(1000); //czas po jakim będzie możliwe generowanie kolejnego impulsu
//jeśli dasz kolo 200 i mniej to mogą dać o sobie drgania styków

da to impulsy "podłączenia do masy" na czas który ustawisz nie częściej niż co 1000 ms

Jednak urzycie _dely_ms() nie zapewnia dużej dokładności

  • Lubię! 1
Link do komentarza
Share on other sites

Program Twój jest ok, ale impuls będzie wysyłany wielokrotnie jak ktoś będzie trzymał przyciśnięty klawisz. To można łatwo zmienić.

Dodaj zmienną "a", która będzie miała 3 wartości:

0-klawisz nie wciśnięty

1-klawisz wciśnięty, ale impuls nie wysłany

2-klawisz wciśnięty, impuls już wysłany

Pomysł jest prosty. Zmienna "a" startuje z wartością 0. Jak ktoś naciśnie klawisz to jej wartość zmieni się na 1. Przy wartości 1 wywołasz impuls i zmieniasz wartość na 2. Teraz tak długo jak jest wciśnięty klawisz wartość będzie 2 i następny impuls nie zostanie wysłany. Dopiero po puszczeniu klawisza wartość wróci na 0 i będzie można wysłać kolejny impuls przy ponownym naciśnięciu klawisza.

Na szybko przerobiony program wygląda tak:

#include <avr/io.h>
#include <util/delay.h>

#define F_CPU 1000000

int main(void)
{
  char a;
  a = 0;
  DDRB = 0; // guzik - wejscie
  DDRC = 0xFF; // dioda - wyjscie

  PORTB |= _BV(0);
  PORTC |= _BV(0);  // dioda zgaszona
  for(;;)
     {
        if ((a==0) && (bit_is_clear(PINB, 0))
        {//klawisz został naciśnięty
              a=1;
        }
        if (a==1)
        {
              PORTC &= ~(_BV(0));   //  dioda zapalona
              _delay_ms(2500);
              PORTC |= _BV(0);  // dioda zgaszona
              a=2;//impuls już wysłany więc blokujemy wysłanie kolejnego
        }
        if ((a==2) && (bit_is_set(PINB,0))
        {//klawisz został puszczony
              a=0;
        }
     }
return 0;
} 

Pamiętaj tylko o problemie drgających styków jak będzie to zwykły przycisk. Jak to rozwiązać znajdziesz w innych tematach na forum.

  • Lubię! 1
Link do komentarza
Share on other sites

Genialne w swojej prostocie 😃 Jeden z moich prototypów miał podobne działanie, jednak ta dodatkowa zmienna okazała się być kluczem 🙂 Po poprawie kilku literówek program pięknie śmiga a dioda świeci jak szalona 😅

Dziękuje i pozdrawiam

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Obecnie jest najprostrza metoda. Jeśli chcemy zmienić częstotliwość układu na NE555 musimy wylutować stare i przylutować nowe części, a stosując na przykład ATtiny13 wystarczy że zmienimy jedną albo dwie linijki kodu .

(Jest to moja subiektywna opinia 😉 )

Link do komentarza
Share on other sites

Zgadzam się,
dlatego w fazie eksperymentów i doboru parametrów (np. czas impulsu)

można posłużyć się jakimś generatorem np. na avrku.

Ale nie ma sensu zajmować procka do tylko takiego zadania w układzie docelowym,
chyba, że poza tym realizuje także inne zadania.

To jest jak strzelanie do wróbli z armaty.

Link do komentarza
Share on other sites

Na NE555 próbowałem już zrobić coś takiego i wszystko mi pięknie działało dla czasów powyżej 0.6 sekundy, czyli w moim przypadku dużo za dużo. By osiągnąć czas jaki potrzebuję musiałbym użyć kondensatora którego nie ma w produkcji 😅 a połączenia szeregowe/równoległe też dawały nieszczególne rezultaty. Ale to już nieistotne, bo chciałem i tak wykorzystać Atmege8, by wprowadzić szereg innych opcji, których przy użyciu NE555 osiągnąć się nie da, lub wiąże się to z użyciem kilku metrów kabli.

Korzystając z okazji podepnę kolejne pytanie. Docelowo Atmega ma być wykorzystana w układzie zasilającym elektrozwaór 24V DC. Impulsy odpowiednio sterowane w uC mają uruchamiać elektrozawór. Problem jest natury takiej, że nie mam pojęcia jak bezpiecznie i szybko obniżyć napięcie z 24V do 5V (dla uC), a potem zwiększyć napięcie z wyjścia Atmegi z 5V z powrotem do 24V. Macie jakieś pomysły?

Link do komentarza
Share on other sites

Konwersję sygnału 24 <-> 5 można zrobić na kilka sposobów.

Z optoizolacją z wykorzystaniem transoptorów,
bez optoizolacji.

Jeżeli obydwa układy 5V i 24V pracują bez wspólnej masy to proponowałbym

zastosować transoptory.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.