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

ATMEGA16 - zmienny czas trwania pętli for w programie

krzysztofh 19 Mar 2014 14:14 1323 5
  • #1 13420809
    krzysztofh
    Poziom 29  
    Mam do Was pytanie dotyczące fragmentu programu, w szczególności pętli for, która wykonuje się 16 razy i każde kolejne wykonanie trwa dłużej niż poprzednie.
    Czas trwania ostatniej pętli jest kilkanaście razy dłuższy niż pierwszej i przyrost czasu wykonania każdej pętli jest z grubsza liniowy.
    fragment programu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    [/code]

    Przebieg na pinie PB4 obserwowany oscyloskopem.
    Atmega16 jest taktowana zegarem 16Mhz. W programie dwa przerwania:
    ISR(TIMER1_COMPA_vect) wywołane co 100ms do inkrementowania jednej zmiennej (wyłącznie)
    oraz
    ISR(TIMER0_COMP_vect) wywołane z częstotliwością 800Hz do multipleksowania wyświetlaczy.
    W programie nie ma żadnego "_delaya". Poza tym program na razie niewiele robi.
    Funkcja prezentowania powyżej służy do komunikacji szeregowej procesora z przetwornikiem DC/AC i działa poprawnie, co stwierdzam na podstawie oglądanych przebiegów oscyloskopem oraz pomiarze napięcia na wyjściu przetwornika.
    Interesuje mnie, dlaczego czas wykonania każdej kolejnej pętli for rośnie liniowo.
  • #2 13420927
    BlueDraco
    Specjalista - Mikrokontrolery
    Dlatego, że napisałeś ją mocno nieoptymalnie - w pętli jest przesunięcie o zmienną liczbę bitów, a AVR nie ma instrukcji przesuwania o dowolną liczbę bitów, więc samo przesunięcie realizuje w pętli, której liczba obiegów rośnie w kolejnych obiegach pętli zewnętrznej.

    Napisz np. tak

    if (send_data & 1)
    ...
    send_data >>= 1;
  • Pomocny post
    #3 13421100
    Konto nie istnieje
    Poziom 1  
  • #4 13421499
    krzysztofh
    Poziom 29  
    Trochę wyjaśnię.
    Zmienna send_data jest zmienną int16_t.
    W programie zmienną send_data deklaruje się w zakresie -8192 d0 8191.
    W przetwornik oczekuje przesłania w ramce 16 bitów, przy czym dwa najstarsze bity nie mają znaczenia.

    if(send_ & (1 << cbn)) odczytuje 16 kolejnych bitów liczny wpisanej do zmiennej send_data.
    Jeżeli dany bit jest 1, ustawiany jest wysoki stan portu PB5, jeżeli 0 to niski stan.
    Przetwornik odczytuje kolejne stany (stany 0, 1 ) i wartości te są zatrzaskiwane w przetworniku razem z opadającym zboczem przebiegu zegarowego.
  • Pomocny post
    #5 13422485
    BlueDraco
    Specjalista - Mikrokontrolery
    Zamiast wyjaśniać to, co już wiemy, po prostu zrób to wg. wskazówek i pochwal się wynikami. Kod powyżej poprawiłem tak, żeby był zgodny z kolejnością bitów w Twoim kodzie.
  • #6 13422513
    krzysztofh
    Poziom 29  
    Dziękuję obu Kolegom, właśnie usiadłem do rozgrzebanego projektu, na razie na płytce stykowej.
    Działa rewelacyjnie.
    Podziękowania "pomógł" odklikałem.
REKLAMA