Sterownik

Pytania, kody i porady dotyczące nie tylko Bascom.
ODPOWIEDZ
Rafał Piwowarczyk
Posty: 8
Rejestracja: 18 gru 2016, 17:36

Sterownik

Post autor: Rafał Piwowarczyk » 26 gru 2019, 19:02

Potrzebuję pomocy niby w bardzo prostej sprawie. Zbudowałem prosty sterownik schodowy który odmierza czas od 9 minut do zera na attiny2313 i wyświetłaczu siedmiosegmentowym. Program napisałem w Bascom AVR. Program działa bez żadnych problemów tylko nie mam pojęcia jak zapisać czas do pamięci EEPROM oraz wyświetlacz nie dekrementuje odliczanego czasu. Niby jest to błahostka ale spędziłem nad tym już sporo czasu i nic mi nie przychodzi sensownego do głowy. Proszę o pomoc.

Program ma działać w następujący sposób: Switchami sw1 i sw2 ustawiamy zadany czas na wyświetlaczu od 1 do 9 minut a po przyjściu stanu wysokiego na nóżkę mokrokontrolera sterownik ma zliczać czas od zadanego do zera po tym czasie wyłącza przekaźnik i ma wrócić do uprzednio ustawionego czasu (odczyt z EEPROM).
Drugi problem to wyświetlanie bieżącego czasu na wyświetlaczu (wyświetla się tylko czas ustawiony switchami na początku odliczania). Niby sprawa bardzo prosta ale nie wiem jak ją rozwiązać. Za co byłbym bardzo wdzięczny. Pozdrawiam serdecznie.

Poniżej załączam kod bascom:
  1. $regfile = "attiny2313a.dat"
  2. $crystal = 8000000
  3. $hwstack = 40
  4. $swstack = 16
  5. $framesize = 32
  6.  
  7.  
  8. Config Timer0 = Timer , Prescale = 64                       'Konfiguracja TIMER0
  9. On Timer0 Przerwanie_1s
  10.  
  11. Config Timer1 = Timer , Prescale = 8                        'Konfiguracja TIMER1
  12. On Timer1 Przerwanie_1min
  13.  
  14. '*******************
  15. 'Konfiguracja portów
  16. '*******************
  17.  
  18. Config Portb.0 = Output : Portb.0 = 1
  19. Config Portb.1 = Output : Portb.1 = 1
  20. Config Portb.2 = Output : Portb.2 = 1
  21. Config Portb.3 = Output : Portb.3 = 1
  22. Config Portb.4 = Output : Portb.4 = 1
  23. Config Portb.5 = Output : Portb.5 = 1
  24. Config Portb.6 = Output : Portb.6 = 1
  25. Config Portb.7 = Output : Portb.7 = 1
  26. Config Portd.0 = Output : Portd.0 = 0
  27. Config Portd.4 = Output : Portd.4 = 0
  28. Config Portd.5 = Output : Portd.5 = 0
  29.  
  30. Config Pind.1 = Input : Pind.1 = 1
  31. Config Pind.2 = Input : Pind.2 = 1
  32. Config Pind.3 = Input : Pind.3 = 1
  33.  
  34.  
  35.  
  36. '************
  37. 'Nazwy portow
  38. '************
  39.  
  40. Seg_a Alias Portb.0
  41. Seg_b Alias Portb.1
  42. Seg_c Alias Portb.2
  43. Seg_d Alias Portb.3
  44. Seg_e Alias Portb.4
  45. Seg_f Alias Portb.5
  46. Seg_g Alias Portb.6
  47. Wsp_a Alias Portb.7
  48.  
  49. Pk Alias Portd.0
  50. Sw_1 Alias Pind.1
  51. Int_ Alias Pind.2
  52. Sw_2 Alias Pind.3
  53. Led_1 Alias Portd.4
  54. Led_2 Alias Portd.5
  55.  
  56. '*******
  57. 'Zmienne
  58. '*******
  59.  
  60. Dim I As Byte
  61. Dim A As Integer
  62. 'Dim Helpb As Byte
  63. 'Dim T1 As Eram Byte
  64. Dim Get_sek As Bit
  65. Dim Get_min As Bit
  66. Dim Licznik_1 As Word
  67. Dim Licznik_min As Word
  68. Dim Licznik_1min As Word
  69. Dim Change_time As Byte
  70.  
  71. '***********
  72. 'Podprogramy
  73. '***********
  74.  
  75. Declare Sub Count_time
  76.  
  77. '**********************
  78. 'Początek pętli głównej
  79. '**********************
  80.  
  81. Enable Interrupts
  82.  
  83. Gosub Test
  84. Waitms 250
  85. Set Led_1
  86.  
  87. 'Helpb = T1                                                  'Odczyt zmiennej T1 z pamięci EEPROM
  88. 'If Helpb > 1 Then Helpb = 0
  89. 'Change_time = Helpb
  90.  
  91. Do
  92.  
  93. Disable Timer0                                              'wyłącz timer0
  94. Disable Timer1                                              'wyłącz timer1
  95. Reset Wsp_a                                                 'włącz segment LCD
  96.  
  97. If Sw_1 = 0 Then                                            'wciśnij sw_1 aby zmienić czas
  98. Waitms 300
  99. Incr Change_time
  100. If Change_time > 9 Then
  101. Change_time = 9
  102. End If
  103. End If
  104.  
  105. If Sw_2 = 0 Then
  106. Waitms 300
  107. Decr Change_time
  108. If Change_time < 1 Then
  109. Change_time = 1
  110. End If
  111. End If
  112.  
  113. If Int_ = 0 Then                                            'wciśnij sw_2 aby odliczać czas
  114. Call Count_time
  115. End If
  116.  
  117. Select Case Change_time
  118.  
  119. Case 0:
  120.  
  121. Seg_a = 0
  122. Seg_b = 0
  123. Seg_c = 0
  124. Seg_d = 0
  125. Seg_e = 0
  126. Seg_f = 0
  127. Seg_g = 1
  128.  
  129. Case 1:
  130.  
  131. Seg_a = 1
  132. Seg_b = 0
  133. Seg_c = 0
  134. Seg_d = 1
  135. Seg_e = 1
  136. Seg_f = 1
  137. Seg_g = 1
  138.  
  139. Case 2:
  140.  
  141. Seg_a = 0
  142. Seg_b = 0
  143. Seg_c = 1
  144. Seg_d = 0
  145. Seg_e = 0
  146. Seg_f = 1
  147. Seg_g = 0
  148.  
  149. Case 3:
  150.  
  151. Seg_a = 0
  152. Seg_b = 0
  153. Seg_c = 0
  154. Seg_d = 0
  155. Seg_e = 1
  156. Seg_f = 1
  157. Seg_g = 0
  158.  
  159. Case 4:
  160.  
  161. Seg_a = 1
  162. Seg_b = 0
  163. Seg_c = 0
  164. Seg_d = 1
  165. Seg_e = 1
  166. Seg_f = 0
  167. Seg_g = 0
  168.  
  169. Case 5:
  170.  
  171. Seg_a = 0
  172. Seg_b = 1
  173. Seg_c = 0
  174. Seg_d = 0
  175. Seg_e = 1
  176. Seg_f = 0
  177. Seg_g = 0
  178.  
  179. Case 6:
  180.  
  181. Seg_a = 0
  182. Seg_b = 1
  183. Seg_c = 0
  184. Seg_d = 0
  185. Seg_e = 0
  186. Seg_f = 0
  187. Seg_g = 0
  188.  
  189. Case 7:
  190.  
  191. Seg_a = 0
  192. Seg_b = 0
  193. Seg_c = 0
  194. Seg_d = 1
  195. Seg_e = 1
  196. Seg_f = 1
  197. Seg_g = 1
  198.  
  199. Case 8:
  200.  
  201. Seg_a = 0
  202. Seg_b = 0
  203. Seg_c = 0
  204. Seg_d = 0
  205. Seg_e = 0
  206. Seg_f = 0
  207. Seg_g = 0
  208.  
  209. Case 9:
  210.  
  211. Seg_a = 0
  212. Seg_b = 0
  213. Seg_c = 0
  214. Seg_d = 0
  215. Seg_e = 1
  216. Seg_f = 0
  217. Seg_g = 0
  218.  
  219. End Select
  220.  
  221. Loop
  222. End
  223.  
  224. '**********************
  225. 'Podprogram odlicz czas
  226. '**********************
  227.  
  228. Sub Count_time:
  229.  
  230. Enable Timer0                                               'włącz timer0
  231. Enable Timer1                                               'włącz timer1
  232. Set Pk
  233. Set Led_2
  234. Waitms 100
  235.  
  236. Do
  237.  
  238. If Get_sek = 1 Then                                         'migaj co 1sek. LCD
  239. Get_sek = 0
  240. Toggle Wsp_a
  241. End If
  242.  
  243. If Get_min = 1 Then                                         'Dekrementacja odmierzania czasu
  244. Get_min = 0
  245. Decr Change_time
  246. If Change_time = 0 Then
  247. 'Helpb = Change_time                                         'zapis danej do eeprom
  248. 'T1 = Helpb
  249. Reset Wsp_a                                                 'zapal segment LCD
  250. Reset Led_2                                                 'wyłącz led_2
  251. Reset Pk                                                    'wyłącz przeksźnik
  252.  
  253. Exit Do
  254. End If
  255. End If
  256. Loop
  257.  
  258. End Sub
  259.  
  260. '******************
  261. 'Podprogram testowy
  262. '******************
  263.  
  264. Test:
  265.  
  266. Reset Wsp_a
  267. Waitms 500
  268. For A = 0 To 7
  269. Portb . A = 1
  270. Waitms 500
  271. Portb . A = 0
  272. Next A
  273.  
  274. Waitms 500
  275. Set Led_1
  276. Waitms 500
  277. Set Led_2
  278. Waitms 500
  279. Set Pk
  280. Wait 1
  281. Reset Led_1
  282. Reset Led_2
  283. Reset Pk
  284. Wait 1
  285.  
  286. Return
  287.  
  288. '********************
  289. 'Przerwanie od timer0
  290. '********************
  291.  
  292. Przerwanie_1s:
  293. Incr Licznik_1
  294. If Licznik_1 > 490 Then                                     'odlicz do 1 sek.
  295. Licznik_1 = 0
  296. Get_sek = 1                                                 'Flaga sekund
  297. End If
  298. Return
  299.  
  300. '********************
  301. 'Przerwanie od timer1
  302. '********************
  303.  
  304. Przerwanie_1min:
  305.  
  306. Incr Licznik_1min
  307. If Licznik_1min > 915 Then                                  'odlicz do 1 minuty.
  308. Licznik_1min = 0
  309. Get_min = 1                                                 'Flaga minut
  310. End If
  311. Return
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Sterownik

Post autor: Oldman » 26 gru 2019, 20:12

Żeby coś zapisać do Epromu to najpierw musisz zadeklarować zmienną w tej pamięci, np:
  1. Dim E_zmienna As Eram Byte At 10
gdzie 10 to przykładowy numer komórki pamięci.
Teraz żeby coś zapisać do Epromu wystarczy zwykłe przypisanie:
  1. E_zmienna = Jakaś_zmienna
Odczyt wygląda podobnie.
Mała uwaga: Zapis do Epromu musisz zrobić tak, żeby następował dopiero po zmianie ustawień. Jak poleci z automatu w jakiejś pętli to szybko wykończysz procka.
Do wykrywania przycisków możesz wykorzystać Debounce. Najlepiej program przepisać tak, żeby w pętli głównej były tylko dwa Debounce od przycisków i nic więcej. Cała reszta w przerwaniach. Wtedy program można łatwiej ogarnąć.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Sterownik

Post autor: niveasoft » 26 gru 2019, 20:28

Najpierw co do odpowiedzi @Oldman'a - MCS radzi by nie dodawać na końcu deklaracji "At konkretny adres" tylko zostawić to kompilatorowi. Zmienne w pamieci będą poukładane po kolei i jak coś zmienisz, dodasz to nie musisz się martwić bo wszystko się przesunie.
At najlepiej używać tylko do zmiennych które kompilator zna np. Dim Mybyte As Byte At Bufor(0) Overlay

Co do kodu to napisałem to tak na kolanie bez testowania i gwarancji że ruszy nie ma :D
Miałeś tam tez błąd programowania. Pinu nie da się podciągnąć do plusa wpisując PIND.1=1 Żeby podciągnąć konfigurujesz jako Input, ale potem piszesz PORTD.1=1 i to włączy podciąganie. Poprawiłem też dwa błędy w opisie... ciekawe czy znajdziesz jakie :D
  1. $regfile = "attiny2313a.dat"
  2. $crystal = 8000000
  3. $hwstack = 40
  4. $swstack = 16
  5. $framesize = 32
  6.  
  7. Config Submode = New
  8.  
  9.     '*******************
  10.     'Konfiguracja Timera1 dla 1s
  11.     '*******************
  12.  
  13. Config Timer1 = Timer , Prescale = 256 , Clear_timer = 1
  14.  Compare1a = 31249                                          '1s @8MHz/256
  15.  
  16.     '*******************
  17.     'Konfiguracja portów
  18.     '*******************
  19.  
  20. Config Portb = Output : Portb = 255
  21.  
  22. Config Portd.0 = Output : Portd.0 = 0 : Pk Alias Portd.0
  23. Config Portd.4 = Output : Portd.4 = 0 : Led_1 Alias Portd.4
  24. Config Portd.5 = Output : Portd.5 = 0 : Led_2 Alias Portd.5
  25.  
  26. Config Pind.1 = Input : Portd.1 = 1 : Sw_1 Alias Pind.1     'podciąganie ustawia się na PORT a nie PIN!
  27. Config Pind.2 = Input : Portd.2 = 1 : Int_ Alias Pind.2
  28. Config Pind.3 = Input : Portd.3 = 1 : Sw_2 Alias Pind.3
  29.  
  30.     '************
  31.     'Nazwy portow
  32.     '************
  33.  
  34. Seg_a Alias Portb.0
  35. Seg_b Alias Portb.1
  36. Seg_c Alias Portb.2
  37. Seg_d Alias Portb.3
  38. Seg_e Alias Portb.4
  39. Seg_f Alias Portb.5
  40. Seg_g Alias Portb.6
  41. Wsp_a Alias Portb.7                                         ' segmenty aktywne kiedy LO
  42.  
  43.     '*******
  44.     'Zmienne
  45.     '*******
  46.  
  47. Dim Cyfra_new As Byte , Cyfra_prev As Byte , Mytest As Byte
  48. Dim Odlicz_czas As Byte , Odlicz_minute As Byte
  49. Dim Czas_ustawiany As Byte , Czas_ustawiany_ee As Eram Byte
  50.  
  51. Czas_ustawiany = Czas_ustawiany_ee                          'odczyt z eeprom
  52. If Czas_ustawiany > 9 Then
  53.  Czas_ustawiany = 9
  54.   Czas_ustawiany_ee = Czas_ustawiany
  55. End If
  56.  
  57.     '***********
  58.     'Podprogramy
  59.     '***********
  60.  
  61. Sub Ustaw_cyfre
  62.  
  63.    Select Case Cyfra_new
  64.  
  65.       Case 0:
  66.  
  67.          Seg_a = 0
  68.          Seg_b = 0
  69.          Seg_c = 0
  70.          Seg_d = 0
  71.          Seg_e = 0
  72.          Seg_f = 0
  73.          Seg_g = 1
  74.  
  75.       Case 1:
  76.  
  77.          Seg_a = 1
  78.          Seg_b = 0
  79.          Seg_c = 0
  80.          Seg_d = 1
  81.          Seg_e = 1
  82.          Seg_f = 1
  83.          Seg_g = 1
  84.  
  85.       Case 2:
  86.  
  87.          Seg_a = 0
  88.          Seg_b = 0
  89.          Seg_c = 1
  90.          Seg_d = 0
  91.          Seg_e = 0
  92.          Seg_f = 1
  93.          Seg_g = 0
  94.  
  95.       Case 3:
  96.  
  97.          Seg_a = 0
  98.          Seg_b = 0
  99.          Seg_c = 0
  100.          Seg_d = 0
  101.          Seg_e = 1
  102.          Seg_f = 1
  103.          Seg_g = 0
  104.  
  105.       Case 4:
  106.  
  107.          Seg_a = 1
  108.          Seg_b = 0
  109.          Seg_c = 0
  110.          Seg_d = 1
  111.          Seg_e = 1
  112.          Seg_f = 0
  113.          Seg_g = 0
  114.  
  115.       Case 5:
  116.  
  117.          Seg_a = 0
  118.          Seg_b = 1
  119.          Seg_c = 0
  120.          Seg_d = 0
  121.          Seg_e = 1
  122.          Seg_f = 0
  123.          Seg_g = 0
  124.  
  125.       Case 6:
  126.  
  127.          Seg_a = 0
  128.          Seg_b = 1
  129.          Seg_c = 0
  130.          Seg_d = 0
  131.          Seg_e = 0
  132.          Seg_f = 0
  133.          Seg_g = 0
  134.  
  135.       Case 7:
  136.  
  137.          Seg_a = 0
  138.          Seg_b = 0
  139.          Seg_c = 0
  140.          Seg_d = 1
  141.          Seg_e = 1
  142.          Seg_f = 1
  143.          Seg_g = 1
  144.  
  145.       Case 8:
  146.  
  147.          Seg_a = 0
  148.          Seg_b = 0
  149.          Seg_c = 0
  150.          Seg_d = 0
  151.          Seg_e = 0
  152.          Seg_f = 0
  153.          Seg_g = 0
  154.  
  155.       Case 9:
  156.  
  157.          Seg_a = 0
  158.          Seg_b = 0
  159.          Seg_c = 0
  160.          Seg_d = 0
  161.          Seg_e = 1
  162.          Seg_f = 0
  163.          Seg_g = 0
  164.  
  165.    End Select
  166.  
  167.  
  168. End Sub
  169.  
  170.     '**********************
  171.     'Początek pętli testu
  172.     '**********************
  173.  
  174. Call Ustaw_cyfre                                            'ustawi zero ma wyświetlaczu
  175.  
  176. Do
  177.  
  178.  If Cyfra_new <> Mytest Then                                'dlatego tutaj żeby nie próbował ustawić 10
  179.   Cyfra_new = Mytest
  180.    Call Ustaw_cyfre
  181.  End If
  182.  
  183.  If Tifr.ocf1a = 1 Then
  184.   Tifr.ocf1a = 1
  185.    Incr Mytest
  186.     If Mytest = 9 Then
  187.      Set Pk                                                 'dla testu ustaw przekaźnik tylko na jedną, ostatnią sekundę
  188.      Set Led_2
  189.     End If
  190.  End If
  191.  
  192. Loop Until Mytest = 10                                      'przejdzie od 0 do 9 i wyjdzie
  193.  
  194. Reset Pk
  195. Reset Led_2
  196. Set Led_1
  197.  
  198.     '**********************
  199.     'Początek pętli głównej
  200.     '**********************
  201.  Cyfra_new = Czas_ustawiany
  202.    Call Ustaw_cyfre
  203.  
  204. Do
  205.  
  206.   If Tifr.ocf1a = 1 Then                                    'tu kod co 1 sekundę
  207.    Tifr.ocf1a = 1
  208.  
  209.    If Odlicz_czas > 0 Then
  210.     If Odlicz_minute > 0 Then
  211.      Decr Odlicz_minute
  212.     Else
  213.      Odlicz_minute = 59
  214.      Decr Odlicz_czas
  215.       Cyfra_new = Odlicz_czas
  216.        Call Ustaw_cyfre
  217.     End If
  218.  
  219.     Toggle Wsp_a                                            'segmenty migaja co sekundę
  220.  
  221.     If Odlicz_czas = 0 Then
  222.      Reset Pk
  223.      Reset Led_2
  224.      Reset Wsp_a                                            'segmenty świeca na stałe
  225.       Cyfra_new = Czas_ustawiany
  226.        Call Ustaw_cyfre
  227.     End If
  228.  
  229.    End If
  230.  
  231.   'end if 1s
  232.   End If
  233.  
  234.   Debounce Int_ , 0 , Start_sub , Sub
  235.   Debounce Sw_1 , 0 , Plus_sub , Sub
  236.   Debounce Sw_2 , 0 , Minus_sub , Sub
  237.  
  238. Loop
  239. End
  240.  
  241. Plus_sub:
  242.  If Czas_ustawiany < 9 Then
  243.   Incr Czas_ustawiany
  244.   Czas_ustawiany_ee = Czas_ustawiany
  245.    Cyfra_new = Czas_ustawiany
  246.     Call Ustaw_cyfre
  247.    If Odlicz_czas > 0 Then
  248.     Gosub Start_sub
  249.    End If
  250.  End If
  251. Return
  252.  
  253. Minus_sub:
  254.  If Czas_ustawiany > 1 Then
  255.   Decr Czas_ustawiany
  256.   Czas_ustawiany_ee = Czas_ustawiany
  257.    Cyfra_new = Czas_ustawiany
  258.     Call Ustaw_cyfre
  259.    If Odlicz_czas > 0 Then
  260.     Gosub Start_sub
  261.    End If
  262.  End If
  263. Return
  264.  
  265. Start_sub:
  266.  Odlicz_czas = Czas_ustawiany
  267.   Odlicz_minute = 59
  268.   Set Pk
  269.    Set Led_2
  270. Return
Rafał Piwowarczyk
Posty: 8
Rejestracja: 18 gru 2016, 17:36

Re: Sterownik

Post autor: Rafał Piwowarczyk » 28 gru 2019, 19:24

Dzięki serdeczne ale program działa wyśmienicie. Dzięki za pomoc. Pozdrawiam serdecznie
ODPOWIEDZ