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

bascom+atmega - konfigurowanie pinu jako wyjście...

sundayman 06 Nov 2013 20:55 2625 22
  • #1
    sundayman
    Level 25  
    Problem jest nieco bardziej skomplikowany (atmega128 + Bascom);

    Otóż jeden z pinów MCU1 służy mi do resetowania innego MCU2. Czyli pin ten musi być normalnie w stanie wysokim, a w razie potrzeby jest ustawiany na moment na "0". Fizycznie ten pin podłączony jest do wejścia RESET MCU2 poprzez diodę, a sam RESET MCU2 oczywiście normalnie jest podciągnięty rezystorem 5K1 do zasilania. Kiedy wyjście resetujące MCU spada na "0" to poprzez diodę resetuje nam MCU2. Proste :)

    Jednak, problem powstaje w momencie konfiguracji pinu w MCU1.
    Po starcie MCU1piny nie skonfigurowane są w stanie wysokiej impedancji. I nie ma problemu.

    Jednak, kiedy na starcie programu chcę skonfigurować dane wyjście MCU1 (PORT G.4) jako wyjście, i ustawić na na "1", to niestety mimowolnie generuje mi to króciutki impuls "0", ponieważ po komendzie ustawiającej pin jako wyjściowy, a przed ustawieniem wyjścia na "1" - pojawia się tam stan niski na chwilkę;



    Wygląda to tak;

    Code:

    Config Portg.4 = Output   

    ' *** tutaj mamy na portg.4 stan niski !!!!

    Reset_mcu2 Alias Portg.4
    Reset_mcu2 = 1

    ' *** teraz dopiero na portg.4 jest stan wysoki



    Czyli pytanie jest następujące - jak zadeklarować pin jako wyjście, przechodząc ze stanu wysokiej impedancji od razu do stanu wysokiego ?
  • #2
    Kuniarz
    Moderator of Designing
    Może (nie sprawdzone) najpierw:

    set portg.4

    a później

    config PINg.4 = output (ważne, powinno być PIN a nie PORT)
    ...dopiero dalej alias
  • #3
    sundayman
    Level 25  
    Niestety, tak nie działa - config PIN ustawia pin jako wejście tak czy siak, i później nic nie można wysłać tam...

    Wymyśliłem rozwiązanie "zastępcze" - konfigurować pin jako wyjściowy dopiero tuż przed realnie potrzebnym resetem MCU2. No ale to jest takie sobie :)
  • #4
    User removed account
    Level 1  
  • #5
    sundayman
    Level 25  
    Niestety, modyfikacje układowe są już niemożliwe.
    Nie ma żadnego "zewnętrznego generatora".

    Urządzenie zawiera dwa MCU - każdy ma możliwość resetowania drugiego - innymi słowy - jeden nadzoruje drugi (komunikują się po RS232) i w razie jeśli któryś się by "powiesił" wtedy kolega go podnosi :)

    Ale problem pojawił się podczas uruchamiania urządzenia w niskiej temperaturze - po prostu podczas konfigurowania wyjść następuje nieprzewidziane "resetowanie wzajemne" - co ciekawe w temperaturze pokojowej problemu nie było, właśnie z powodu innego czasu uruchamiania.

    Ale rozwiązanie powyższego problemu z konfigurowaniem wyjść usunie problem całkowicie, niezależnie od czasów.
  • #6
    User removed account
    Level 1  
  • #7
    dondu
    Moderator on vacation ...
    sundayman wrote:
    Ale problem pojawił się podczas uruchamiania urządzenia w niskiej temperaturze - po prostu podczas konfigurowania wyjść następuje nieprzewidziane "resetowanie wzajemne" - co ciekawe w temperaturze pokojowej problemu nie było, właśnie z powodu innego czasu uruchamiania.

    Pokaż schemat i napisz co oznacza według Ciebie "niska temperatura".
  • #8
    sundayman
    Level 25  
    Quote:
    do tego służy watchdog i nie trzeba zdublowanego systemu resetów, który moim skromnym jest konstrukcją błędną


    Właśnie, nie rozumiemy się :)

    Otóż, w urządzeniu, które jest sterownikiem pewnej pompy, początkowo był tylko jeden MCU. Oczywiście program korzysta z watchdoga. Był także, w jednej z początkowych wersji , watchdog zewnętrzny. Jednak okazało się to zbyteczne, ponieważ wbudowany watchdog AVR działa wystarczająco dobrze, i dublowanie go nie ma sensu.

    Ale - okazuje się, że nie jest to wystarczające, ponieważ zdarzają się sytuacje, w których program działa niepoprawnie - a jednak watchdog nie restartuje urządzenia.
    Oczywiście są to sytuacje "patologiczne" - podczas już prawie 2 lat działania urządzeń w warunkach "polowych" zdarzyło się np. że pobliskie wyładowanie (z burzy) spowodowało "odpięcie" rezystorów wewnętrznych AVR na liniach klawiatury, co spowodowało, że "poprawnie" działający program wykonywał polecenie "ducha" naciskającego klawisze :)

    Niezwykłe, ale prawdziwe - nic innego nie zostało uszkodzone, jedynie ten rejestr został wyłączony - i to tymczasowo, po resecie wszystko wróciło do normy.
    A udało się dojść do przyczyny tego dziwnego zjawiska tylko dlatego, ze sterownik zapisuje występujące zdarzenia ("rejestr zdarzeń").

    Czyli - watchdog oczywiście tak - ale to nie jest zabezpieczenie 100%.
    Rzecz jasna, poprawnie napisany program to przynajmniej równie ważna rzecz, ale-
    nie da się wszystkiego przewidzieć, jak się okazało.

    Dlatego też został wprowadzony dodatkowy układ "bezpieczeństwa", który
    zasadniczo, w oparciu o własne, wprowadzone dane, kontroluje czy główny MCU działa poprawnie, i w razie potrzeby albo wyłącza całe urządzenia, albo tylko resetuje.

    Oczywiście - to jest także nie jest zabezpieczenie 100%, ale ryzyko jednoczesnego niepoprawnego działania dwu niezależnych MCU jest odpowiednio niższe.

    Nie ma sensu pokazywanie schematu (który jest poza wszystkim zbyt duży), ale idea o której tutaj mowa jest banalnie prosta (jak już pisałem) ;

    Główny MCU (Atmega128) oraz "dodatkowy" (Atmega8) są skomunikowane via RS232. Dzięki temu wymieniają informacje - jeśli jeden z nich stwierdzi, że drugi nie odpowiada - wtedy może go zresetować (to jest uproszczenie, bo trochę to działa inaczej, ale nie w tym rzecz tutaj).

    Fizycznie - każdy z MCU posiada wejście RESET podciągnięte normalnie zewnętrznym rezystorem 5K1 do plusa, oraz - przez diodę - podłączone do jednego z pinów drugiego MCU. No banał.

    Jedyny obecny problem, to ten, że podczas startu systemu oba MCU deklarują te odpowiednie piny jako wyjścia - i wtedy właśnie, na skutek opisanego mechanizmu , następuje niekorzystne resetowanie. Co ciekawe - w temperaturze pokojowej wszystko działa ok.

    Oba MCU mają bootloadery (żeby mieć możliwość ładowania właściwego softu via wyprowadzony RS232). I właśnie - w temp. pokojowej, mimo, że przy uruchamianiu występują te impulsy resetujące na skutek deklarowania wyjść - no wszystko działa poprawnie.

    Tak oczywiście nie powinno być - bo to jest niekorzystne zjawisko, i te resety powinny być wykonywane tylko "na żądanie". Ale - okazało się, że w normalnej temp.
    mimo, że te "przypadkowe" impulsy resetujące też się pojawiają , to nic złego się nie dzieje.

    A w temperaturze poniżej ok. +2 st. minimalnie zmieniają się czasy, w których się te
    impulsy resetujące pojawiają, i zaczyna się wtedy cyrk :)


    Czyli - źródłem całego zamieszania jest podstawowy błąd - generowanie nieprzewidzianych sygnałów RESET podczas startowania systemu.
    To, że w normalnej temp. nie powoduje to problemu, to tylko kłopot "maskujący"
    całe zjawisko. Jak to się dzieje, że normalnie nie powoduje to nic złego - nie wiem.

    Aha, Atmega128 ma rezsonator kwarcowy, a Atmega8 korzysta z wewnętrzenego.
    Żeby ujawnił się problem, wystarczy ochłodzić Atmega128 (sam chip, bez chłodzenia kwarcu i czegokolwiek innego). Zrobiłem to zabezpieczając otoczenie chipa, przyklejając do Atmegi mały metalowy radiatorek i chłodząc ten radiatorek.

    Oczywiście , nie ma tu mowy o jakimś lucie nieprawidłowym (że niby po ochłodzeniu coś nie kontaktuje), bo wszystkie sygnały docierają prawidłowo. Wystarczy wylutować diodę, przez którą MCU2 resetuje MCU1 i problem znika.

    ___________________________________________________

    Nie wiem, na ile udało mi się wyjaśnić , ale się starałem :)

    Zatem - potrzebne jest "eleganckie" rozwiązanie konfigurowania wyjścia, bez ustawiania go przejściowo na "0". Oczywiście, można jak wspomniałem, robić to dopiero tuż przed potrzebnym resetem, i będzie to działać poprawnie - ale to nie jest
    "estetyczne" rozwiązanie.
  • #9
    dondu
    Moderator on vacation ...
    Selektywne chłodzenie mikrokontrolera w oderwaniu od innych elementów, to nie jest poprawny test na działanie urządzenia.
    Ponowię prośbę o schemat, bo bez tego, to gdybanie ... podczas gdy przyczyna może leżeć zupełnie w innym miejscu.
  • #10
    sundayman
    Level 25  
    Quote:
    Selektywne chłodzenie mikrokontrolera w oderwaniu od innych elementów, to nie jest poprawny test na działanie urządzenia.


    Całe urządzenie jest testowane w całości - w odpowiedniej zamrażarce :)
    I tam się problem "wykrył". A że "winowajcą" (*) jest ochłodzenie Atmegi128 doszedłem drogą testów, i dlatego teraz mogę sobie to na biurku sprawdzać.

    (sprawdzone na kilku urządzeniach, nie jest to kwestia "osobnicza" itp.
    Naprawdę nie leży problem w schemacie, uwierz mi na słowo, że z jakiegoś powodu
    minimalne wydłużenie czasu startu Atmegi128 powoduje, że reset przychodzący z drugiego MCU powoduje problemy).

    Ale - zostawmy to - bo teraz to wszystko razem nie ma już znaczenia :)
    Gdybym nie popełnił błędu, umieszczając w obu programach tej nieszczęsnej deklaracji wyjść na początku - lub gdyby ta deklaracja nie powodowała błędnego generowania sygnałów, to wszystko byłoby ok.

    I w tej chwili poszukujemy już tylko rozwiązania opisanego na wstępie -
    jak w tych nieszczęsnym bascomie zadeklarować wyjście bez ustawiania go na "low" ?
    _________________________________________________________________
    (*) nie jest prawdziwym winowajcą, tylko wtedy ujawnia się prawdziwa przyczyna.
  • #12
    sundayman
    Level 25  
    Quote:
    zbytnio przekombinowałeś swój projekt


    No rozumiem, że to tak może wyglądać, ale to jest efekt ponad 2 lat pracy nad tym sterownikiem, wykrywania różnych problemów "w terenie" . W sumie jest już 3 czy 4 wersja (właśnie ta z wprowadzonym dodatkowym układem zabezpieczającym) i kilkadziesiąt działających urządzeń.

    Taka "nadmiarowa" pozornie ochrona jest uzasadniona, bo błędna praca sterownika
    może stworzyć pewne niebezpieczeństwo dla ludzi, stąd taki wymóg "kontrolowania za wszelką cenę".

    W pewnym sensie - jest to układ zewnętrznego watchdoga, który jednak jest bardziej "wymagający" niż normalnie, bo nie wystarcza mu tylko "machanie" pinem, żeby go zresetować.

    Takie rozwiązanie "wzajemnego" nadzoru jest bardzo skuteczne - i raczej się zdarzy, że cały system zostanie wyłączony "bez powodu" , niż że główny MCU będzie wykonywał coś niepoprawnego. I to jest poprawne, ponieważ lepiej , żeby układ się wyłączył niepotrzebnie, niż żeby działał źle.
  • #14
    sundayman
    Level 25  
    No więc widzę, że muszę zacząć grzebać w rejestrach, żeby najpierw wpisać wartość pinu, a potem przełączyć kierunek, bo w bascomie "configiem" chyba się nie da łatwo...

    Myślałem, że może ktoś już to robił, ale skoro nie , to bierę dataszita i spróbuję...
  • #15
    dondu
    Moderator on vacation ...
    sundayman wrote:
    No więc widzę, że muszę zacząć grzebać w rejestrach, żeby najpierw wpisać wartość pinu, a potem przełączyć kierunek, bo w bascomie "configiem" chyba się nie da łatwo...

    No to nadszedł czas na krok do przodu --> C :)
  • #16
    sundayman
    Level 25  
    Quote:
    No to nadszedł czas na krok do przodu --> C


    Ba - planuję w przyszłości zrobienie nowej wersji programu, ale
    zacząłem 2 lata temu w Bascomie (bo to jednak bardzo szybko się w nim robi)
    i teraz program ma 10021 linii (zajmuje mi całe 128K) , i niestety nie ma czasu na pisanie od początku...

    Poza różnymi "wpadkami" zresztą sprawdza się ten bascom nienajgorzej,
    oczywiście zdarzały się różne cuda... Podstawowym problemem jest jednak żarłoczność - to co kompilator generuje chyba niewiele ma wspólnego z oszczędnością pamięci programu...

    Tak czy siak - na razie muszą brnąć dalej - obecnie całość generalnie działa bez zastrzeżeń, jedynie dodanie tego drugiego MCU mi spowodowało opisane niespodziewane kłopoty...
  • #17
    dondu
    Moderator on vacation ...
    sundayman wrote:
    ... w Bascomie (bo to jednak bardzo szybko się w nim robi)
    i teraz program ma 10021 linii (zajmuje mi całe 128K) , i niestety nie ma czasu na pisanie od początku...

    Podstawowym problemem jest jednak żarłoczność - to co kompilator generuje chyba niewiele ma wspólnego z oszczędnością pamięci programu...

    Oj, od następnego projektu koniecznie zmień język. Im szybciej przejdziesz na C tym lepiej dla Ciebie.
  • #18
    sundayman
    Level 25  
    No więc rozwiązanie okazuje się (jak zwykle) banalne;

    W dataszicie czytamy :

    *****************

    When switching between tri-state ({DDxn, PORTxn} = 0b00) and output high ({DDxn, PORTxn}
    = 0b11), an intermediate state with either pull-up enabled ({DDxn, PORTxn} = 0b01) or output
    low ({DDxn, PORTxn} = 0b10) must occur. Normally, the pull-up enabled state is fully acceptable,
    as a high-impedant environment will not notice the difference between a strong high driver
    and a pull-up. If this is not the case, the PUD bit in the SFIOR Register can be written to one to
    disable all pull-ups in all ports.

    *****************

    Czyli niestety, przełączając ze stanu TRI-STATE do HIGH nie ma lewara, musimy mieć włączony rezystor podciągający. No ale - nic nam to nie robi przecież, bo i tak potrzebujemy stan wysoki.

    Czyli zamiast używać CONFIG robimy tak (dla przypomnienia - chodzi o pin G.4) ;

    Code:

    ' ustawiamy wartość pinu na H, tak jakbyśmy chcieli włączyć rezystory podciągające
    ' przy czym dla pinów 0 i 1 rzeczywiście chodzi o podciąganie , a dla 4 - tylko "chwilowo"

    Portg = &B00010011       
     
    ' teraz określamy kierunek pinów (piny 0,1,2 jako wejścia, piny 3 i 4 jako wyjścia 
                 
    Ddrg = &B00011000                                       

    Reset_mcu2 Alias Portg.4


    I wyglada na to, że działa to poprawnie. Tzn podczas deklaracji nie pojawia się
    ujemny impuls na G.4 , a dalej w programie można sobie ostawić ten poziom w razie potrzeby.
  • #19
    Andrzej222
    Level 2  
    Moje pytanie związane z Arduino, dlaczego w Arduino po skonfigurowaniu I2C niepotrzebne są oporniki podciągające , a Bascomie konfigurując I2C oporniki
    muszą być zapięte? Mam na myśli te same piny (Arduino Nano SDA - PC.4 SCL-PC.5)
  • #20
    slawko_k
    Level 34  
    Oporniki muszą być bo tego wymaga magistrala.
    Może nie zauważyłeś ze je masz w podłączanym urządzeniu.
  • #21
    Andrzej222
    Level 2  
    Rozumiem ale, gdy ładuję programik obsługujący I2C z kompilatora C++ Arduino
    I2C działa. Natomiast gdy podobny programik ładuję po skompilowaniu w Bascomie
    I2C zacznie działać dopiero po podpięciu oporników podciągających. Skąd te różnice ?
  • #22
    slawko_k
    Level 34  
    Na pewno w kodzie arduino masz dopisane pullupy a w bascomie nie.
    Ale to nie rozwiązuje problemu bo rezystory musza być.
    Na wewnętrznych jeżeli nawet działa to nie sa one prawidłowe wiec transmisja padnie przy małym zakłóceniu czy przedłużeniu kabli.
  • #23
    Andrzej222
    Level 2  
    Zgoda na tym etapie mnie przekonałeś Dzięki za zainteresowanie problemem