eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaAVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu › AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
  • Path: news-archive.icm.edu.pl!news.gazeta.pl!newsfeed.pionier.net.pl!news.glorb.com!n
    ews-out.readnews.com!transit3.readnews.com!nx01.iad01.newshosting.com!newshosti
    ng.com!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-01.news.neo
    strada.pl!news.neostrada.pl.POSTED!not-for-mail
    From: "Robbo" <y...@m...com>
    Newsgroups: pl.misc.elektronika
    Subject: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
    Date: Wed, 9 Feb 2011 13:54:01 +0100
    MIME-Version: 1.0
    Content-Type: text/plain; format=flowed; charset="iso-8859-2"; reply-type=original
    Content-Transfer-Encoding: 8bit
    X-Priority: 3
    X-MSMail-Priority: Normal
    X-Newsreader: Microsoft Outlook Express 6.00.2900.5512
    X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5512
    X-Antivirus: avast! (VPS 110208-1, 2011-02-08), Outbound message
    X-Antivirus-Status: Clean
    Lines: 122
    Message-ID: <4d528e6b$0$2436$65785112@news.neostrada.pl>
    Organization: Telekomunikacja Polska
    NNTP-Posting-Host: 83.24.161.91
    X-Trace: 1297256043 unt-rea-b-01.news.neostrada.pl 2436 83.24.161.91:4694
    X-Complaints-To: a...@n...neostrada.pl
    Xref: news-archive.icm.edu.pl pl.misc.elektronika:604486
    [ ukryj nagłówki ]

    Witam,

    Jakiś czas temu pytałem o sprawy związane z pomiarem częstotliwości
    sinusoidy o częstotliwości od 2 do 150Hz oraz zmiennej amplitudzie (od kilku
    V do 400V). Mam już układ elektroniczny przekształcający sinusoidę na
    prostokąt (brana jest pod uwagę tylko dodatnia połówka, a ujemna jest
    usuwana). Jest tu kilka rezystorów, mostek, tranzystor, dioda oraz
    transformatorek. (Może działanie tego układu da się jeszcze ulepszyć, ale to
    w sumie nie jest teraz tematem). Uzyskany z dodatniej połówki sinusoidy
    prostokąt jest podawany na nóżkę PE7(INT7) mikrokontrolera ATmega128 (kwarc
    16MHz). Dokładność pomiaru, którą chciałbym osiągnąć to 0,2Hz przy
    częstotliwości 50Hz. Chciałem Was prosić o sprawdzenie mojego kodu, którego
    zadaniem jest nieustanne mierzenie czasu trwania dodatniej połówki, a
    następnie wypisywanie tej wartości na wyświetlacz. Kod, który napisałem
    wygląda na działający, ale może ma jakiś ukryty błąd.

    volatile unsigned long int timer = 100000;
    volatile short actualTime;

    ./* procedura wywoływana 100000 razy na sekundę */
    SIGNAL (SIG_OUTPUT_COMPARE2)
    {
    cli();

    if (timer < 100000)
    timer++;

    sei();
    }

    /* wyzwalane zboczem narastającym i opadającym */
    SIGNAL (SIG_INTERRUPT7)
    {
    cli();

    if (PINE & PINE7) {
    timer = 0;
    TCCR2 = 0; // stop timera
    TCNT2 = 0; // zerowanie licznika
    TCCR2 = _BV(WGM21) | // start timera
    _BV(C21); // (prescaler 8)
    } else {
    actualTime = timer;
    }

    sei();
    }

    int main(void)
    {
    char s[16];

    initLCD();

    cli();

    EICRB |= _BV(ISC70);
    EIMSK |= _BV(INT7);

    TCCR2 = 0;
    OCR2 = 19;
    TIFR |= _BV(OCF2);
    TIMSK |= _BV(OCIE2);
    while (ASSR & _BV(OCR2UB))
    ;

    sei();

    while (1) {

    if (timer == 100000)
    LCDshowString("---");
    else {
    sprintf(s, "%d ", actualTime);
    LCDshowString(s);
    }
    }

    return 0;
    }

    ***
    Jak to się sprawuje:
    Jako źródło sygnału podłączyłem po prostu zasilanie sieciowe 230V/50Hz.
    Wczoraj wieczorem przed godziną 22 liczba na wyświetlaczu wynosiła 996
    (ostatnia cyfra niekiedy migała na "5"). Potem zaczęło to rosnąć... 997/8. O
    godzinie 22 było jakieś 999. Potem zaczęło spadać do 996. Teraz (godzina
    13:40) mam 996/7.
    ***

    W szczególności chciałem zapytać o to, czy poprawnie zastosowałem cli() i
    sei() w procedurach obsługi przerwań. Ponadto chciałem zapytać, czy kod
    wewnątrz while(1) jest poprawny i czy nie lepiej byłoby zapisać to tak:

    while (1) {
    unsigned long int timerLatch;
    short actualTimeLatch;

    cli();
    timerLatch = timer;
    actualTimeLatch = actualTime;
    sei();

    if (timerLatch == 100000)
    LCDshowString("---");
    else {
    sprintf(s, "%d ", actualTimeLatch);
    LCDshowString(s);
    }
    }

    Chodzi o sytuację, w której w pętli głównej jest przetwarzana wartość
    zmiennej timer albo actualTime (np. został odczytany pierwszy bajt) i w
    trakcie nastąpi przerwanie, zmieni wartość zmiennej, obsługa przerwania się
    skończy, zostanie dokończone przetwarzanie zmiennej timer albo actualTime --
    wartość chyba będzie błędna (jeden bajt z poprzedniej wartości, reszta
    bajtów po aktualizacji w przerwaniu).

    Z góry dziękuję za rady.

    Robbo

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: