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

[Mega32][Bascom] PCF8583 ustawianie czasu przez menu

Elektronik_Kraków 07 Mar 2011 01:11 3372 9
  • #1
    Elektronik_Kraków
    Level 13  
    Witam
    Chciałem mieć możliwość ustawiania czasu i daty za pomocą dwóch przycisków - SELECT i +.
    Założenie jest takie, aby menu ustawiania czasu uruchamiać przez przycisk Menu_ustaw oraz zatwierdzać, a zwiększać wartość przez przycisk Ustaw

    Napisałem coś takiego
    Code: basic4gl
    Log in, to see the code

    Efekt jest taki, że po naciśnięciu przycisku menu_ustaw ( czyli wybierającego/zatwierdzającego ) program przechodzi od razu do ustawiania godzin - LCD wyświetla "Ustaw godzine" ( pomija Case 1 ) i zawiesza procesor.
  • #2
    gray77
    Level 12  
    Widzę parę błędów. Wieczorkiem będę miał więcej czasu i Ci poprawię.

    Edit:

    Nigdzie w tym podprogramie nie zwiększasz zmiennej: Start_menu - dlatego nie działa.
    Opcje Select Case bym wyrzucił i zrobił to na IFach tylko. Jeśli warunek w IFie jest prawidłowy, wtedy komunikat na LCD i stosowna procedura.
    Pętla Do Loop miałaby za zadanie tylko sprawdzać przyciski, musisz pomyśleć tez o wyjściu z tej niekończącej się pętli.

    A procesor się nie zawiesza w twoim przypadku tylko cały czas wyświetla "Ustaw minuty" i sprawdza dalej kombinacje klawiszy, która zawsze będzie niestety taka sama. Wstaw sobie na próbę polecenie CLS zaraz po Do i zobaczysz, ze wyświetlacz będzie migał z tym napisem.
  • #3
    Elektronik_Kraków
    Level 13  
    Dzięki za odpowiedź.
    Wzorowałem się na Link

    Co do nie zwiększania zmiennej Start_menu - myślałem, że
    
    If Menu_ustaw = 0 And Start_menu = 1 Then
     Incr Start_menu
    End If
    
    If Menu_ustaw = 0 And Start_menu = 5 Then
     Start_menu = 1
    End If
    

    to załatwi problem.
    Wolałbym zostać przy Case, wtedy mam możliwość zmiany dowolnie wybranych wartości.
    Czy przy każdym podprogramie dla każdej wartości powinienem się odwołać na końcu do procedury zapisu settime ?

    Wstawiłem w kilku miejscach waitms i faktycznie - program wyświetla najpierw ustawienie minut, następnie godzin, ale dalej już nic.
    Co do wyjścia z pętli - masz na myśli If Then Exit Do. Może użyć flagi i przy wejściu do programu Menu ustawiać ją na 1 a po zapisie Settime ustawiać na 0 i wtedy If Flaga = 0 Then Exit Do
  • Helpful post
    #4
    gray77
    Level 12  
    Po mojemu to mogło by być tak.

    
    '*********************** Podprogram ustawiania godzin ,minut, dni i miesięcy
    
    Sub Menu:
    Start_menu = 0
    
    Do 
    
    If Menu_ustaw = 0 Then
       Waitms 25
          If Menu_ustaw = 0 Then
             Incr Start_menu
             If  Start_menu >= 6 Then
                Start_menu = 0
             End If
          End If
    End If
    
    
    Select Case Start_menu
       Case 0 :
       Case 1 :
          Locate 1 , 1
          Lcd "Ustaw minuty"
          Wait 1 : Cls : Gosub Ustaw_min
       Case 2 :
          Locate 1 , 1
          Lcd "Ustaw godzine"
          Wait 1 : Cls : Gosub Ustaw_godz
       Case 3 :
          Locate 1 , 1
          Lcd "Ustaw dzien"
          Wait 1 : Cls : Gosub Ustaw_dzien
       Case 4 :
          Locate 1 , 1
          Lcd "Ustaw miesiac"
          Wait 1 : Cls : Gosub Ustaw_mc
       Case 5 :
          Locate 1 , 1
          Lcd "Zapisz"
          Wait 1 : Cls : Gosub Ustaw_Settime 
       End Select
    
    If Klawisz_ESC = 0 Then                  ' Tutaj musisz sobie określić klawisz lub ich kombinacje do wyjścia z podprogramu Menu
       Exit Do                              
    End If
    
    Loop
    
    Return


    Powinno działać. Nie sprawdzałem w Bascomie bo jestem w pracy i nie mam dostępu. Jak by coś nie działało, daj znać, będziemy naprawiać.
  • #5
    Elektronik_Kraków
    Level 13  
    Bardzo dziękuje, działa jak trzeba.
    Teraz rozumiem, że logiczna kolejność jest najważniejsza - warunek zwiększania Menu_ustaw był nie taki jak trzeba i źle umieszczony.
    Na razie wyjście z programu zrobiłem na trzecim przycisku, ale trochę szkoda go marnować do tego, można na nim zrobić obsługę czegoś innego - w przypadku, gdy program nie jest trybie ustawiania daty/czasu.
    Można by też przy użyciu Timer0.
    Tylko czy można używając tylko jednego Timer'a sterować kilkoma parametrami ?
    W tym momencie wykorzystuję Timer0 do sterowania długością czasu podświetlania wyświetlacza pełną jasnością.

    Mam coś takiego:
    
    '**************** Podprogram Timer0 **********
    Czas:
    Counter0 = Counter0 + 6
    Incr Licznik                                                'zwiększaj stan licznika
    If Flaga_lcd = 1 Then
    
    If Licznik = T Then                                         'jeśli Licznik = T
    Ocr2 = 80                                                   'jesli Pwm1a większe od 0
    Licznik = 0
    Flaga_lcd = 0                                               'zeruj licznik
    
    End If
    End If
    Return
    
    


    Czy wystarczy dodać Licznik2 oraz drugą zmienną?

    Mam też problem z UART, który opisałem Tutaj.
    Komunikacja przez UART blokuje odczyt stanu przycisków.
    To że UART jest konfliktowy z przerwaniami to już zdążyłem zauważyć i nawet odczuć w swoim kodzie ( mam wysyłanie cykliczne danych z pomiarów do PC ) i naciśnięcie przycisku obsługującego jasność wyświetlacza powiązanego z Timer0, sterującym długością czasu podświetlania ma taki dziwny problem, ( dane wysyłam w oparciu o zegar PCF co 10 sekund ,czyli 10, 20 ,30, 40, 50 ), naciskam przycisk podświetlania, gdy zegar wskazuje 10:20:30 i w tym momencie podświetlanie się nie włącza, jak nacisnę o 10:20:32 to się włącza i odlicza czas ustawiony w Timer0.
  • #6
    gray77
    Level 12  
    Quote:
    Bardzo dziękuje, działa jak trzeba.

    Ciesze się ze pomogłem.

    Wyjście możesz zrobić również za pomocą kombinacji przycisków, np wciśnięte dwa na raz. Niestety trzeba jednak ta kombinacje zapamiętać.
    Tak jak napisałeś, można wykorzystać Timer. Dodajesz druga flagę, np Wyjscie_menu i zwiększasz ja w Timerze a w podprogramie Menu ustawiasz sobie, ze jeśli osiągnie 30 to wychodzi całkowicie z menu.
    Lub wchodząc do menu aktywować zliczanie sekund z PCFa i po opływie ileś tam sekund automatycznie opuszczasz menu.

    Quote:
    Mam też problem z UART...

    Kompletnie sie na tym jeszcze nie znam. Nie był mi nigdy UART potrzebny i w tej dziedzinie nie pomogę.
  • #7
    Elektronik_Kraków
    Level 13  
    Czy mógłbyś dać przykład z tym Timer0 ?
    Tzn. pewnej rzeczy nie rozumiem, ktoś na tym forum napisał, że jednym Timerem można "sterować" kilkoma funkcjami ( nie napisał szczegółów ).
    Zakładam coś takiego.
    Mam 3 układy DS18B20, każdy w umieszczony w podprogramie. Mam wyświetlacz tylko 16*2, przy czym dolną linię używam do wyświetlania daty i czasu, a na górnej chcę wyświetlać naprzemiennie wskazania tech trzech czujników, korzystając z czasu odmierzonego przez Timer0, jednocześnie określam długość czasu jaśniejszego świecenia LCD. Dodatkowo można by zrobić wyjście z menu ustawień zegara po określonym czasie Timer0.
    Czy jest możliwe ? Nie chcę używać Timer1 anie Timer2, bo są już wykorzystane - wyjście PWM i PWM wyświetlacza. Można by wykorzystać wyjście INT PCF8583 i podłączyć je do uC, żeby zliczało, ale ciekawsze rozwiązanie to Timer0.
  • #8
    gray77
    Level 12  
    Czy twój Timer0 załącza się na początku programu, po lub przed definicjami stałych, konfiguracji portów? Jeśli tak, czy go gdziekolwiek w programie wyłączasz? Jeśli nie tzn, że działa on cały czas od momentu podania zasilania.

    Tylko i wyłącznie od ciebie zależy co on będzie robił. Dodajesz tyle flag/znaczników w programie, ile potrzebujesz, w Timer0 je zwiększasz a w programie głównym dajesz zależności, co ma się stać gdy np. Flaga48 = 30.

    Najlepszym rozwiązaniem jest, gdy Timer0 będzie ci odmierzał 1s odcinki czasu i wtedy masz wszystkie czasowe wł/wył załatwione przez niego.
  • #9
    Elektronik_Kraków
    Level 13  
    Timer0 włączam na początku przy konfiguracji

    
    '********** Konfiguracja Timer0
    
    Config Timer0 = Timer , Prescale = 1024
    Enable Timer0
    
    On Timer0 Czas
    


    w programie głównym
    
    '************ sterowanie czasem jasnością podświetlania LCD
    If Flaga_lcd = 0 Then
    Ocr2 = 80
    End If
    If Enter = 0 Then
    Ocr2 = 200
    Flaga_lcd = 1
    End If
    
    


    później mam program Timer0

    
    Czas:
    Counter0 = Counter0 + 6
    Incr Licznik                                                'zwiększaj stan licznika
     If Flaga_lcd = 1 Then
      If Licznik = T Then                                       'jeśli Licznik = T
      Ocr2 = 80                                                 'jesli Pwm1a większe od 0
      Licznik = 0
      Flaga_lcd = 0                                             'zeruj licznik
     End If
    End If
    
    

    i chyba coś nie tak robię, nie wiem, czy dobrze Cię zrozumiałem, wydaje mi się że powinno być tak:
    
    Czas:
    Counter0 = Counter0 + 6
    Incr Licznik                                                'zwiększaj stan licznika
    If Licznik = 100 Then
       Flaga1 = 1                                
    End If
    If Licznik = 600 Then
       Flaga23 = 1                                
    End If
    
    If Licznik = 1200 Then
       Flaga12 = 1                                
    End If
    
    

    nie wiem, czy to dobrze zrozumiałem, bo czy w takim przypadku nie będzie problemu z liczeniem od jakiegoś stanu ? i co wtedy z resetem licznika ?
  • #10
    gray77
    Level 12  
    Na temat timerów nie powiem ci za wiele, bo się nie znam. Ja tylko odmierzam około 1sek odcinki w swoim timerze i to mi wystarcza. Nie zagłębiałem się jeszcze bo nie miałem potrzeby takiej.