ATtiny2313 minutnik z enkoderem - problem z menu


Witam, wszystkich. Na wstępie zaznaczę że jestem początkującym i proszę o wyrozumiałość. Jest to mój pierwszy program. Robię go dla własnej satysfakcji. Jako że lubię wyświetlacze LED, enkodery i odliczanie czasu postanowiłem zbudować minutnik charakteryzujący się:

- 4 pozycyjny wyświetlacz Led - max 99min i 59 sekund
- buzzer jako sygnał po zakończeniu odliczania wyznaczonego czasu
- enkoder do ustawiania czasu odliczania

W normalnej pracy enkoder będzie wyłączony. Reakcja będzie tylko na jego naciśnięcie. każde naciśnięcie zmienia stan minutnika pomiędzy start/stop. Przytrzymując klawisz enkodera dłużej przechodzimy do jego ustawienia. najpierw ustawiamy minuty, później naciskamy krótko znów enkoder i ustawiamy sekundy po kolejnym naciśnięciu wychodzimy z trybu programowania.

Na chwilę obecną program piszę dla 3 klawiszy - "+", "-", "start/stop (programowanie)". Zamiast + i - jak już minutnik będzie działać dorobię obsługę enkodera. Testowałem kod do enkodera podany przez mirka i nada się lecz troszkę wolno reaguje na obrót. Powyżej 3 impulsów na sekundę praktycznie już nie reaguje. Może ma ktoś jakiś lepszy kod? Dodam że gotowiec w bascomie w postaci "encoder..." w ogóle mi nie ruszył.

W poniższym kodzie działa już mi prawie wszystko poza jedną rzeczą - gdy wchodzę do programowania to automatycznie przechodzi mi od razu na ustawianie sekund (przeskakuje ustawianie minut). Domyślam się że chodzi o szybkość programu, lub drgania styków - zanim porządnie zwolnię klawisz to program zarejestruje już kolejne jego naciśnięcie i przechodzi od razu na minuty.

Gdzie mam wstawić opóźnienie, lub jakieś zliczanie bym spokojnie przejść przez programowanie minutnika?

Nie mam na chwilę obecną żadnego schematu gdyż całość testuję na odpowiednio połączonej płycie testowej zaprojektowanej przez Mirka z kolegą i module pod atiny2313.

Oto kod jaki udało mi się wyskrobać:

'*******************************************************************************
                               'Konfiguracja
'*******************************************************************************
 
$regfile = "attiny2313.dat"
$crystal = 8000000
 
Config Portd = Output : Portd = &B11111111                  ' port d jako wyjscie segmentów wyswietlacza LED
Config Portb = &B00011111 : Portb = &B11111111              ' 3 starsze bity portu B jako wejście, reszta jako wyjścia
 
 
Config Timer0 = Timer , Prescale = 256
Enable Timer0
 
On Timer0 Przerwanie0
Enable Interrupts
 
 
 
 
'*******************************************************************************
                                 'Zmienne
'*******************************************************************************
 
 
Dim Mux As Byte                                             ' zmienna używana do multiplexowania wyświetlacza LED
Dim F4ms As Bit                                             ' flaga oznaczająca że timer z dzielnikiem odliczył 4ms
Dim F1s As Bit                                              'flaga oznaczająca że timer z dzielnikiem odliczył 1s
Dim Dziel(1) As Byte                                        ' dzielnik timera do odliczania sekundy
Dim Dziel2 As Byte                                          ' dzielnik timera używany do migania ustawianą wartością
Dim Fsta As Bit                                             ' bit oznaczający start timera, 0 oznacza zatrzymany, 1 oznacza uruchomione odliczanie
Dim Stan_sw As Byte , Sw As Byte , Licznik_sw As Byte       ' zmienne używane do obsługi klawiatury
Dim S As Byte , M As Byte , W As Byte                       ' M minuty, S sekundy, W wyswietlana wartosc
Dim Dlugie As Integer                                       ' zmnienna byte zliczająca ile razy przeleciała pętla gdy jest naciśnięty klawisz programowania/start/stop
Dim Programowanie As Bit                                    ' gdy bit jest 1 oznaczauruchomiony tryb programowanie (ustawiania timera) gdy jest 0 - normalna praca
Dim Ms As Bit                                               ' zmienna używana w trybie programowania timera - 0 oznacza ustawianie sekund, 1 ustawianie minut
Dim Miganie As Bit                                          ' flaga bitowa z timera służąca do migania wyświetlaczem
Ala Alias Portb.4                                           'bit 4 portu B  nazwany ALA jako skrót od alarmu, gdzie został podłączony buzzer
 
 
 
 
 
 
'*******************************************************************************
                               'Wartosci Poczatkowe
'*******************************************************************************
 
Fsta = 0
S = 30
M = 12
Dlugie = 0
Ms = 1
Programowanie = 0
Miganie = 0
 
 
'*******************************************************************************
                                  'Petla glowna
'*******************************************************************************
 
Do
 
If F4ms = 1 Then                                            ' gdy timer odliczy 4ms i ustawi flagę F4ms
  Reset F4ms                                                ' zerujemy tę flagę
  Gosub Wyswietlanie                                        'skaczemy do obsługi wyświetlaczy
  Gosub Przyciski                                           'skaczemy do obsługi klawiatury
End If
 
 
 
 
If Fsta = 1 Then                                            ' sprawdza wartość bitu Fstai gdy jest 0 nie robi nic wiecej (timer zatrzymany) a gdy 1 idzie dalej (odliczanie aktywne)
   If M > 0 Or S >= 1 Then                                  ' gdy wartość minut jest większa od 0 lub gdy wartość sekund większa lub równa 1
      If F1s = 1 Then                                       ' to gdy timer z dzielnikiem odliczy 1 sekundę i ustawi flagę F1s
         Reset F1s                                          ' zeruje tę flagę
 
         Decr S                                             ' dekrementuje wartość sekund
            If S = 255 Then                                 ' gdy sekundy spadną poniżej zera i ich wartość osiągnie 255 (max liczba w bajcie)
               S = 59                                       ' to ustawia je jako 59
               Decr M                                       ' i dekerementuje minuty
            End If
 
 
 
         If M = 0 And S = 0 Then                            ' jesli czas minie, a więc jeśli wartość minut i sekund będzie 0
 
 
         Reset Ala                                          ' uruchom buzzer
         Reset Fsta                                         ' zatrzymaj odliczanie
 
         End If
 
      End If
 
  End If
 
 
End If
 
 
 
Loop                                                        ' i powrót do początku pętli
End
 
 
 
 
 
 
 
'*******************************************************************************
                                'wyswietlanie
'*******************************************************************************
 
Wyswietlanie:
 
Incr Mux
  If Mux = 5 Then Mux = 0
 
  Select Case Mux
 
    Case 0:
      If Programowanie = 0 Then Reset Portb.0               ' wyswietlenie normalne gdy nie programujemy
 
      If Programowanie = 1 And Ms = 0 Then Reset Portb.0    ' wyswietlenie normalne gdy programujemy
 
      If Programowanie = 1 And Ms = 1 And Miganie = 1 Then Reset Portb.0       ' wyswietlenie migająco ustawioną wartością gdyt programujemy
 
 
    W = M / 10
    W = Lookup(w , Tabela)
    Portd = W
    Set Portb.3
 
 
 
    Case 1:
     If Programowanie = 0 Then Reset Portb.1
 
      If Programowanie = 1 And Ms = 0 Then Reset Portb.1
 
      If Programowanie = 1 And Ms = 1 And Miganie = 1 Then Reset Portb.1
 
      W = M Mod 10
      W = Lookup(w , Tabela)
      Portd = W
     Set Portb.0
 
 
 
    Case 2:
     If Programowanie = 0 Then Reset Portb.2
 
      If Programowanie = 1 And Ms = 1 Then Reset Portb.2
 
      If Programowanie = 1 And Ms = 0 And Miganie = 1 Then Reset Portb.2
 
      W = S / 10
      W = Lookup(w , Tabela)
      Portd = W
     Set Portb.1
 
 
 
    Case 3:
    If Programowanie = 0 Then Reset Portb.3
 
      If Programowanie = 1 And Ms = 1 Then Reset Portb.3
 
      If Programowanie = 1 And Ms = 0 And Miganie = 1 Then Reset Portb.3
 
     W = S Mod 10
     W = Lookup(w , Tabela)
     Portd = W
    Set Portb.2
 
    Case 5:
      Do
      Loop
 
  End Select
 
 
 
Return
 
 
 
 
'*******************************************************************************
                                  'Przyciski
'*******************************************************************************
 
 
Przyciski:
Sw = Pinb And &B11100000                                    'maskowanie nieużywanych pinów
 
 
 
If Sw <> &B11100000 And Stan_sw = Sw Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
      Select Case Stan_sw
 
 
        Case &B01100000:                                    ' zwiekszamy wartosc dlugie i w instrukcjach powyzej sprawdzamy jak dlugo przycisk jest nacisniejty
            Incr Dlugie
 
 
        Case &B10100000:                                    'zwiekszanie minut badz sekund
            If Programowanie = 1 Then                       ' jesli włączony tryb programowania
              If Ms = 1 Then                                ' i jesli ustawiamy minuty
 
               Incr M                                       ' inkrementujemy minuty
               If M = 100 Then M = 99                       'jesli minuty osiagnęły maksimum to juz nie zwiekszamy ich wartości
 
              Else                                          ' jesli ustawiamy sekundy
               Incr S                                       ' to inkrementujemy sekundy
                  If S = 60 Then                            ' gdy sekundy osiagna wartosc 60
                  S = 0                                     ' to zerujemy je
                  Incr M                                    ' i inkrementujemy minuty
               End If
              End If
             End If
        Case &B11000000:
                                                    'zmniejszanie minut badz sekund
             If Programowanie = 1 Then
              If Ms = 1 Then                                ' analogicznie jak przy zwiekszaniu
 
               Decr M
               If M = -1 Then M = 0
 
              Else
               Decr S
                  If S = -1 Then
                  S = 59
                  Decr M
               End If
              End If
             End If
 
 
      End Select
    End If
  Else
    Stan_sw = Sw
    Licznik_sw = 80
  End If
 
 
If Pinb.7 = 1 And Dlugie > 0 Then                           ' jesli przycisk został puszczony a wartosc dlugie wieksza od 0
 
 
   If Dlugie < 3 Then                                       ' i mniejsza od 3
 
 
 
      If Programowanie = 1 Then                             ' a programowanie wlaczone
        'If Dlugie > 1 Then
         If Ms = 0 Then                                     ' a ustawialismy minuty
               Reset Programowanie                          ' to wychodzimy z programowania
         Else
                                                             ' jesli ustawialismy sekundy
            Ms = 0                                          ' to teraz ustawiamy minuty
         End If
       'End If
      Else                                                  ' jesli programowanie wylaczone
         Toggle Fsta                                        ' start/ stop timer'a
         Set Ala                                            ' wylaczenie alarmu gdy jest włączony
      End If
      Dlugie = 0                                            ' zerujemy wartosc zmiennej dlugie w celu kolejnego zliczania jak dlugo jest nacisniety
   End If
 
 
 
   If Dlugie >= 3 Then                                      ' jesli dlugie  jest wieksze lub równe 3
      'Reset Ala
      Set Programowanie                                     ' wejdz do trybu programowania timera
      Reset Fsta                                            ' zatrzym timer gdyby byl w trakcie odliczania
      Dlugie = 0                                            ' zeruj wartosc dlugie ktora sprawdzala nacisniecie przycisku
   End If
 
 
End If
 
 
 
Return
 
 
 
 
'*******************************************************************************
                                'Przerwanie timer0
'*******************************************************************************
 
Przerwanie0:
 
Timer0 = 131
   Set F4ms
   Incr Dziel(1)
   Incr Dziel2
 
  If Dziel(1) = 250 Then                                    'liczy 25 przerwań czyli 100ms i ustawia flage
    Dziel(1) = 0
    Set F1s
  End If
 
  If Dziel2 = 50 Then                                       ' sluzy do migania ustawianej wartosci w trybie programowania
    Dziel2 = 0
    Toggle Miganie
  End If
Return
 
 
'*******************************************************************************
                   'Tabela do wyswietlania na wyswietlaczu
'*******************************************************************************
 
Tabela:
   Data 64 , 121 , 36 , 48 , 25 , 18 , 2 , 120 , 0 , 16




Portret użytkownika mareks6

umiałby ktoś zerknąć na

umiałby ktoś zerknąć na powyższy kod? Nadal nie umiem uporać się z problemem... Dodałem komentarze w kodzie by każdy mógł zrozumieć jak on działa ale jak będzie trzeba to dodam dokładniejsze...

Portret użytkownika gosc

dodaj dokładniejsze komentarze

To oczywiście tylko moja prośba , chciałbym ogarnąć właśnie taki sposób tworzenia menu z badaniem stanu wyłączników za pomocą funktora and.

Portret użytkownika gosc

Jeżeli możesz to dodaj dodatkowe opisy

Właśnie jak w temacie. Chciałbym ogarnąć taki właśnie sposób tworzenia menu poprzez badanie stanu portu za pomocą funktora and

Portret użytkownika mareks6

postaram się dodać więcej

postaram się dodać więcej komentarzy jutro, jednak sama obsługi klawiatury jest zaczerpnięta z kodów źródłowych mirley'a a ja ją tylko rozszerzyłem o długie i krótkie naciśnięcie jednego z klawiszy, jednak mam problem jaki opisałem wyżej...

Portret użytkownika gosc

ktoś ma pomysły? przerobiłem

ktoś ma pomysły?
przerobiłem dzisiaj część kodu odpowiedzialną za długie i krótkie naciśnięcie odrobinę inaczej ale sam już nie wiem... Problem polega na tym że jak już wejdę do trybu programowania to zanim się puści klawisz to mikroprocesor zdąży jeszcze przynajmniej raz nabić licznik wartości długie i z tego powodu przechodzi od razu dalej... Niestety nie mogę tam wprowadzić żadnych komend typu bitwait by czekać na puszczenie klawisza gdyż wtedy multipleksowanie padnie z powodu zatrzymania programu... Opóźnienia też chyba nie wchodzą w grę z tego samego powodu. Może jakaś kolejna dodatkowa zmienna??? Ma ktoś pomysły???

Przerobiona dzisiaj część kodu:

If Pinb.7 = 1 And Dlugie >= 3 Then
  If Programowanie = 1 Then
   Dlugie = 0
  End If
End If
 
 
 
 
 
If Pinb.7 = 1 And Dlugie > 0 Then                           ' jesli przycisk został puszczony a wartosc dlugie wieksza od 0
 
 
   If Dlugie < 3 Then                                       ' i mniejsza od 3
 
 
 
      If Programowanie = 1 Then                             ' a programowanie wlaczone
        'If Dlugie > 1 Then
 
        Dlugie = 0
 
         If Ms = 0 Then                                     ' a ustawialismy minuty
               Reset Programowanie                          ' to wychodzimy z programowania
         Else
                                                             ' jesli ustawialismy sekundy
            Ms = 0                                          ' to teraz ustawiamy minuty
         End If
       'End If
      Else                                                  ' jesli programowanie wylaczone
         Toggle Fsta                                        ' start/ stop timer'a
         Set Ala                                            ' wylaczenie alarmu gdy jest włączony
      End If
      Dlugie = 0                                            ' zerujemy wartosc zmiennej dlugie w celu kolejnego zliczania jak dlugo jest nacisniety
   End If
 
End If
 
 
   If Dlugie >= 3 Then                                      ' jesli dlugie  jest wieksze lub równe 3
      'Reset Ala
      Set Programowanie                                     ' wejdz do trybu programowania timera
 
 
      Reset Fsta                                            ' zatrzym timer gdyby byl w trakcie odliczania
      'Dlugie = 0
      'Waitms 10                                             ' zeruj wartosc dlugie ktora sprawdzala nacisniecie przycisku
   End If

Portret użytkownika matrix

Re: ktoś ma pomysły?

Robisz tak:
- wprowadzasz zmienną
- sprawdzasz czy masz wciśnięty przycisk
- jeśli wciśnięty to zwiększasz wartość tej zmiennej
- sprawdzasz czy przycisk został puszczony
- jeśli został puszczony to:
- jeśli wartość zmiennej jest mniejsza niż interesujący Cię czas to przechodzisz do jednego podmenu
- jeśli jest większa to przechodzisz do innego podmenu
- na koniec zerujesz wartość danej zmiennej

Portret użytkownika EDC

Przycisk: If Ip = 0 Then

Przycisk:
 If Ip = 0 Then
   Incr Licznik_sw
   If Licznik_sw = 68 Then
   Licznik_sw = 0
'tu istrukcje do wykonania po krótkim nacisnieciu
 
 Else
 Licznik_sw = 60
 End If
Return

To przerobione na potrzeby obsługi przycisku enkodera u mnie z projektu "strownik CO". Skutecznie eliminuje drgania styków. Przerobisz i masz. Ip to przycisk enkodera, Licznik sw to zmienna. Podpatrz obsługe przycisków w projekcie sterownika CO.

-

BARTek
Moja strona

Portret użytkownika mareks6

Odpowiedzi

Do MATRIX:

Może program jest mało przejrzysty ale właśnie tak go napisałem...

DO EDC:

Czy mógłbyś zerknąć na mój program z góry i pomyśleć jak to tam wstawić? Bo próbowałem na różne sposoby ale robi mi się z tego co raz dłuższy program a efektu nie ma... Nawet nie wklejam tego co napisałem bo szkoda zawracać głowy...

Wklejam natomiast poniżej to na jakim etapie jestem, czyli na początku... Tu gdzieś coś bym musiał przerobić lub dorobić bo mam błędy jak opisane w pierwszym poście. Poniżej fragment kodu do odczytu i interpretacji klawiatury, który jest wywoływany co 4ms

'*******************************************************************************
                                  'Przyciski
'*******************************************************************************
 
 
Przyciski:
Sw = Pinb And &B11100000                                    'maskowanie nieużywanych pinów
 
 
 
If Sw <> &B11100000 And Stan_sw = Sw Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
      Select Case Stan_sw
 
 
        Case &B01100000:                                    ' zwiekszamy wartosc dlugie i w instrukcjach poniżej sprawdzamy jak dlugo przycisk jest nacisniejty
            Incr Dlugie
 
 
        Case &B10100000:                                    'zwiekszanie minut badz sekund
            If Programowanie = 1 Then                       ' jesli włączony tryb programowania
              If Ms = 1 Then                                ' i jesli ustawiamy minuty
 
               Incr M                                       ' inkrementujemy minuty
               If M = 100 Then M = 99                       'jesli minuty osiagnęły maksimum to juz nie zwiekszamy ich wartości
 
              Else                                          ' jesli ustawiamy sekundy
               Incr S                                       ' to inkrementujemy sekundy
                  If S = 60 Then                            ' gdy sekundy osiagna wartosc 60
                  S = 0                                     ' to zerujemy je
                  Incr M                                    ' i inkrementujemy minuty
               End If
              End If
             End If
        Case &B11000000:
                                                    'zmniejszanie minut badz sekund
             If Programowanie = 1 Then
              If Ms = 1 Then                                ' analogicznie jak przy zwiekszaniu
 
               Decr M
               If M = -1 Then M = 0
 
              Else
               Decr S
                  If S = -1 Then
                  S = 59
                  Decr M
               End If
              End If
             End If
 
 
      End Select
    End If
  Else
    Stan_sw = Sw
    Licznik_sw = 80
  End If
 
 
 
If Pinb.7 = 1 And Dlugie > 0 Then                           ' jesli przycisk został puszczony a wartosc dlugie wieksza od 0
 
 
 
   If Dlugie < 3 Then                                       ' i mniejsza od 3
 
 
 
      If Programowanie = 1 Then                             ' a programowanie wlaczone
 
 
 
         If Ms = 0 Then                                     ' a ustawialismy minuty
               Reset Programowanie                          ' to wychodzimy z programowania
         Else
                                                             ' jesli ustawialismy sekundy
            Ms = 0                                          ' to teraz ustawiamy minuty
         End If
 
 
 
 
      Else                                                  ' jesli programowanie wylaczone
         Toggle Fsta                                        ' start/ stop timer'a
         Set Ala                                            ' wylaczenie alarmu gdy jest włączony
      End If
      Dlugie = 0                                            ' zerujemy wartosc zmiennej dlugie w celu kolejnego zliczania jak dlugo jest nacisniety
   End If
End If
 
 
   If Dlugie >= 3 Then                                      ' jesli dlugie  jest wieksze lub równe 3
 
      Set Programowanie                                     ' wejdz do trybu programowania timera
      Reset Fsta                                            ' zatrzymaj timer gdyby byl w trakcie odliczania
      Dlugie = 0                                            ' zeruj wartosc dlugie ktora sprawdzala nacisniecie przycisku
   End If
 
 
 
 
 
 
Return

Portret użytkownika mareks6

UDAŁO SIĘ :-)))

kurcze, przeoczyłem najważniejszą rzecz - ustawianie "1" w zmiennej MS. Wszystko już działa jak należy. Teraz muszę dodać obsługę enkodera.

Bartek, gdzie znajdę ten sterownik CO z enkoderem o którym piszesz? Jest gdzieś tu na forum czy na elektrodzie itp?

Portret użytkownika EDC

Przejrzyj projekty ;)

Tutaj, w projektach, w artykułach i na forum dzisiaj..wystarczy poczytać.

-

BARTek
Moja strona

Portret użytkownika gosc

aaaa, myślałem że masz jakiś

aaaa, myślałem że masz jakiś konkretny projekt na myśli. ten tutaj ma klawiaturę bez enkodera. sam kod enkodera od kuby już opanowałem jednak jest troszkę wolny. Przy troszkę szybszym kręceniu juz gubi impulsy dlatego szukam jakiejś szybszej procedury...

Portret użytkownika gosc

aaaa, myślałem że masz jakiś

aaaa, myślałem że masz jakiś konkretny projekt na myśli. ten tutaj ma klawiaturę bez enkodera. sam kod enkodera od kuby już opanowałem jednak jest troszkę wolny. Przy troszkę szybszym kręceniu juz gubi impulsy dlatego szukam jakiejś szybszej procedury...

Portret użytkownika gosc

aaaa, myślałem że masz jakiś

aaaa, myślałem że masz jakiś konkretny projekt na myśli. ten tutaj ma klawiaturę bez enkodera. sam kod enkodera od kuby już opanowałem jednak jest troszkę wolny. Przy troszkę szybszym kręceniu juz gubi impulsy dlatego szukam jakiejś szybszej procedury...

Portret użytkownika mareks6

aaaa, myślałem że masz jakiś

aaaa, myślałem że masz jakiś konkretny projekt na myśli. ten tutaj ma klawiaturę bez enkodera. sam kod enkodera od kuby już opanowałem jednak jest troszkę wolny. Przy troszkę szybszym kręceniu juz gubi impulsy dlatego szukam jakiejś szybszej procedury...

Portret użytkownika EDC

Chyba brak Ci cierpliwości

Chyba brak Ci cierpliwości kolego ;) ..Tyle postów..że oberwie Ci się od moderatora. Poczekaj zawsze chwilę , potem stronę odśwież, a dopisując coś użyj opcji "edytuj".
Co do enkodera to chyba ten drugi, zrobiony na przerwaniu, jesli zmianę wartości też w obsłudze przerwania zrobisz raczej żadnego eventu nie zgubi..zanim coś napiszesz rozejrzyj się. Dla zabawy chyba zrobie sobie sejf z enkoderem :D taki "retro" z głośniczkiem "cykania" W nowych samochodach już nie ma przerywacza na przekaźniku i za klikanie też odpowiedzialny jest głośnik.

-

BARTek
Moja strona

Portret użytkownika mareks6

z tymi postami to długa

z tymi postami to długa historia. .. nie wiem kiedy mnie wylogowało i w skrócie jak klikałem zachowaj to nawet po odświeżeniu nie pokazywało posta wiec go wklejałem i próbowałem ponownie aż w końcu zauważyłem ze jestem wylogowany i po zalogowaniu udało się zatwierdzić ten post i prócz tego pokazało jeszcze 3 jako gość... sam bym je usunął ale nie umiem.

wracając do tematu, przeglądałem dział projekty oraz forum w poszukiwaniu sterownika co z enkoderem o którym opisałeś i nie znalazłem ale poszukam raz jeszcze

--------------------------------------------------------------------------------------------------------------------------------
Edytuję by nie dodawać postu pod postem

Otóż jak wspominałem z procedurką z działu Kody Źródłowe mikrokontroler liczy tylko wolne obracanie enkodera bo jak za szybko kręcimy to zliczy tylko kilka razy ale ogólnie to całość już mi działa. Dodałem ograniczenie tak by po zjechaniu z minutami i sekundami w trybie programowania do zera nic się nie działo już kręcąc dalej w dół. Niestety ze względu na ograniczoną pamięć mikrokontrolera nie udało mi się tego zrealizować z góry zakresu, przez co osiągając 99 minut i kręcąc w górę ustawianie nie zatrzymuje się na 99min i 59s, lecz sekundy się zerują po przeleceniu przez 59 i znów od zera je możemy kręcić, przy czym minuty zostają 99.

Poniżej kod gdyby ktoś chciał zobaczyć jak to działa na uniwersalnej płycie do programowania od kuby. Dodam że podłączenia na płycie są następujące:
* PORT D - segmenty wyświetlaczy LED
* PORT B bity:
- 0 do 3 wspólne anody wyświetlaczy
- 4 - buzzer lub dioda sygnalizująca uruchomienie alarmu
- 5 i 6 - podłączenie enkodera
- 7 - przycisk enkodera
Dwukropek rozdzielający minuty i sekundy na wyświetlaczu podłączyłem na stałe przez co świeci ale to nic :-)

'*******************************************************************************
                               'Konfiguracja
'*******************************************************************************
 
$regfile = "attiny2313.dat"
$crystal = 8000000
 
Config Portd = Output : Portd = &B11111111                  ' port d jako wyjscie segmentów wyswietlacza LED
Config Portb = &B00011111 : Portb = &B11111111              ' 3 starsze bity portu B jako wejście, reszta jako wyjścia
 
 
Config Timer0 = Timer , Prescale = 256
Enable Timer0
 
On Timer0 Przerwanie0
Enable Interrupts
 
 
 
 
'*******************************************************************************
                                 'Zmienne
'*******************************************************************************
 
 
Dim Mux As Byte                                             ' zmienna używana do multiplexowania wyświetlacza LED
Dim F4ms As Bit                                             ' flaga oznaczająca że timer z dzielnikiem odliczył 4ms
Dim F1s As Bit                                              'flaga oznaczająca że timer z dzielnikiem odliczył 1s
Dim Dziel As Byte                                           ' dzielnik timera do odliczania sekundy
Dim Dziel2 As Byte                                          ' dzielnik timera używany do migania ustawianą wartością
Dim Fsta As Bit                                             ' bit oznaczający start timera, 0 oznacza zatrzymany, 1 oznacza uruchomione odliczanie
Dim Licznik_sw As Byte                                      ' zmienna używana do obsługi klawiatury
Dim S As Byte , M As Byte , W As Byte                       ' M minuty, S sekundy, W wyswietlana wartosc
Dim Dlugie As Integer                                       ' zmnienna byte zliczająca ile razy przeleciała pętla gdy jest naciśnięty klawisz programowania/start/stop
Dim Programowanie As Bit                                    ' gdy bit jest 1 oznaczauruchomiony tryb programowanie (ustawiania timera) gdy jest 0 - normalna praca
Dim Ms As Bit                                               ' zmienna używana w trybie programowania timera - 0 oznacza ustawianie sekund, 1 ustawianie minut
Dim Miganie As Bit                                          ' flaga bitowa z timera służąca do migania wyświetlaczem
Ala Alias Portb.4                                           'bit 4 portu B  nazwany ALA jako skrót od alarmu, gdzie został podłączony buzzer
I1 Alias Pinb.6
I2 Alias Pinb.5
 
Dim Wartosc_ustawiana As Integer
Dim In1 As Bit , In2 As Bit
Dim Tryb As Byte , Rezultat As Integer
 
 
 
 
'*******************************************************************************
                               'Wartosci Poczatkowe
'*******************************************************************************
 
 
S = 30
M = 12
Ms = 1
 
 
 
'*******************************************************************************
                                  'Petla glowna
'*******************************************************************************
 
Do
 
If F4ms = 1 Then                                            ' gdy timer odliczy 4ms i ustawi flagę F4ms
  Reset F4ms                                                ' zerujemy tę flagę
  Gosub Wyswietlanie                                        'skaczemy do obsługi wyświetlaczy
  Gosub Przyciski                                            'skaczemy do obsługi klawiatury
  Gosub Impulsator                                          'skaczemy do obsługi impulstora
End If
 
 
If Fsta = 1 Then                                            ' sprawdza wartość bitu Fstai gdy jest 0 nie robi nic wiecej (timer zatrzymany) a gdy 1 idzie dalej (odliczanie aktywne)
   If M > 0 Or S >= 1 Then                                  ' gdy wartość minut jest większa od 0 lub gdy wartość sekund większa lub równa 1
      If F1s = 1 Then                                       ' to gdy timer z dzielnikiem odliczy 1 sekundę i ustawi flagę F1s
         Reset F1s                                          ' zeruje tę flagę
 
         Decr S                                             ' dekrementuje wartość sekund
            If S = 255 Then                                 ' gdy sekundy spadną poniżej zera i ich wartość osiągnie 255 (max liczba w bajcie)
               S = 59                                       ' to ustawia je jako 59
               Decr M                                       ' i dekerementuje minuty
            End If
 
 
 
         If M = 0 And S = 0 Then                            ' jesli czas minie, a więc jeśli wartość minut i sekund będzie 0
 
 
         Reset Ala                                          ' uruchom buzzer
         Reset Fsta                                         ' zatrzymaj odliczanie
 
         End If
 
      End If
 
  End If
 
 
End If
 
 
 
Loop                                                        ' i powrót do początku pętli
End
 
 
 
 
 
 
 
'*******************************************************************************
                                'wyswietlanie
'*******************************************************************************
 
Wyswietlanie:
 
Incr Mux
  If Mux = 5 Then Mux = 0
 
  Select Case Mux
 
    Case 0:
      If Programowanie = 0 Then Reset Portb.0               ' wyswietlenie normalne gdy nie programujemy
 
      If Programowanie = 1 And Ms = 0 Then Reset Portb.0    ' wyswietlenie normalne gdy programujemy
 
      If Programowanie = 1 And Ms = 1 And Miganie = 1 Then Reset Portb.0       ' wyswietlenie migająco ustawioną wartością gdyt programujemy
 
 
    W = M / 10
    W = Lookup(w , Tabela)
    Portd = W
    Set Portb.3
 
 
 
    Case 1:
     If Programowanie = 0 Then Reset Portb.1
 
      If Programowanie = 1 And Ms = 0 Then Reset Portb.1
 
      If Programowanie = 1 And Ms = 1 And Miganie = 1 Then Reset Portb.1
 
      W = M Mod 10
      W = Lookup(w , Tabela)
      Portd = W
     Set Portb.0
 
 
 
    Case 2:
     If Programowanie = 0 Then Reset Portb.2
 
      If Programowanie = 1 And Ms = 1 Then Reset Portb.2
 
      If Programowanie = 1 And Ms = 0 And Miganie = 1 Then Reset Portb.2
 
      W = S / 10
      W = Lookup(w , Tabela)
      Portd = W
     Set Portb.1
 
 
 
    Case 3:
    If Programowanie = 0 Then Reset Portb.3
 
      If Programowanie = 1 And Ms = 1 Then Reset Portb.3
 
      If Programowanie = 1 And Ms = 0 And Miganie = 1 Then Reset Portb.3
 
     W = S Mod 10
     W = Lookup(w , Tabela)
     Portd = W
    Set Portb.2
 
 
  End Select
 
 
 
Return
 
 
 
 
'*******************************************************************************
                                  'Przyciski
'*******************************************************************************
 
 
Przyciski:
 
 
If Pinb.7 = 0 Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
                                        '
      Incr Dlugie                                           'zwiekszamy wartosc dlugie i w instrukcjach powyzej sprawdzamy jak dlugo przycisk jest nacisniejty
 
 
    End If
Else
  Licznik_sw = 80
End If
 
 
 
If Pinb.7 = 1 And Dlugie > 0 Then                           ' jesli przycisk został puszczony a wartosc dlugie wieksza od 0
 
 
 
   If Dlugie < 3 Then                                       ' i mniejsza od 3
 
 
 
      If Programowanie = 1 Then                             ' a programowanie wlaczone
 
 
 
         If Ms = 0 Then                                     ' a ustawialismy sekundy
               Reset Programowanie                          ' to wychodzimy z programowania
         Else
                                                             ' jesli ustawialismy minuty
            Ms = 0                                          ' to teraz ustawiamy sekundy
         End If
 
 
 
      Else                                                  ' jesli programowanie wylaczone
         Toggle Fsta                                        ' start/ stop timer'a
         Set Ala                                            ' wylaczenie alarmu gdy jest włączony
      End If
      Dlugie = 0                                            ' zerujemy wartosc zmiennej dlugie w celu kolejnego zliczania jak dlugo jest nacisniety
   End If
End If
 
 
If Dlugie >= 3 Then                                         ' jesli dlugie  jest wieksze lub równe 3
 
   Set Programowanie                                        ' wejdz do trybu programowania timera
   Reset Fsta                                               ' zatrzymaj timer gdyby byl w trakcie odliczania
   Dlugie = 0                                               ' zeruj wartosc dlugie ktora sprawdzala nacisniecie przycisku
   Ms = 1                                                   ' najpierw ustawiamy minuty
End If
 
 
Return
 
 
 
 
'*******************************************************************************
                                'Przerwanie timer0
'*******************************************************************************
 
Przerwanie0:
 
Timer0 = 131
   Set F4ms
   Incr Dziel
   Incr Dziel2
 
  If Dziel = 250 Then                                       'liczy 25 przerwań czyli 100ms i ustawia flage
    Dziel = 0
    Set F1s
  End If
 
  If Dziel2 = 50 Then                                       ' sluzy do migania ustawianej wartosci w trybie programowania
    Dziel2 = 0
    Toggle Miganie
  End If
Return
 
 
'*******************************************************************************
                                 'Impulsator
'*******************************************************************************
 
Impulsator:
 In1 = I1
 In2 = I2
 Rezultat = 0
 Select Case Tryb
  Case 0:
   If In1 = 1 And In2 = 1 Then Incr Tryb                    'jezeli dwa rozwarte
  Case 1:
   If In1 = 1 And In2 = 0 Then Tryb = 2
   If In1 = 0 And In2 = 1 Then Tryb = 3
  Case 2:
   If In1 = 0 And In2 = 1 Then
     Rezultat = 1
     Tryb = 0
   End If
  Case 3:
   If In1 = 1 And In2 = 0 Then
     Rezultat = -1
     Tryb = 0
   End If
 End Select
 Waitus 100
 
 If Rezultat <> 0 Then
 
   If Programowanie = 1 Then
      If Ms = 1 Then
 
         M = M + Rezultat
         If M = -1 Then M = 0
         If M = 100 Then M = 99
 
      Else
         S = S + Rezultat
 
             If S = -1 Then
 
                   If M > 0 Then
                     S = 59
                     Decr M
                   Else
                     S = 0
                   End If
                If M = -1 Then M = 0
             End If
 
 
             If S = 60 Then                                 ' gdy sekundy osiagna wartosc 60
                  S = 0                                     ' to zerujemy je
                  Incr M
                  If M = 100 Then M = 99
             End If
 
 
      End If
   End If
 
 End If
 
Return
 
'*******************************************************************************
                   'Tabela do wyswietlania na wyswietlaczu
'*******************************************************************************
 
Tabela:
   Data 64 , 121 , 36 , 48 , 25 , 18 , 2 , 120 , 0 , 16