Strona 1 z 3

Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 14:16
autor: maxd89pl
Witam, Panowie pierw się przywitam, gdyż to mój pierwszy post. W poszukiwaniu informacji/pomocy w internecie trafiłem na 3 magików w dziedzinie bascoma tj. p.Bartek, p.Kaktus i p.Mirley, dlatego postanowiłem tu napisać, mianowicie mam problem w oprogramowaniu menu użytkownika bazującego na wyświetlaczach 7 segmentowych.

Chciałbym by program wyglądał tak:
-Program startuje z 0000 na wyś. Led gdzie pierwsze 2 zera to minuty a następne dwa to sek.
-Program odczytuje stan 3 przycisków : plus, minus, Enter(start odliczania)

i w tym miejscu mam problem gdyż:
oprogramowanie tych zmiennych wyświetlanych na led się wszystko krzaczy, przy dodawaniu jest jeszcze ok ale przy odejmowaniu zwalnia jakby procek był zajęty czymś innym a jak dojdzie do zera to się nie zatrzymuje tylko wkakują jakieś inne nie ustalone liczby, program ten ma obsługiwać naświetlarkę uv

Prosił bym bardzo o pomoc w kodzie by zakres był 30:00 i nie dało się więcej i żeby poniżej 00:00 także nie dało się zejść

a tu kod:
  1. regfile = "m8def.dat"
  2. $crystal = 8000000
  3. $hwstack = 64
  4. $swstack = 64
  5. $framesize = 128
  6.  
  7. Config Portd = Output
  8. Config Portb.0 = Output
  9. Config Portb.1 = Output
  10. Config Portb.2 = Output
  11. Config Portb.3 = Output
  12. Config Pinc.0 = Input
  13. Config Pinc.1 = Input
  14. Config Pinc.2 = Input
  15.  
  16. Portc.0 = 1
  17. Portc.1 = 1
  18. Portc.2 = 1
  19.  
  20.  
  21. Portb.0 = 0
  22. Portb.1 = 0
  23. Portb.2 = 0
  24. Portb.3 = 0
  25. Portd = 255
  26.  
  27. W1 Alias Portb.0
  28. W2 Alias Portb.1
  29. W3 Alias Portb.2
  30. W4 Alias Portb.3
  31. Prz1 Alias Pinc.0
  32. Prz2 Alias Pinc.1
  33. Enter Alias Pinc.2
  34.  
  35. Segmenty Alias Portd
  36.  
  37. Declare Sub Dec2bcd(byval Liczba As Byte , Byval Pozycja_wysw As Byte , Byref Tab() As Byte)
  38.  
  39. Dim Sekundy As Byte
  40.  
  41. Dim s1 as Byte
  42. Dim m1 as byte
  43.  
  44.  
  45. Dim Minuty as byte
  46. Dim Wyswietlacz As Byte
  47. Dim Tablica(4) As Byte
  48. Dim Kr1 as Bit
  49. Dim Kr2 as Bit
  50. Dim Kr3 as Bit
  51. Dim Kr4 as Bit
  52. Dim f_Odej as Bit
  53. Dim Startuj as bit
  54. dim 1_sek as Word
  55. Dim Menu as Byte
  56.  
  57.  
  58. Config Timer0 = Timer , Prescale = 256
  59. On Ovf0 Przerwanie
  60. Load Timer0 , 65
  61.  
  62. Enable Ovf0
  63. Enable Interrupts
  64.  
  65. s1 = 0
  66. m1 = 0
  67. Sekundy = 0
  68. Startuj = 0
  69. Menu = 1
  70.  
  71. 'Set Kr1
  72. 'Set Kr2
  73. 'Set Kr3
  74. 'Set Kr4
  75.  
  76. Do
  77.  
  78. Select Case Menu
  79.  
  80.    Case 1:
  81.  
  82.           if Prz1 = 0 then
  83.             waitms 15
  84.                If Prz1 = 0 Then
  85.  
  86.                   s1 = s1 + 1
  87.                   gosub Wyswietl
  88.                   waitms 30
  89.  
  90.                end if
  91.           End if
  92.  
  93.  
  94.           if f_Odej = 0 then
  95.             if Prz2 = 0 then
  96.                waitms 15
  97.                   If Prz2 = 0 Then
  98.  
  99.                      s1 = s1 - 1
  100.                      gosub Wyswietl
  101.                      waitms 30
  102.  
  103.  
  104.           If m1 > 0 Then
  105.  
  106.             If s1 < 1 Then
  107.  
  108.                m1 = m1 - 1
  109.  
  110.             end if
  111.           end if
  112.  
  113.  
  114.  
  115.  
  116.                   end if
  117.             End if
  118.           end if
  119.  
  120.           if s1 = 60 Then
  121.  
  122.              m1 = m1 + 1
  123.              s1 = 0
  124.              gosub Wyswietl
  125.  
  126.           end if
  127.  
  128.           If m1 > 0 Then                     'zapalanie kropki gdy min większe od 0
  129.  
  130.              Set Kr2
  131.  
  132.              else
  133.  
  134.              Reset Kr2
  135.  
  136.           End if
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.     Case 2:
  144.  
  145. End Select
  146.  
  147.  
  148.  
  149.  
  150. Loop
  151. End                                                         'end program
  152.  
  153.  
  154. '**************************************************************
  155.  
  156. Wyswietl:
  157.  
  158.  
  159.  
  160.       If Sekundy = 60 then
  161.  
  162.             Sekundy = 60
  163.  
  164.       End if
  165.  
  166.       If Minuty = 30 Then
  167.  
  168.             Minuty = 30
  169.             Sekundy = 0
  170.       End if
  171.  
  172.  
  173.       Sekundy = s1
  174.       Dec2bcd Sekundy , 3 , Tablica(1)
  175.  
  176.       Minuty = m1
  177.       Dec2bcd Minuty , 1 , Tablica(1)
  178.  
  179.  
  180.  
  181.  
  182. return
  183.  
  184.  
  185. Przerwanie:
  186.  
  187.       Load Timer0 , 65
  188.  
  189.       Incr Wyswietlacz
  190.       incr 1_sek
  191.  
  192.       If Wyswietlacz = 5 Then
  193.          Wyswietlacz = 1
  194.       End If
  195.  
  196.      ' if Startuj = 1 then
  197.  
  198.         ' 1_sek = 0
  199.  
  200.       '    if 1_sek = 481 then
  201.  
  202.        '        s1 = s1 - 1
  203.         '       toggle Kr3
  204.          '      1_sek = 0
  205.  
  206.  
  207.  
  208.           'end if
  209.       'end if
  210.  
  211.       Select Case Wyswietlacz
  212.             Case 1:
  213.                              W4 = 1
  214.                              Segmenty = Lookup(tablica(1) , Kody7seg)
  215.                              Portd.7 = Kr1
  216.                              W1 = 0
  217.             Case 2:
  218.                              W1 = 1
  219.                              Segmenty = Lookup(tablica(2) , Kody7seg)
  220.                              Portd.7 = Kr2
  221.                              W2 = 0
  222.             Case 3:
  223.                              W2 = 1
  224.                              Segmenty = Lookup(tablica(3) , Kody7seg)
  225.                              Portd.7 = Kr3
  226.                              W3 = 0
  227.             Case 4:
  228.                              W3 = 1
  229.                              Segmenty = Lookup(tablica(4) , Kody7seg)
  230.                              Portd.7 = Kr4
  231.                              W4 = 0
  232.  
  233.       End Select
  234.  
  235. Return
  236.  
  237. '************************************************************
  238.  
  239. Sub Dec2bcd(byval Liczba As Byte , Byval Pozycja_wysw As Byte , Byref Tab() As Byte)
  240.  
  241.     Local Pomocnicza1 As Byte
  242.     Local Pomocnicza2 As Byte
  243.  
  244.      Pomocnicza1 = Makebcd(liczba)
  245.      Pomocnicza2 = Pomocnicza1 And &B00001111
  246.      Tablica(pozycja_wysw + 1) = Pomocnicza2
  247.      Shift Pomocnicza1 , Right , 4
  248.      Pomocnicza2 = Pomocnicza1 And &B00001111
  249.      Tablica(pozycja_wysw) = Pomocnicza2
  250. End Sub
  251.  
  252.  
  253. Kody7seg:
  254.  
  255. Data &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110,
  256. Data &B01101101 , &B01111101 , &B00000111 , &]

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 17:30
autor: kaktus
Witam.

Najpierw postaraj się wywalić obsługę wyświetlacza z przerwania!

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 17:39
autor: kaktus
Potem przebuduj program by pozbyć się instrukcji wait...

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 17:41
autor: kaktus
I w trzecim etapie modyfikuj licznik minut i sekund tylko wtedy gdy mieści się w ustalonym zakresie.
Tzn zwiększaj gdy nie osiągną maksymalnego limitu i zmniejszaj tylko gdy nie osiągnął ustalonego minimum.

;)

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 18:19
autor: maxd89pl
Dziękuje za cenne wskazówki, na razie to wygląda tak coś tam popisze - nie uda frustracja i odchodzę od kompa na 30min. Następnie powracam na spokojnie z nowymi pomysłami aż do kolejnej porażki, heh i tak w kółko. A jak pozbyć się obsługi wyświetlacza w przerwaniu, w sensie multipleksować do w pętli do loop?

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 18:32
autor: kaktus
Proponuję zrobić znacznik wystąpienia przerwania, w jego obsłudze i tylko tyle.
A w pętli głównej analizować czy przerwanie wystąpiło, i tylko wtedy podejmować stosowną akcję.

To samo przerwanie można zaprząc do odmierzania dłuższych odcinków czasu, które można dodatkowo wykorzystać (zamiast wait ileśtam).
Jak? - zliczać ilość wystąpień przerwania i wykonywać odpowiednie instrukcje przy pewnej liczbie jego wystąpień.

;)

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 19:25
autor: maxd89pl
Trochę tera pomęczyłem ten kod i teraz wmiarę wszystko chodzi, nie wiem czy dobrze zrobiłem ale wrzuciłem wszystkie obliczenia do if-ów od obsługi przycisków plus i minus.

wygląda to teraz tak:
  1. Do
  2.  
  3. Select Case Menu
  4.  
  5.    Case 1:
  6.  
  7. If f_Dodaj = 0 Then
  8.    if Prz1 = 0 then
  9.       waitms 15
  10.          If Prz1 = 0 Then
  11.  
  12.             s1 = s1 + 1
  13.             gosub Wyswietl
  14.  
  15.                if s1 = 60 Then
  16.  
  17.                   m1 = m1 + 1
  18.                   s1 = 0
  19.                   gosub Wyswietl
  20.  
  21.                end if
  22.  
  23.          waitms 30
  24.  
  25.          end if
  26.    End if
  27. End if
  28.  
  29.  
  30.    if f_Odej = 0 then
  31.       if Prz2 = 0 then
  32.          waitms 15
  33.             If Prz2 = 0 Then
  34.  
  35.                s1 = s1 - 1
  36.                gosub Wyswietl
  37.  
  38.                   If m1 > 0 Then
  39.  
  40.                      If s1 = 0 Then
  41.  
  42.                         m1 = m1 - 1
  43.                         s1 = 59
  44.  
  45.                      end if
  46.  
  47.                      if s1 = 60 Then
  48.  
  49.                         m1 = m1 + 1
  50.                         s1 = 0
  51.                         gosub Wyswietl
  52.  
  53.                      end if
  54.  
  55.                waitms 30
  56.                   end if
  57.             end if
  58.       End if
  59.    end if
  60.  
  61.  
  62.  
  63.           If m1 > 0 Then                     'zapalanie kropki gdy min większe od 0
  64.  
  65.              Set Kr2
  66.  
  67.              else
  68.  
  69.              Reset Kr2
  70.  
  71.           End if
  72.  
  73.  
  74.           If m1 = 0 then
  75.  
  76.             If s1 = 0 Then
  77.  
  78.                f_Odej = 1
  79.  
  80.                else
  81.  
  82.                f_Odej = 0
  83.  
  84.             End if
  85.           end if
  86.  
  87.           If m1 = 15 then
  88.  
  89.             If s1 = 0 then
  90.  
  91.                s1 = 0
  92.                m1 = 0
  93.                gosub Wyswietl
  94.  
  95.             End if
  96.           End if
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.     Case 2:
  104.  
  105. End Select
  106.  
  107.  
  108.  
  109.  
  110. Loop
  111. End                                                         'end program
miałem problem z ograniczeniem jak dobije do końca np. 30:00, więc zrobiłem że:
  1.   If m1 = 15 then
  2.  
  3.             If s1 = 0 then
  4.  
  5.                s1 = 0
  6.                m1 = 0
  7.                gosub Wyswietl
  8.  
  9.             End if
  10.           End if
się wszystko zeruje

Teraz zostaje napisanie rozpoczęcia odliczania po naciśnięciu entera

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 20:41
autor: niveasoft
Kod nie wygląda dobrze. Napisany w ten sposób nie będzie również dobrze liczył czasu.
Dla czterech wyświetlaczy powinieneś zacząć od ustawienia Timera na 200Hz co da 5ms.
W przerwaniu można multipleksować takie wyświetlacze. Unikam tego tylko kiedy system ma uważać na inne przerwania których u Cibie nie ma.
Sekunda ma 1000ms. To podzielone przez 5ms daje liczbę 200 i do tylu powinieneś liczyć by sobie obliczyć sekundę.

Nie wiem po co tam masz te zamianę na BCD bo przecież wykorzystujesz cały PORTD.

Niestety jestem obłożony pracą i nie bardzo mam czas napisać jakiś przykład. Może coś tam wygospodaruję, ale w twoim kodzie u góry brakuje ostatniej wartości w tabeli.

Mam też małą uwagę organizacyjną. Chcąc umieścić kod wybierz "Bascom" z rozwijanego menu po lewej "Select code". Bascom jest tam trochę niżej, ale jest. Niedługo dam go na samą górę...tylko muszę znaleźć czas :D

Re: Pomoc przy wyświetlaczach 7seg...

: 24 kwie 2017, 22:10
autor: maxd89pl
No zgadzam się, że kod to jeden wielki brudnopis, tak kombinuje i szukam w necie jak to inni robia tylko że w sieci sa całe kody jakiś urządzeń i trudno mi z nich powyciagać fragmenty które mi są potrzebne bo nie zabardzo mi idzie analizowanie całych kodów, a znowu jak gdzie indziej pisałem o pomoc to nie chcą wklejać działajacego kawałka kodu tylko pisza po ludzkiemu jak to powinno działać.

Teraz jestem w pracy to już się nie pobawie, ale uruchomiłem już odliczanie ale nie timera0 który multipleksuje wyswietlacze tylko uruchomiłem do tego timera2 czyli 8mhz/256/280 to jest 8ms razy 125 co daje 1sek

Re: Pomoc przy wyświetlaczach 7seg...

: 25 kwie 2017, 9:50
autor: niveasoft
Napisz jak ten timer ma działać. Ma odliczać w dół czy ma liczyć w górę? Jeśli w dół to jak tymi klawiszami planujesz ustawiać czas.
Przytrzymanie Plusa ma zwiększać sekundy tak by narosło do 30minut? To trochę potrwa.
Napisz jak to widzisz. Popraw kod w pierwszym poście bo tam brakuje ostatniego elementu tablicy Kody7seg.
Gdyby ktoś chciałby Ci pomóc to musiałby to rozgryźć i dopisać.
Dobrze by było jak byś opisał przy jednej komórce tej tablicy który bit odpowiada za dany segment ABCDEFG*
Zamiany na kod BCD używa się gdy w schemacie urządzenia występuje układ dekodera kodu BCD na wyświetlacz.
Coś w stylu HEF4543. Wtedy kod cyfry zapisany jest tylko na czterech bitach.