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

Jak dostosować kod PIC 16F84A do wyświetlaczy ze wspólną anodą?

pathirrus 05 Cze 2015 17:37 2580 12
REKLAMA
  • #1 14747601
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Witam.
    Chcę sobie zrobić zegar ze strony: Link
    Tylko mam problem, ponieważ kod programu jest przeznaczony dla wyświetlaczy ze wspólną katodą, ja natomiast posiadam wyświetlacze ze wspólną anodą. Co w kodzie należy zmienić, aby działało to z wyświetlaczem ze wspólną anodą?

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


    Po wgraniu tego kodu i uruchomieniu zegara, wyświetla się: 8.8.8.8.

    Proszę o pomoc
  • REKLAMA
  • #2 14747684
    dioda1000
    Poziom 28  
    Posty: 830
    Pomógł: 143
    Ocena: 130
    pathirrus napisał:

    Co w kodzie należy zmienić, aby działało to z wyświetlaczem ze wspólną anodą?

    Zmiana samego kodu nic nie da.Zmiana schematu i kodu to tak.
    Jak masz płytkę poszukaj wyświetlacza.
  • REKLAMA
  • #3 14747906
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Schemat jest oczywiście zmieniony odpowiednio, zamiast tranzystorów NPN są PNP i odpowiednio podłączone. Problem mam z kodem bo nie bardzo orientuję się jak to poprawić, żeby działało.

    Wydaje mi się, że muszę zmienić:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    należy zmienić na:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    No ale nie jestem pewien
  • Pomocny post
    #4 14747977
    dioda1000
    Poziom 28  
    Posty: 830
    Pomógł: 143
    Ocena: 130
    zaneguj te wartości 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67

    Tu masz 'chodzącą' 1 ,zamienić na 'chodzące' 0
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 14748008
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Zanegowałem wartości segmentów, ale nie rozumiem tego "chodzącego" 0. zmieniam wartości przy "i = 0xXX" ale nic z tego raczej
  • REKLAMA
  • #6 14748468
    kspro
    Poziom 27  
    Posty: 509
    Pomógł: 158
    Ocena: 107
    Zamiast robić "chodzące zero", czyli przesuwać wartość 0xFE, można zostawić tak jak jest i tylko zanegować 4 młodsze bity przed wysłaniem do portu A, czyli instrukcję na samym końcu:
    PORTA = i; // light on selected 7 segment display
    zmienić na:
    PORTA = i^0x0F;

    Podobnie zamiast negować znak po znaku całą tablicę kodów wyświetlacza 7-segmentowego wystarczyło wstawić negację do przedostatniej instrukcji, czyli zamiast:
    PORTB = digiled[digit]; // write 7 segment output
    napisać:
    PORTB = ~digiled[digit]; // write 7 segment output
  • #7 14748592
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Hmm...niestety nie wiele to zmienia. kspro jak zrobiłem tak napisałeś to jedynie niektóre segmenty słabiej świecą, ale nadal wszystkie się palą.
  • Pomocny post
    #8 14748649
    kspro
    Poziom 27  
    Posty: 509
    Pomógł: 158
    Ocena: 107
    Do tej pory zakładałem, że sprawa jest prosta i jest to tylko kwestia negacji, bo przecież napisałeś, że zmodyfikowałeś odpowiednio schemat, tranzystory NPN zastąpiłeś PNP łącząc je odpowiednio (czyli emitery do Vcc, jak rozumiem), więc wszystko powinno działać, ale teraz zajrzałem na podaną przez Ciebie stronę z oryginalnym projektem i zauważyłem pewien szczegół, którego obejście może wymagać więcej wysiłku. Chodzi o opornik R13 i przycisk S1 do wyświetlania minut i sekund zamiast godzin i minut, one też wymagają zmiany, gdyż podłączone tak jak w tej chwili po zanegowaniu portów mogłyby przestać działać. Czy zmieniłeś ich podłączenie a jeśli tak to w jaki sposób?

    Przyjrzałem się też bliżej programowi. Stan przycisku S1 odczytywany jest w pętli nieskończonej w main() w sekwencji instrukcji:
    PORTA = 0; // shut down display
    PORTB = 0; // clear segment outputs

    TRISB = 0x80; // set PORTB.F7 as input
    kp = PORTB.F7; // read key
    TRISB = 0x00; // set PORTB.F7 as output again

    Pierwsza instrukcja, co przeoczyłem wcześniej, musi zostać zmieniona na:
    PORTA = 0x0F;
    żeby wyłączyć wyświetlacze przed odczytaniem stanu przycisku.
    Następne instrukcje przypuszczalnie też wymagają zmian, ale to już zależy od tego jak podłączyłeś S1 i R13, więc nie jestem w stanie w tej chwili niczego zaproponować. Musisz załączyć schemat lub bardzo dokładnie to opisać.

    Dodam jeszcze, że uprzednie rozwiązanie z zanegowaniem tablicy kodów wyświetlacza 7-segmentowego ma ten feler, że w ogóle nie uzwględnia bezpośredniego kasowania cyfr wyświetlacza ani kropek dziesiętnych, a są one wykorzystywane przez program do sygnalizowania statusu odbioru DCF77 i innych operacji (nie wnikałem już jakich), więc należałoby to jeszcze poprawić. Pod tym względem moje rozwiązanie z zanegowaniem wartości tuż przed wpisaniem ich do portów A i B jest lepsze, gdyż nie narusza logiki wewnątrz programu.

    Niezależnie od tego wszystkiego mam wrażenie, że jednak coś jest nie tak z hardware lub kontroler po prostu nie działa, bo z programu w żaden sposób nie wynika żeby w jakiejkolwiek sytuacji mogły być wyświetlane (bądź wygaszone) wszystkie segmenty tak jak to opisujesz, tablica wyświetlanych cyfr digiled[ ] jest zawsze wypełniana czymś sensownym. Zresztą jest to opisane na stronie projektu zaraz pod filmikiem.
  • #9 14749258
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Na tą chwilę nie mam wgl podłączonego przycisku oraz tego rezystora R13. Generalnie korzystam z płytki ewaluacyjnej dla PICów AVT5275 [url=]http://serwis.avt.pl/manuals/AVT5275.pdfLink[/url]
    Ale jest jakiś progres, po zmianie kodu na:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Miałem mały błąd ponieważ, anody wyświetlaczy podłączyłem nie tak jak trzeba (odwrotna kolejność). Po poprawieniu tego i uruchomieniu wyświetlają się na końcu tylko dwa 0. niestety nic nie zlicza. Odbiornik robiłem wg datasheetu dla U4221B, antenę miałem ze starego odbiornika



    A czy w linijce:
     PORTB = 0 ;                     // clear segment outputs

    nie trzeba też przypadkiem zmienić na
     PORTB = 1 ;                     // clear segment outputs
    (zmiana stanu z 0 na 1) ?
  • REKLAMA
  • Pomocny post
    #10 14750501
    kspro
    Poziom 27  
    Posty: 509
    Pomógł: 158
    Ocena: 107
    No to rzeczywiście miałeś coś źle połączone ale PIC16F84 działa i wykonuje program, bo teraz dane na wyświetlaczu mają sens. Dwa puste miejsca i dwa zera wskazują na to, że program znajduje się na początku odczytu danych z odbiornika DCF77 i niestety nic nie odbiera. Jak napisano pod filmikiem:
    Clock not locked:
    - In this state, the clock can't display time because it has never received a complete DCF77 time frame. The clock is in this state at start time.
    - The first two digits of the digits are blanked, and the two last digits show the current bit number of the frame in progress.

    czyli (tłumaczenie moje):
    Zegar nie zsynchronizowany:
    - W tym stanie zegar nie może wyświetlać czasu ponieważ nigdy nie odebrał pełnej ramki DCF77. Zegar jest w tym stanie zaraz po włączeniu.
    - Dwie pierwsze cyfry są wygaszone, a dwie ostatnie pokazują numer bieżącego bitu ramki podczas odbioru.

    Wygląda więc na to, że wyświetlanie działa dobrze ale masz problem albo z samym odbiornikiem DCF77 albo z jego połączeniem z PIC16F84.

    Program napisany jest tak, że nie przejdzie do wyświetlania czasu dopóki nie odbierze kompletnej ramki. Możesz to oszukać zmieniając na próbę definicję z początku programu:
    unsigned char locked = 0 ; // set to 1 when clock has been adjusted
    na:
    unsigned char locked = 1 ;
    Wówczas program natychmiast zacznie wyświetlać czas tak jakby ramka DCF77 została już odebrana. Zliczanie czasu rozpocznie się od 12:34:56, gdyż takimi wartościami autor zainicjował sobie zmienne:
    unsigned char rhh = 12, rmn = 34, rss = 56 ; // RTC clock : hours, minutes, seconds
    Przypuszczalnie zostało tak zrobione tylko do celów testowych, gdyż, o ile zdołałem się zorientować, w normalnej pracy zegara wartości te nie są nigdy wykorzystywane.

    Do kompletu powinieneś jeszcze oszukać odczyt stanu przycisku S1, najlepiej tak, żeby wyświetlane były minuty i sekundy dla lepszego uwidocznienia zliczania, czyli zamiast:
    kp = PORTB.F7 ; // read key
    wstaw:
    kp = 1;
    Oczywiście te wszystkie zmiany, które opisałem powyżej, mają charakter wyłącznie tymczasowy do przeprowadzenia próby wyświetlacza.

    A co do ostaniego pytania to nie jestem pewien, czy wpisywanie czegokolwiek do PORTB w tym miejscu programu ma w obecnej sytuacji sens. Z punktu widzenia wyświetlacza na pewno nie, bo po instrukcji PORTA=0x0F wszystkie anody są wyłączone, więc wszystkie cyfry są wygaszone. Być może autorowi chodziło o to, żeby jakieś upływności LED-ów poszczególnych segmentów wyświetlacza nie zakłócały współpracy przycisku S1 z pulldownem R13. Jeżeli w tej chwili nie masz w ogóle przycisku, to myślę, że na razie nie musisz się tym przejmować.

    Gdybyś w przyszłości chciał dodać przycisk S1, to wydaje mi się, że po zanegowaniu wyświetlacza powinien on zwierać nie do plusa a do masy, opornik R13 powinien być dołączony do plusa, i wówczas:
    zamiast PORTB = 0; powinno być PORTB = 0xFF;
    a zamiast kp = PORTB.F7; powinno być kp= ~PORTB.F7;
    Ale to na przyszłość, na razie głównym problemem jest brak współpracy z odbiornikiem DCF77 i skoro odbiornik robiłeś samemu to w tym już raczej nie będę w stanie pomóc w ramach tego tematu.
  • #11 14751421
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Dzięki za pomoc kspro
    Wczoraj walczyłem z tym tak długo, że drut uzwojeniowy z anteny przerwał mi się w najgorszym punkcie, czyli przy początku nawijania. Niestety antenka (wraz z odpowiednim kondensatorem) była wybebeszona z innego zegarka z dcf'em. Zamówiłem już odbiornik nowy i czekam.

    Bawiłem się tym przełącznikiem i wyszło z tego, że przełącznik do masy, a rezystor do +zasilania. Dodatkowo zmiana końcówki kodu na coś takiego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Działać działa to. Zegar ustawiony na sztywno liczy i sekundy i minuty (godziny pewnie tez ale nie dotrwałem do tego momentu :)) Czekam na nowy odbiornik i myślę że będzie git.
    Dzięki za pomoc jeszcze raz :)
  • #12 14761029
    pathirrus
    Poziom 11  
    Posty: 87
    Pomógł: 1
    Ocena: 6
    Witam ponownie.
    Doszła do mnie paczka z odbiornikiem DCF od conrada.
    PO podłączeniu układu i uruchomieniu zegar zachowuje się prawidłowo, ale nie może się w pełni zsynchronizować. Ciągle wyświetla bity i zliczając je, gubi się i znowu zaczyna od nowa. Wygląda na to, że nie może złapać odpowiedniej częstotliwości? Czytałem, że zła pogoda, urządzenia elektronicznie skutecznie potrafią zakłócić odbiór sygnału. A, że pogoda bardzo pochmurna to przypuszczam, że sygnał jest na tyle zakłócony, że odbiornik nie jest w stanie odebrać prawidłowo ramki.
  • #13 14761168
    Konto nie istnieje
    Konto nie istnieje  

Podsumowanie tematu

✨ Użytkownik poszukuje pomocy w dostosowaniu kodu dla mikrokontrolera PIC 16F84A do pracy z wyświetlaczami 7-segmentowymi ze wspólną anodą, zamiast ze wspólną katodą. W odpowiedziach zasugerowano negację wartości segmentów oraz modyfikację kodu, aby dostosować go do nowego schematu. Użytkownik zmienił wartości w tablicy kodów segmentów, ale napotkał problemy z działaniem wyświetlacza, który nie synchronizuje się z sygnałem DCF77. Wskazano również na możliwe zakłócenia sygnału, które mogą wpływać na odbiór. Użytkownik zaktualizował połączenia i kod, co przyniosło pewne postępy, ale nadal występują trudności z synchronizacją zegara.
Wygenerowane przez model językowy.
REKLAMA