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

Atmega8 C - Licznik częstotliwości na wyświetlaczach 7 segmentowych

DaKKi 16 Lip 2013 12:23 1893 9
REKLAMA
  • #1 12527820
    DaKKi
    Poziom 16  
    Posty: 235
    Ocena: 665
    Witam,
    Próbuje napisać program do licznika częstotliwości na 9 wyświetlaczach 7 segmentowych (z czego 2 wyświetlać miały by tylko jednostkę Hz) - coś na wzór tego projektu:
    http://mdiy.pl/miernik-czestotliwosci-na-avr-od-1hz-do-10mhz/
    Z tym, że w języku C i na procesor ATMega8. Wystarczy mi zakres do około 1MHz.
    Kwarc 16MHz, fusebity C9/FF.

    Procedura obsługująca wyświetlacze jakoś już działa (choć nie wiem czy jest to optymalne rozwiązanie) - w przerwaniu od Timera2 multipleksują się wyświetlacze, następnie "wstrzelam" się poprzez instrukcje switch w pętli while(1) w chwilę kiedy wysterowany jest dany wyświetlacz i zapalam jego odpowiednie segmenty.

    Z Timera0 chciałem zrobić postawę czasu (odmierzał by dokładnie 1 sek.), i zliczać ilość przychodzących w tym czasie impulsów na nóżkę T1 (pin PD5 procesora) - następnie wynik idzie do zmiennej x i jest wyświetlany na wyświetlaczach.

    Niestety program nie działa jak powinien i nie mogę już dojść co jest nie tak - wyświetla liczby od 0 do 30 gdy T1 wisi w powietrzu, gdy zewrę do masy wyświetla 0.
    Proszę o pomoc w poprawieniu kodu.


    Pozdrawiam !
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 12527861
    piotrva
    VIP Zasłużony dla elektroda
    Posty: 6409
    Pomógł: 625
    Ocena: 735
    Mamma, mia, co to jest?
    Program w każdym calu błędny, zarówno pod względem logicznym, funkcjonalnym jak i programistycznym.
    Zacznij od porządnego multipleksowania, zwiększ rozdzielczość pomiaru tej jednej sekundy, dalej pobieranie TCNT1 następuje hmm, w losowym momencie - masz zupełnie brak synchronizacji z odmierzaniem 1s...
  • #3 12528099
    DaKKi
    Poziom 16  
    Posty: 235
    Ocena: 665
    Multipleksowanie jakoś działa, nie mam pomysłu jak można by to było zrobić lepiej.
    Gdzie umieścić pobieranie TCNT1 też nie za bardzo mam pomysłu...będę kombinował.
  • REKLAMA
  • #4 12528212
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Zacznij od uruchomienia samego wyświetlania. Przerwanie timera zgłaszane z częstotliwością np. 300 x liczba_cyfr Hz, a w procedurze obsługi tego przerwania jakieś 8..10 linii kodu realizujących wyświetlanie cyfr na wyświetlaczu, przechowywanych w posatci tablicy. Kiedy to Ci zadziała, bierz się za resztę. Cały program, który to robi, zapewne zmieści się w 30..40 liniach.
  • REKLAMA
  • #5 12528230
    Konto nie istnieje
    Poziom 1  
  • #6 12561879
    DaKKi
    Poziom 16  
    Posty: 235
    Ocena: 665
    Zmieniłem nieco program (wprawdzie niewiele), ale licznik zaczął działać :)
    Działa świetnie, ale jest jeden mankament - liczy do częstotliwości 33kHz - powyżej tej magicznej granicy dzieją się cuda - wyświetlacze gasną, zapalają się, nie wiadomo dlaczego...
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Ma ktoś jakiś pomysł?

    Przymknijcie oko na procedurę wyświetlania(multipleksowania) wyświetlaczy, próbowałem to zrobić inaczej, ale po prostu nie wiem jak.
    Poza tym sam podprogram do wyświetlania działa bez zastrzeżeń - wyświetla bez problemu liczby > 33000.

    Nie jest to też wina sygnału wejściowego - sprawdzałem na oscyloskopie w granicach tych 33kHz nic szczególnego się nie dzieje.
  • #7 12562120
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Zacznij od nowa od wyświetlanai w przerwaiu timera - w tym programie wszystko jest źle.

    Całe wyświetlanie - to jakieś 5 linii kodu - mniej-więcej takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #8 12562121
    piotrva
    VIP Zasłużony dla elektroda
    Posty: 6409
    Pomógł: 625
    Ocena: 735
    Nie lubię się powtarzać, ale:
    piotrva napisał:
    Zacznij od porządnego multipleksowania,

    Dlatego wyświetlacze szaleją
    Ponadto - po co zatrzymujesz T0 podczas obsługi przerwania? BŁĄD
    Jeśli już nie używasz trybu CTC to ładuj TCNT0=131 jako PIERWSZĄ instrukcję w przerwaniu - BŁĄD
    Z rzeczy estetycznych - używaj nowych nazw przerwań i ISR zamiast SIGNAL

    Ale tak czy siak zacznij od poprawnej obsługi wyświetlaczy - dopóki tym się nie zajmiesz będę w temacie oczekiwał na poprawę tej kwestii.
  • #9 12564847
    DaKKi
    Poziom 16  
    Posty: 235
    Ocena: 665
    Poprawiłem program.
    Multipleksowanie próbowałem zrobić na tablicy, ale jakoś mi to nie działało, poza tym tablica okazała się zbędna (zauważcie że mam niewygodnie podłączone segmenty wyświetlaczy jak i katody do 2 portów mikroprocka).
    Aktualnie zakres pomiaru poprawił się do około 60kHz, po tej wartości licznik jakby zataczał koło i liczył od nowa (np. dla 70 000 pojawia się około 10 000), dodatkowo zaniża pomiar o około 10% (w porównaniu z multimetrem), co tu by można jeszcze poprawić ?
    Próbowałem skonfigurować timer1 w trybie CTC (aby zliczał do wartosci 9 000 000), ale nic to nie dało.


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


    Pozdro !
  • #10 12564972
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Powtarzam: w tym programie sporo rzeczy jest źle. Pokazałem Ci powyżej wyświetlanie w 5 liniach kodu. Przy podłączeniu segmentów do dwśch portów wystarczy zamiast tablicy bajtów zadeklarować np. tablicę struktur dwubajtowych. Wartości cyfr do wyświetlania też powinny byś w tablicy - wtedy Twój kod skraca się np. 10-krotnie.
    Timer musi pracowaś w trybie CTCi zgłaszać przerwania ze stałą częstotliwością np. 2400 Hz. W tym przerwaniu odliczasz np. do 240 i odczytujesz stan licznika impulsów w okresie 1/10 sekundy. Nie możesz zatrymywać i restartować timera, bo zajmuje to jakiś czas i rozjeżdża Ci się w ten sposób baza czasu i pomiar częstotliwości.

    Timer nie może zliczać do 9000000 bo ma tylko 16-bitów.

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik pracuje nad programem do licznika częstotliwości na 9 wyświetlaczach 7-segmentowych z procesorem ATMega8, z zakresem do 1 MHz. Problemy dotyczą synchronizacji pomiarów oraz wyświetlania cyfr. Wskazówki dotyczące poprawy obejmują optymalizację multipleksowania, użycie tablic do przechowywania cyfr oraz poprawne ustawienie timerów. Użytkownik zauważył, że licznik działa do 33 kHz, a powyżej tej wartości wyświetlacze zachowują się nieprawidłowo. Wskazano na konieczność użycia trybu CTC dla timerów oraz unikanie zatrzymywania timerów podczas obsługi przerwań, co wpływa na dokładność pomiarów.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA