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

Attiny13A - Sprawdzenie schematu i kodu do sterowania przekaźnikiem po 5s

adamza 04 Paź 2014 13:57 1344 12
  • #1 14013849
    adamza
    Poziom 12  
    Witam,

    Układ ma za zadanie po podaniu zasilania 12V odczekać ok 4-5 sekund i załączyć przekaźnik na około 0,5 sekundy.

    Attiny13A - Sprawdzenie schematu i kodu do sterowania przekaźnikiem po 5s

    Możecie zerknąć czy niczego nie spaprałem?

    I jeszcze kod:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Nie wiem czy dobrze ustawiłem porty i czy dobry pin wybrałem na schemacie.
    Z góry dziękuje za pomoc.
  • #2 14013871
    vonar
    Poziom 28  
    C2 niepotrzebnie tak duży, właściwie w takim układzie mogłoby w ogóle go nie być. 7805 możesz spokojnie zamienić na 78L05 (jeśli pod względem obudowy/dostępności bardziej Ci odpowiada).
    Stosujesz BD139 - jeśli to ze względu na wyjątkowo duże zapotrzebowanie na prąd przekaźnika, to powinieneś zmniejszyć rezystor w bazie, bo nie wysterujesz właściwie tranzystora, jeśli trafi się sztuka o małym wzmocnieniu.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    możesz zmienić na
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Powrót z funkcji main to ogólnie taki sobie pomysł w programach na mikrokontrolery, chociaż tutaj nie szkodzi.
  • #3 14013886
    dondu
    Moderator na urlopie...
    Schemat OK z uwagą o C2 jak kol wyżej.

    Program prawie dobrze. Zamiast return 0 daj pętlę while(1);
    F_CPU ustawiłeś w opcjach projektu?



    vonar napisał:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    możesz zmienić na
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    ... co w tym przypadku nie ma znaczenia.
  • #4 14013941
    Konto nie istnieje
    Poziom 1  
  • #5 14013948
    adamza
    Poziom 12  
    Witam, faktycznie c2 dam też 10uf, przekaźnik jest mikro wiec nie ma dużego zapotrzebowania na prąd. Chyba zmienię tranzystor na mniejszy.
    Co do pętli while to program ma się uruchomić tylko raz po podaniu zasilania. Będzie mial za zadanie wyłączyć mi Start-Stop po odpaleniu silnika.
    Czy w takim razie może zostać return 0?

    Sorry ale to mój pierwszy układ na mikrokontroler.

    Dodano po 4 [minuty]:

    @M@rek Projekt traktuje jako samouczek ;)
  • #6 14014003
    vonar
    Poziom 28  
    Jak rozumiem korzystasz z AVR-GCC.
    Return 0 może zostać - program i tak wyląduje w nieskończonej pętli z zablokowanymi przerwaniami. Różnica byłaby, gdybyś chciał zostawić odblokowane przerwania lub (w C++) nie chciał wywoływania destruktorów globalnych obiektów.

    Jeśli zależy Ci na symbolicznym zmniejszeniu poboru prądu, możesz też zakończyć tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    (konieczne <avr/sleep.h>).
  • #8 14014062
    dondu
    Moderator na urlopie...
    vonar napisał:
    Jak rozumiem korzystasz z AVR-GCC.
    Return 0 może zostać - program i tak wyląduje w nieskończonej pętli z zablokowanymi przerwaniami.

    To i bez Return 0 się stanie, więc return jest zbędny. Natomiast świadoma pętla nieskończone w programie to tzw. "dobre praktyki" nie pozostawiające kompilatorowi, żadnych wątpliwości jak ma wyglądać skompilowany program.

    adamza napisał:
    A nie można jakos zakończyć programu? Tak żeby po jego wykonaniu układ nie robił juz nic?

    Sleep - jak najbardziej właściwy kierunek.
  • #10 14015449
    adamza
    Poziom 12  
    A jaka jest różnica miedzy:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    A twoim:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    wyczytałem ze jest aż 5 poziomów uśpienia:

    SLEEP_MODE_IDLE
    SLEEP_MODE_ADC
    SLEEP_MODE_PWR_SAVE
    SLEEP_MODE_STANDBY
    SLEEP_MODE_PWR_DOWN

    I czy SLEEP_MODE_PWR_DOWN nie jest najbardziej oszczędny?
    Nie potrzebuje wzbudzać ponownie układu wiec czy nie powinienem użyć SLEEP_MODE_PWR_DOWN?
  • Pomocny post
    #11 14015524
    vonar
    Poziom 28  
    Tak jest, w Twoim wypadku (zakończenie działania programu) najodpowiedniejsze będzie wejście w tryb power down. Mój kod miał tylko ogólnie zwrócić uwagę na uśpienie (wejście w domyślny, najmniej oszczędny tryb idle; pętla nie szkodzi, ale jest potrzebna tylko dla programów, które chcą pozostawać w trybie uśpienia, ale wykonywać procedury obsługi przerwań – tutaj zbędna).

    dondu napisał:
    vonar napisał:
    Jak rozumiem korzystasz z AVR-GCC.
    Return 0 może zostać - program i tak wyląduje w nieskończonej pętli z zablokowanymi przerwaniami.

    To i bez Return 0 się stanie, więc return jest zbędny.
    To prawda, osiągnięcie końca funkcji main jest równoznaczne z return 0, jednak moim zdaniem return jaśniej określa intencje programisty.

    Jeśli chodzi ogólnie o sposób kończenia programu, warto wyjaśnić
    dondu napisał:
    Natomiast świadoma pętla nieskończone w programie to tzw. "dobre praktyki" nie pozostawiające kompilatorowi, żadnych wątpliwości jak ma wyglądać skompilowany program.
    Tak jest, pętla nieskończona napisana explicite jest lepszym pomysłem niż powrót z funkcji main (w swoim pierwszym poście też wspomniałem, że to nie najlepszy pomysł), jednak muszę sprostować – taki zapis pozostawia wątpliwości człowiekowi, jednak dla kompilatora jest jednoznaczny: ma on wywołać funkcję exit, która jest definiowana przez avr-libc jak wspomniałem wcześniej.
  • #12 14016255
    dondu
    Moderator na urlopie...
    vonar napisał:
    ... taki zapis pozostawia wątpliwości człowiekowi, jednak dla kompilatora jest jednoznaczny: ma on wywołać funkcję exit, która jest definiowana przez avr-libc jak wspomniałem wcześniej.

    "Dobre praktyki" to takie praktyki, które niezależnie od kompilatora lub ich wersji będą prowadziły do uzyskania działającego poprawnie kodu. Nie należy więc zostawiać kompilatorowi pola do popisu w tym jakże ważnym zakresie.

    Dlatego właśnie kończenie programu za pomocą świadomego umieszczenia pętli nieskończonej w programie pisanym dla mikrokontrolera (a nie do uruchomienia na jakimś systemie operacyjnym) jest bardzo ważne. Jest to tym istotniejsze, że nie wiemy, czy użyty w przyszłości kompilator zachowywać będzie się tak samo jak aktualna jego wersja.

    Dla autora tematu do porównania:

    - bez pętli nieskończonej lub z return 0 wygenerowany kod jest taki sam (jak pisałem wcześniej):

    Kod: text
    Zaloguj się, aby zobaczyć kod




    - z pętlą nieskończoną:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #13 14016539
    vonar
    Poziom 28  
    dondu, nigdzie nie napisałem, że twierdzę inaczej. Jednak wspomniałeś:
    dondu napisał:
    nie pozostawiające kompilatorowi, żadnych wątpliwości jak ma wyglądać skompilowany program.
    Słowa „wątpliwości kompilatora” sugerują zachowanie niezdefiniowane (undefined behavior – może się stać cokolwiek i nie musi to być nigdzie udokumentowane), podczas gdy mamy tutaj działanie zależne od implementacji – (działanie przewidywalne, udokumentowane, ale nieprzenośne, więc przez to potencjalnie kłopotliwe). Nie zmienia to faktu, że obu lepiej unikać, ale Twoje słowa mogły wprowadzać początkujących w błąd, sugerując, że działania programu z powrotem z main nie można przewidzieć, stąd moje sprostowanie.

    @dondu poniżej – doprecyzowałem, zmieniając ten post.

    Tak przy okazji – pomysł powrotu z funkcji main może przyjść do głowy, kiedy brakuje nam kilku bajtów pamięci programu i szukamy oszczędności, gdzie się da. Lepiej w takiej sytuacji jednak napisać pętlę nieskończoną, a oszczędzić (niestety, mniej) na instrukcji powrotu deklarując funkcję main ze specyfikatorem _Noreturn w C (czy atrybutem [[noreturn]] w C++). Dla GCC powinniśmy wtedy jawnie określić, że kompilujemy program freestanding, (opcja -ffreestanding) bo przy domyślnie przyjmowanym przez gcc hosted jest to niezgodne ze standardem. Ponadto w większości sytuacji warto przy tym dodać przełącznik -fbuiltin, by nie wyłączać automatycznej podmiany niektórych funkcji na wbudowane, zwykle zoptymalizowane wersje.
REKLAMA