Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Attiny13 - opóźnienie _delay_ms i nop

Alexkun 30 Lip 2012 20:13 1855 8
  • #1 30 Lip 2012 20:13
    Alexkun
    Poziom 6  

    Witam, używam do symulacji zanim wgram program do kontrolera Proteusa i mam mały problem. Powiedzmy że chcę dać 1 na port na sekundę i go zgasić. Na Atmega8 użyłbym _delay_ms(1000) ale jak tak napiszę na Attiny13 to kod się kompiluje ale jak włączam symulację to Proteus zaczyna sypać błędami(myślałem że symulator może po prostu nie obsługuje takiej funkcji ale jak mam _delay_ms w kodzie i symuluję Atmege8 to wszystko ładnie chodzi, nie mam akurat tego Attiny13 żeby wgrać o niego program i też trochę się boję że może jednak nie obsługuje on tej funkcji i go uszkodziłbym tym kodem).

    Pomyślałem że może użyję funkcji nop z asm. Z tego co wyczytałem trwa ona 1 cykl. Tak więc jeśli dobrze rozumiem i mam Atiny13 z zegarem 9,6MHz to jeden cykl trwa 1 / 9.6 MHz = 104.166667 ns czyli jeśli bym napisał

    void delay(void){
    for(long int i=0; i<=9600000; i++)
    asm(nop);
    }

    to funkcja będzie generować opóźnienie 1s. Tylko nie wiem czy jest to dobry pomysł.

    0 8
  • #2 30 Lip 2012 20:31
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie będzie generować opóźnienia 1s, lecz znacznie dłuższe - przecież trzeba zrobić pętlę, nie sądzisz chyba, że kompilator umieści 9,6 mln następujących po sobie instrukcji nop :) Stąd też lepiej całe opóźnienie napisać w asm, ale zapewne będzie wyglądało tak samo jak to z delay.h. Lepiej napisz co to za błędy którymi sypie Proteus, pamiętaj też, że symulację możesz zrobić także w AVR Studio.

    0
  • Pomocny post
    #3 30 Lip 2012 20:53
    eleproject

    Poziom 17  

    Nie analizowałem poprawności tego fragmentu kodu. Jednak jest to bardzo dobry pomysł. Zrób sobie funkcję, która w argumencie przyjmuje np. liczbę milisekund. Po napisaniu takiej funkcji sprawdzisz sobie jej dokładność na symulatorze i ewentualnie skorygujesz inkrementowaną/dekrementowaną wartość.
    Funkcje biblioteczne opóźnień, np: _delay_ms przyjmują w argumencie zmienną typu float, a to czasem wymaga konwersji przy wywoływaniu tej funkcji z całkowitej liczby na float. A to z kolei strasznie połyka pamięć procesora i silnie angażuje procka.
    Napisana więc samodzielnie funkcja opóźnienia ze zmienną całkowitą w argumencie, jest pod tym względem lepsza.

    Dodano po 17 [minuty]:

    Właśnie rzuciłem okiem jak to kiedyś rozwiązałem.
    Jednak okazuje się, że moja funkcja używa funkcji bibliotecznej _delay_loop_2. Jednak ta przyjmuje argument całkowity.
    Spróbuj wykorzystać moją mini bibliotekę do generowania opóźnień - w załączonych plikach.
    Musisz mieć określone makrem F_CPU.
    Używałem tego na procesorach atmega. Nie wiem czy dla ATtiny nie będzie trzeba zmodyfikować wyliczenia factor_ms.
    Ale spróbować zawsze możesz :)

    0
  • #4 30 Lip 2012 21:06
    tmf
    Moderator Mikrokontrolery Projektowanie

    grosiu2 napisał:
    Nie analizowałem poprawności tego fragmentu kodu. Jednak jest to bardzo dobry pomysł. Zrób sobie funkcję, która w argumencie przyjmuje np. liczbę milisekund. Po napisaniu takiej funkcji sprawdzisz sobie jej dokładność na symulatorze i ewentualnie skorygujesz inkrementowaną/dekrementowaną wartość.
    Funkcje biblioteczne opóźnień, np: _delay_ms przyjmują w argumencie zmienną typu float, a to czasem wymaga konwersji przy wywoływaniu tej funkcji z całkowitej liczby na float. A to z kolei strasznie połyka pamięć procesora i silnie angażuje procka.
    Napisana więc samodzielnie funkcja opóźnienia ze zmienną całkowitą w argumencie, jest pod tym względem lepsza.


    Niestety to co piszesz jest kompletną nieprawdą. żeby nie przynudzać długimi wywodami:
    http://mikrokontrolery.blogspot.com/2011/04/gcc-avr-funkcje-opoznienia-delay.html

    0
  • #5 30 Lip 2012 21:26
    eleproject

    Poziom 17  

    Oczywiście, że mam rację - nie raz się o tym przekonałem. Nawet na stronie, którą podałeś jest napisane - podejrzewam, że z resztą przez Ciebie:
    "... Ponieważ podana stała zostanie wyliczona na etapie kompilacji programu, w efekcie w finalnym kodzie żadne obliczenia zmiennopozycyjne nie będą wykonywane."
    STAŁA a ja pisałem o ZMIENNEJ - a tu "obliczenia zmiennoprzecinkowe" będą wykonywane.
    Najprościej skompiluj sobie kawałek programu to się przekonasz, że ZMIENNA całkowita przekazana w argumencie do _delay_ms powoduje puchnięcie kodu wywołane konwersją na float.

    0
  • #6 30 Lip 2012 21:32
    tmf
    Moderator Mikrokontrolery Projektowanie

    Argumentem funkcji __delay_ms nie powinna, a w nowszych wersjach AVR-libc nie może być zmienna. Autor wątka zresztą żadnych zmiennych nie stosuje (prawidłowo).

    0
  • #7 30 Lip 2012 23:41
    Alexkun
    Poziom 6  

    Proteus sypie czymś takim:
    Attiny13 - opóźnienie _delay_ms i nop Attiny13 - opóźnienie _delay_ms i nop

    Jednak gdy w Eclipse w build zmieniłem z Debug na Release i wybrałem w Proteusie wygenerowany hex(wcześniej generowało tylko plik elf) to przestało sypać te errory. Tylko zamiast opóźnienie 1s przy delay_ms(1000) to robi 8s zegar mam ustawiony w właściwościach projektu i też w kodzie wpisywałem.

    0
  • Pomocny post
    #8 31 Lip 2012 07:46
    tmf
    Moderator Mikrokontrolery Projektowanie

    Najpewniej wynika to z tego, że z Debug masz kompilację bez optymalizacji (-O0), w efekcie program jest tak długi, że nie mieści się w pamięci FLASH ATTiny - sprawdź jego długość, sprawdź też czy nie masz żadnych ostrzeżeń - zapewne jedno masz. W release pewnie kompiluje z -Os i jest ok - to, że masz czasy 8x dłuższe sugeruje brak ustawienia fusebitu odpwiedzialnego za podział zegara - może proteus takowy ma. Z drugiej strony dla symulacji zapewne to nie ma znaczenia czy masz 1 czy 8 s.

    0
  • #9 31 Lip 2012 20:35
    Alexkun
    Poziom 6  

    Faktycznie przy Debug pokazuje warning jednak pokazuje w innej zakładce a nie w consoli z wynikiem kompilacji(nie dawno zacząłem używać Eclipsa w wcześniejsze IDE których używałem wynik kompilacji ilość błędów i ostrzeżeń pokazywały w jednym miejscu). A w proteusie zegar jest prawidłowo ustawiony jednak w attiny13 jest standardowo włączony rejestr CKDIV8 (który dzieli przez 8 częstotliwość zegara).

    Dzięki za pomoc.

    0