Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

kat85 02 May 2008 14:26 1810 10
  • #1
    kat85
    Level 11  
    Robię projekt zegarka NIXIE i oczywiście mam z nim problemy :|
    Na początku zamieszczę może fotke układu.

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Program jest pisany na Atmega8 w wersji L (czyli niskonapieciowej). Uklad wyswietlacza to 4 lampy IN-14, sterowane multipleksowo, driver 74141 i jako klucze sterujace anodami lamp transoptory TLP627.

    Problem z tym układem jest taki, że gdy ustwaie wszystkie porty jako wyjścia i wszędzie stany wysokie, częśc pinow (po podlączenia przykladowo do wejść 74141) zachowuje sie jakby były w stanie wysokiej impedancji. Występuje na nich napięcie ok. 1,8V a wejścia drivera '141 zachowuja sie jak plywające (i interpretuje je jako stany wysokie). Problem rozwiązał częsciowo układ ULN2803A (dzieki niemu wejścia '141 są wysterowane prawidlowo). Niestety jest to niezbyt dobre i opłacalne rozwiązanie :| Czy ktoś wie co może byc przyczyną takiego zachowania sie atmegi?
    Problem ten ma także miejsce w przypadku sterowania transoptorami (kluczami). Dzialaja one prawidlowo dopiero po dołaczeniu do portów, które zachowuja się normalnie, w przeciwnym razie nie wysterowuja one poprawnie anod lamp. Skutek tego jest taki jak na zamieszczonym filmiku. Ta piewsza lampa od prawej jest sterowana z wyjścia, na którym wystepuje napięcie 1,8V (druga w koleji lampa miga szybciej ponieważ w czasie świecenia zostaje jeszcze wyłaczony jej klucz - transoptor).




    Cyfry na początku filmu ulozyły się przypadkowo :D

    Kolejny problem to sterowanie samych lamp. Oczywiście pojawiają się duchy co jest widoczne poniżej

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Program "testowy" jest pisany w Bascomie. Poniżej kod.
    
    Do
    
    Sel1 = 1
    Sel2 = 0
    Sel3 = 0
    Sel4 = 0
    Portd = Lookup(3 , Invbcd)
    Waitms 10
    
    Sel1 = 0
    Sel2 = 1
    Sel3 = 0
    Sel4 = 0
    Portd = Lookup(2 , Invbcd)
    Waitms 10
    
    Sel1 = 0
    Sel2 = 0
    Sel3 = 1
    Sel4 = 0
    Portd = Lookup(4 , Invbcd)
    Waitms 10
    
    Sel1 = 0
    Sel2 = 0
    Sel3 = 0
    Sel4 = 1
    Portd = Lookup(7 , Invbcd)
    Waitms 10
    
    Loop
    

    
    Invbcd:
    Data &B1111111 , &B1111110 , &B1111101 , &B1111100 , &B1111011
    Data &B1111010 , &B1111001 , &B1111000 , &B1110111 , &B1110110
    


    Po każdym wyświetleniu cyfru następuje przerwa 1ms (w powyższym przypadku - zdjeciu, a nie kodzie). Po doborze odpowiednich, maksymalnych czasow opóźnień tak aby cyfry nie migotały duchy też się pojawiaja lecz nie tak wyraznie jak poprzednio.

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Po załozeniu czerwonego filtru osoby, które o nich nie beda wiedziały pewnie ich nie zobaczą, ale niestety troche je wiadc. Czy jest jakis sposób na pozbycie się tego paskudztwa? (oprócz doboru odpowiedniej częstotliwości odświżania). Może jakaś specjalna sekwencja sterujaca? Może ktoś już robił taki zegarek i wie jak rozwiązać ten problem.
    Na koniec filmik, na którym duchów nie ma, ale cyfry migotaja w znaczący sposob.






    PS Jeśli nie działaja filmiki proszę odświeżyć stronę.


    Własnie znalazłem https://www.elektroda.pl/rtvforum/topic998383.html Sprawdze jak to sie ma do mojego przypadku. Jednak problem dalej otwarty.
  • #2
    oj
    Level 42  
    kat85 wrote:

    Program jest pisany na Atmega8 w wersji L (czyli niskonapieciowej).

    Po każdym wyświetleniu cyfru następuje przerwa 1ms


    To znaczy z jakiego napięcia jest to zasilane z 5V ?

    1ms to lampa się nie zdoła wyłączyć
  • #3
    kat85
    Level 11  
    Tak, wszystko jest zasilane napięciem 5V stabilizowanym (dlatego zamieściłem zdjęcie całego układu, żeby każdy mógł zobaczyć jak jest zrobiony - po lewej stronie jest stabilizator). Piszę, że jest to wersja niskonapięciowa bo być może fakt ten wpływa znacząco na budowę i właściwości struktury samego atmega. Być może tranzystory układów portów mikroprocesora nie są w stanie współpracować prawidłowo ze starą technologią TTL (no bo '141 ma swoje lata - jest z odzysku). Ale szczerze mówiąc wydaje mi się to mało prawdopodobne ;/

    Druga sprawa to czas opóźnień. Początkowo zaczynałem z czasami 500ms (bezsens, ale chciałem sprawdzić jak się zachowują lampy) schodząc właśnie do 1ms. Efekt tego taki, że zanim lampy przestaną migotać pojawiają się duchy. Oba te zjawiska tj. się "zazębiają", jeśli można tak powiedzieć. ostatnie zamieszczone przeze mnie zdjęcie to czas rzędu 10ms dla każdej lampy.

    aha, przypomniało mi się! Mam datasheeta do tych lamp, ale po rosyjsku i nie dużo z tego rozumiem. Jak ktoś panimajet etoj jazyk to mogę wysłać lub zamieścić. Może tam będzie coś ciekawego odnośnie czasów propagacji.
  • #4
    gregoorr
    Level 17  
    Jeśli chodzi o duszki to ja poszedłem po najprostszej linii oporu czyli:
    Rem * * * Podprogram Multipleksowania W Przerwaniu * * *
    Multi_wysw:
    Load Timer0 , 100
    Reset W1
    Reset W2
    Reset W3
    Reset W4
    Reset W5
    Reset W6
    
    
    For X = 0 To 100                                            'przerwa na wygaszenie wyświetlaczy
    Incr X : Decr X                                             'likwiduje duszki
    Next X
    


    I sprawa się rozwiązała.
    Tyle że ja mam normalną atmegę i bez uln.
  • #5
    kat85
    Level 11  
    A napisz jak to się ma do czasów. Pętla od 0 do 100, ale jaki zastosowałeś kwarc? W1-W6 to chyba liczba sterowanych lamp, zgadza się?

    For X = 0 To 100
    Incr X : Decr X 
    Next X


    Według mnie to działa tak: jeden takt na zainicjowanie pętli, drugi na zwiększenie X, trzeci na zmniejszenie X, czwarty na zamknięcie jednego cyklu (nie pamiętam czy for...next jest wykonywany w jednym czy w dwóch taktach i jaka za to odpowiada instrukcja asemblerowska, bo go nie lubię :P ). Czyli idąc tym tropem dalej instrukcje

    For X = 0 To 300
    Next X


    działały by podobnie. Chyba, że czegoś nie zrozumiałem. Niemniej spróbuje tego rozwiązania :D

    Słyszałem już dużo głosów, że takie projekty (czyli atmega i '141) działają bez problemowo i coraz bardziej zaczynam się przekonywać, że wina leży gdzieś po stronie samego mikroprocesora. Gdzie dokładnie? nie wiem. Najprościej będzie kupić zwykłą wersję i sprawdzić na tym samym programie. Jednak nie będzie możliwe zastosowanie zasilania bateryjnego 2xAAA, a wtedy zegarek straci dużo na funkcjonalności. Choć zaniki napięcia zdarzają sie raczej rzadko, a jeśli nawet, to ponowne ustawienie czasu zajmie mniej więcej minutę... :? W poniedziałek kupię atmege w wersji normalnej i zobaczymy co z tego wyniknie 8)

    Co do dziwnego zachowania się portów, zrobiłem tak jak pisało w w/w temacie jednak nic to nie pomogło :cry:

    Po przeprowadzonych próbach duchy znikneły :D Zgodnie z pomysłem kolegi zostalo wprowadzone dodatkowe opóźnienie celem całkowitego wygaszenia lamp. Teraz kod wyświetlania wygląda tak:

    sel4 = 0        'wygaszenie czwartego wyswietlacza z poprzedniego cyklu
    waitus 700      'czas potrzebny na jego calkowite wygaszenie
    sel1 = 1       'zalaczenie aktualnie obslugiwanego wyswietlacza
    portd = lookup(z, invbcd)       'zapis na port odpowiedniej liczby do wyswietlenia
    waitms 5        'opóźnienie cylku multipleksowania



    A same lampy tak

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Jeden problem z głowy, zostało jeszcze ich milion :wink:
  • #6
    gregoorr
    Level 17  
    Tu to co brakowało w poprzednim poście:
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Timer0 = Timer , Prescale = 256
    
    On Timer0 Multi_wysw
    

    W1-W6 to wyświetlacze, pierwsze zegary robiłem bez sekundnika, ten już je ma, chyba ciekawszy efekt. W budowie nie ma prawie żadnej różnicy, te 2 lampy więcej nie robią jakiejś poważnej różnicy. Potrzeba tylko 2 porty więcej. U mnie do odliczania czasu są PCF-y i mam potrzymanie bateryjne.

    Lampy mam tak ustawione
    AB:CD:EF
    Dane dla A,B,C,D,E i F pobierane są z PCF-a, a cała obsługa wyświetlania w przerwaniu wygląda tak:
    
    Rem * * * Podprogram Multipleksowania W Przerwaniu * * *
    Multi_wysw:
    Load Timer0 , 100
    Reset W1
    Reset W2
    Reset W3
    Reset W4
    Reset W5
    Reset W6
    
    
    For X = 0 To 100                                            'przerwa na wygaszenie wyświetlaczy
    Incr X : Decr X                                             'likwiduje duszki
    Next X
    
    Select Case Y:
    
    Case 1:
    Portd = A
    Set W1
    
    Case 2:
    Portd = B
    Set W2
    
    Case 3:
    Portd = C
    Set W3
    
    Case 4:
    Portd = D
    Set W4
    
    Case 5:
    Portd = E
    Set W5
    
    Case 6:
    Portd = F
    Set W6
    
    End Select
    
    Incr Y
    If Y = 7then
    Y = 1
    End If
    
    Return
    
  • #7
    teedd
    Level 18  
    Witaj.
    kat85 wrote:
    Jak ktoś panimajet etoj jazyk to mogę wysłać lub zamieścić. Może tam będzie coś ciekawego odnośnie czasów propagacji.

    Podeślij link - poczytam i dam znać, czy jest tam coś ciekawego dla Ciebie.
    Pozdrowienia - teedd
  • #8
    kat85
    Level 11  
    Oto one. Znalezione na stronie o podobnej tematyce.

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    Poszedłem tropem, jaki podsunął kolega gregoorr i zrobiłem program na PCF. Wszystko chodziło jak należy, ale jak ponownie zaprogramowałem atmege na wyświetlaczu widnieją same 4 :| Ręce juz mi opadają ...
  • #9
    teedd
    Level 18  
    Witaj.
    Jeśli chodzi o czasy, to w dokumentacji jest napisane, że opóźnienie zapalenia cyfry może mieć maksymalną wartość 1s. Przy sterowaniu multipleksowym minimalny czas impulsu wynosi 70 mikrosekund, a częstotliwość powtarzania impulsów miedzy 1kHz a 1,8kHz. Czyli jeśli masz 6 wyświetlaczy, to powinieneś je sterować z częstotliwością między 6kHz a 11kHz.
    Jeśli chodzi o te "duszki", to wydaje mi się, że nie ma co stosować jakichś magicznych sztuczek, tylko zrobić odpowiednie sterowanie lampami. Narysuj fragment schematu lub daj link do schematu. No i program, jeśli chcesz, aby Ci pomóc.
    teedd
  • #10
    kat85
    Level 11  
    Właściwie z duchami się juz uporałem, ale zamieszczam to, o co kolega prosił. Pomogło dodanie opóźnienia 700us po wygaszeniu lampy. Oto schemat sterowania jednej lampy:

    Atmega8L+NIXIE. Przyczyna dziwnego zachowania atmegi?

    $regfile = "m8Def.dat"
    $crystal = 4000000
    
    
    Config Portb = $b11111111                                   '8
             Portb = $b11111111
    Config Portc = $b1111111
             Portc = $b1111111                                  '7
    Config Portd = $00011111                                    '8
             Portd = $11111111
    
    Wdtcr = Wdtcr And $b11110111                                'disable watchdog
    
    Sw1 Alias Pind.6
    Sw2 Alias Pind.7
    Sw3 Alias Pind.5
    Sel1 Alias Portb.4
    Sel2 Alias Portb.0
    Sel3 Alias Portc.0
    Sel4 Alias Portc.4
    Dt_a Alias Portd.0
    Dt_b Alias Portd.1
    Dt_c Alias Portd.2
    Dt_d Alias Portd.3
    
    Sel1 = 0 : Sel2 = 0 : Sel3 = 0 : Sel4 = 0
    
    
    Dim X As Word : X = 0
    Dim Jed As Byte : Jed = 0
    Dim Dzie As Byte : Dzie = 0
    Dim Setki As Byte : Setki = 0
    Dim Tys As Byte : Tys = 0
    Dim Licznik As Byte : Licznik = 0
    Dim Predkosc As Byte : Predkosc = 50
    
    Do
    
    If Sw1 = 0 Then
       Predkosc = Predkosc - 5
       If Predkosc < 5 Then
          Predkosc = 5
       End If
    End If
    
    If Sw2 = 0 Then
       Predkosc = Predkosc + 5
       If Predkosc > 100 Then
          Predkosc = 100
       End If
    End If
    
    Incr Licznik
    
    If Licznik = Predkosc Then
       Incr X
       Licznik = 0
    End If
    
    If X = 9999 Then
       X = 0
    End If
    
    Tys = X / 1000
    Setki = X Mod 1000 : Setki = Setki / 100
    Dzie = X Mod 100 : Dzie = Dzie / 10
    Jed = X Mod 10
    
    Sel4 = 0
    Waitus 700
    Sel1 = 1
    Portd = Lookup(jed , Invbcd)
    Waitus 5000
    
    Sel1 = 0
    Waitus 700
    Sel2 = 1
    Portd = Lookup(dzie , Invbcd)
    Waitus 5000
    
    Sel2 = 0
    Waitus 700
    Sel3 = 1
    Portd = Lookup(setki , Invbcd)
    Waitus 5000
    
    Sel3 = 0
    Waitus 700
    Sel4 = 1
    Portd = Lookup(tys , Invbcd)
    Waitus 5000
    
    Loop
    
    End
    
    Invbcd:
    Data &B1111111 , &B1111110 , &B1111101 , &B1111100 , &B1111011
    Data &B1111010 , &B1111001 , &B1111000 , &B1110111 , &B1110110


    Nie ma komentarzy bo program jest według mnie czytelny Wyjaśnienia może wymagać dziwne zestawienie danych w Invbcd. Chodzi o to, że '141 jest sterowane przez układ ULN więc wszystko trzeba było zanegować.
    No, ale jest to drugi z opisywanych przeze mnie problemów (dziwne zachowanie sie portów), z którym do tej pory nie dałem sobie rady. Zmieniłem układ na 90S4433, ale problem taki jak w atmega8. Podobno, gdy użyte są alternatywne funkcje poszczególnych pinów, nie można z nich korzystać jako porty I/O (co jest całkiem logiczne). Jednak ja nie włączałem żadnego z układów za to odpowiedzialnych. W datasheet atmegi wyczytałem, że po inicjalizacji procesora po resecie wszystkie rejestry zostają wypełnione zerami, czyli alternatywne funkcję portów zostają wyłączone. Ale może Bascom je w jakiś sposób inicjalizuje? Nie powinien. Przestudiuję jeszcze raz dokładnie datasheet i powyłaczam wszystkie układy korzystające z pinów. W tym miejscu mam gorącą prośbę. Czy może ktoś zamieścić plik hex skompilowanego programu w C, który inicjalizuje wszystkie porty jako wyjścia i standardowo ustawia na nich stan wysoki?
  • #11
    teedd
    Level 18  
    Witaj.
    Dzięki za schemat i listing programu.
    1. Duszki. Pracując z lampami zapominamy, że są to elementy trochę inne, niż te do których przywykliśmy. Na początek spróbowałbym dać rezystor o wartości np. 1 MOhm między anodą lampy a masą (oczywiście usuwając wszelkie opóźnienia i sztuczki zastosowane do walki z "duszkami". Jeśli to da jakiś efekt, to można poeksperymentować z wartością tego rezystora. Jeśli takie rozwiązanie nie da efektu, to spróbuj zmienić sterowanie tak, jak na załączonym rysunku - to taka mała modyfikacja Twojego schematu. Oczywiście musisz zmienić troszeczkę program - aktywna lampa to stan L na wejściu SEL.
    2. Program. Jeśli chodzi o program, to sekcja odpowiadająca za wyświetlanie cyfr na poszczególnych miejscach wydaje sie mi prawidłowa. Twoje problemy są bardzo łatwe do zdiagnozowania - między fragmenty programu, które wygaszają daną lampę i włączają następną wstaw np. coś takiego:
    do
    Loop Until Pind.5 = 0
    waitms 50
    do
    Loop Until Pind.5 = 1
    waitms 50
    

    Dzięki temu będziesz mógł sobie pomierzyć stany na liniach wejściowych i wyjściowych po każdej zmianie wartości X.
    Pozdrowienia - teedd