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

[Atmega 8] [Atmega 8][GCC][VMLab] - Timer w symulatorze działa za szybko, jak to naprawić?

dzeju555 18 Sty 2014 17:10 1974 14
  • #1 13191053
    dzeju555
    Poziom 10  
    Witam serdecznie.
    Właśnie zacząłem swoją przygodę z AVR. Zrobiłem swój pierwszy projekt - jest to timer do gotowania jajek. Póki co pracuję w VMLAB. Program ten obsługuje dwa przyciski, po wciśnięciu "2" jajko gotowane jest cztery minuty, a po wciśnięciu "3" proces ten trwa 8 minut. Gdy gotowanie się zakończy, diody zaczynają inaczej mrugać, a na PORTC podawany jest prąd, by podłączony tam beeper piszczał tonem przerywanym. Niestety zmierzyłem czas działania i okazuje się, że program nr 2 wykonuje się tak naprawdę kilka sekund (w prawym dolnym rogu time pokazuje 880ms), program 3 działa troszkę dłużej. Byłbym w stanie zrozumieć, gdyby czas ten był dłuższy niż zamierzony, w końcu to symulator, ale tutaj coś musi być nie tak. Wydaje mi się, że wszystko jest dobrze obliczone. Nie mam pojęcia co jest nie tak. Proszę o wskazówkę.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #2 13191176
    olelek
    Poziom 24  
    Program ma dużo błędów i jest źle napisany.
    Po pierwsze nie wiem w jakim celu używasz pętli while.
    Po drugie nie wiem jakie jest taktowanie procesora (zakładam że 1MHz a nie 1 000 000MHz :) ).

    Do takiego zadania wybrałbym prescaler timera0 na maksa (1024), i nie skracał cyklu. Wtedy miałbym przerwanie o częstotliwości ok. 3,8Hz (co ok. 0,26 sekundy). Czyli dla 4 minut byłoby to ok. 915 przerwań (dokładność wystarczająca do gotowania jaja).

    Przepraszam, ale później dokończę post. Na szybko chciałem to odpisać.
  • Pomocny post
    #3 13191194
    dondu
    Moderator na urlopie...
    Witaj.

    1. Nie znam VMLAB, ale czy prawidłowo definiujesz F_CPU?
    2. Czy symulator nie potrzebuje osobnej definicji częstotliwości do prawidłowego określania czasów symulacji? Tak jest w symulatorze w Atmel Studio.
    3. Volatile: http://mikrokontrolery.blogspot.com/2011/04/problemy-c-volatile.html

    Posklejałeś ten program z kilku - no ale każdy kiedyś zaczyna :)
  • #4 13191334
    dzeju555
    Poziom 10  
    Nie wiem o który dokładnie while Ci chodzi. While w ISR() znajduje się dlatego, że w funkcja obsługi przerwań wykonuje różne działania w zależności od tego, czy gotowanie się już skończyło, czy nie (sekundy<240).
    While w funkcji licz() zastosowałem po to, by po zakończeniu gotowania zmienił ilość i kolejność diod. Jako że ta funkcja wywołuje się tylko raz, użyłem instrukcji while zamiast if.
    Jeśli chodzi o taktowanie to jest to oczywiście 1MHz, czyli 1 000 000Hz - niedopatrzenie ;)
    Spróbuję teraz zmienić prescaler na 1024 i zobaczę na efekty. Dziękuję.

    Częstotliwość procesora jest ustawiona na 1MHz jako domyślna, widać to zresztą na panelu kontrolnym. W drugim pytanie wydaje mi się, że odpowiedź jest przecząca. Dodałem volatile przed zmiennymi globalnymi. Dziękuję.
  • #6 13191591
    dzeju555
    Poziom 10  
    Hehe, może nie tyle posklejałem, co po prostu uczę się czytając tutoriale, a że są one pisane przez różne osoby... ;)
    Wprowadziłem drobne modyfikacje:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Niestety po upływie tych 240s, program wciąż działa bez zmian, czyli tak jakby sekundy<240.
  • #7 13191757
    olelek
    Poziom 24  
    Zaraz odpalę tego VMLAB'a i popatrzę.

    Czy możesz wrzucić tutaj wszystkie pliki projektu?

    I jeszcze jedno - czy przed w funkcji licz() nie powinno być np.
    _delay_ms(500);
    ?
  • #8 13191837
    dzeju555
    Poziom 10  
    Już wrzucam cały projekt.

    A co do pytania, nie wydaje mi się. Instrukcja ta ma tylko ustawić co drugą diodę jako świecącą (jednorazowo), tak by przy ISR, w której za każdym wywołaniem neguje tę wartość, powstało wrażenie ruchu.
  • Pomocny post
    #9 13192027
    olelek
    Poziom 24  
    OK. Jestem teraz prawie pewien gdzie leży problem. Otóż ten program VMLAB jest kiepskim symulatorem i nie za bardzo łapie operator volatile. Program zawiesza się na pętli while() w funkcji licz(), ignorując zupełnie przerwania. Jest to moim zdaniem wina tego symulatora. Układ fizyczny powinien działać. W wolnej chwili odpalę na symulatorze AS6.

    Edit: Tak, w symulatorze Atmel Studio wszystko śmiga - przerwanie jest wykonywane, a zmienne się inkrementują.
  • #10 13192290
    dzeju555
    Poziom 10  
    Ech... zapomniałem, że włączyłem optymalizację w VMLAB, pewnie stąd ten problem... Dziękuję bardzo za pomoc!
  • #13 13192781
    dzeju555
    Poziom 10  
    Jasne :)
    Project-->GCC/WinAvrFlags-->Optimization.

    Wiesz co, chodziło mi o to, że, wg tego co czytałem, do symulacji optymalizacja powinna być wyłączona, gdyż powoduje błędy. Podkreślam, tylko do symulacji :) Jak widać coś w tym jest ;)
REKLAMA