Pytania, kody i porady dotyczące nie tylko Bascom.
-
Rafał Piwowarczyk
- Posty: 8
- Rejestracja: 18 gru 2016, 17:36
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:
$regfile = "attiny2313a.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
Config Timer0 = Timer , Prescale = 64 'Konfiguracja TIMER0
On Timer0 Przerwanie_1s
Config Timer1 = Timer , Prescale = 8 'Konfiguracja TIMER1
On Timer1 Przerwanie_1min
'*******************
'Konfiguracja portów
'*******************
Config Portb.0 = Output : Portb.0 = 1
Config Portb.1 = Output : Portb.1 = 1
Config Portb.2 = Output : Portb.2 = 1
Config Portb.3 = Output : Portb.3 = 1
Config Portb.4 = Output : Portb.4 = 1
Config Portb.5 = Output : Portb.5 = 1
Config Portb.6 = Output : Portb.6 = 1
Config Portb.7 = Output : Portb.7 = 1
Config Portd.0 = Output : Portd.0 = 0
Config Portd.4 = Output : Portd.4 = 0
Config Portd.5 = Output : Portd.5 = 0
Config Pind.1 = Input : Pind.1 = 1
Config Pind.2 = Input : Pind.2 = 1
Config Pind.3 = Input : Pind.3 = 1
'************
'Nazwy portow
'************
Seg_a Alias Portb.0
Seg_b Alias Portb.1
Seg_c Alias Portb.2
Seg_d Alias Portb.3
Seg_e Alias Portb.4
Seg_f Alias Portb.5
Seg_g Alias Portb.6
Wsp_a Alias Portb.7
Pk Alias Portd.0
Sw_1 Alias Pind.1
Int_ Alias Pind.2
Sw_2 Alias Pind.3
Led_1 Alias Portd.4
Led_2 Alias Portd.5
'*******
'Zmienne
'*******
Dim I As Byte
Dim A As Integer
'Dim Helpb As Byte
'Dim T1 As Eram Byte
Dim Get_sek As Bit
Dim Get_min As Bit
Dim Licznik_1 As Word
Dim Licznik_min As Word
Dim Licznik_1min As Word
Dim Change_time As Byte
'***********
'Podprogramy
'***********
Declare Sub Count_time
'**********************
'Początek pętli głównej
'**********************
Enable Interrupts
Gosub Test
Waitms 250
Set Led_1
'Helpb = T1 'Odczyt zmiennej T1 z pamięci EEPROM
'If Helpb > 1 Then Helpb = 0
'Change_time = Helpb
Do
Disable Timer0 'wyłącz timer0
Disable Timer1 'wyłącz timer1
Reset Wsp_a 'włącz segment LCD
If Sw_1 = 0 Then 'wciśnij sw_1 aby zmienić czas
Waitms 300
Incr Change_time
If Change_time > 9 Then
Change_time = 9
End If
End If
If Sw_2 = 0 Then
Waitms 300
Decr Change_time
If Change_time < 1 Then
Change_time = 1
End If
End If
If Int_ = 0 Then 'wciśnij sw_2 aby odliczać czas
Call Count_time
End If
Select Case Change_time
Case 0:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 1
Case 1:
Seg_a = 1
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 1
Seg_g = 1
Case 2:
Seg_a = 0
Seg_b = 0
Seg_c = 1
Seg_d = 0
Seg_e = 0
Seg_f = 1
Seg_g = 0
Case 3:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 1
Seg_g = 0
Case 4:
Seg_a = 1
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 0
Seg_g = 0
Case 5:
Seg_a = 0
Seg_b = 1
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 0
Seg_g = 0
Case 6:
Seg_a = 0
Seg_b = 1
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 0
Case 7:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 1
Seg_g = 1
Case 8:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 0
Case 9:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 0
Seg_g = 0
End Select
Loop
End
'**********************
'Podprogram odlicz czas
'**********************
Sub Count_time:
Enable Timer0 'włącz timer0
Enable Timer1 'włącz timer1
Set Pk
Set Led_2
Waitms 100
Do
If Get_sek = 1 Then 'migaj co 1sek. LCD
Get_sek = 0
Toggle Wsp_a
End If
If Get_min = 1 Then 'Dekrementacja odmierzania czasu
Get_min = 0
Decr Change_time
If Change_time = 0 Then
'Helpb = Change_time 'zapis danej do eeprom
'T1 = Helpb
Reset Wsp_a 'zapal segment LCD
Reset Led_2 'wyłącz led_2
Reset Pk 'wyłącz przeksźnik
Exit Do
End If
End If
Loop
End Sub
'******************
'Podprogram testowy
'******************
Test:
Reset Wsp_a
Waitms 500
For A = 0 To 7
Portb . A = 1
Waitms 500
Portb . A = 0
Next A
Waitms 500
Set Led_1
Waitms 500
Set Led_2
Waitms 500
Set Pk
Wait 1
Reset Led_1
Reset Led_2
Reset Pk
Wait 1
Return
'********************
'Przerwanie od timer0
'********************
Przerwanie_1s:
Incr Licznik_1
If Licznik_1 > 490 Then 'odlicz do 1 sek.
Licznik_1 = 0
Get_sek = 1 'Flaga sekund
End If
Return
'********************
'Przerwanie od timer1
'********************
Przerwanie_1min:
Incr Licznik_1min
If Licznik_1min > 915 Then 'odlicz do 1 minuty.
Licznik_1min = 0
Get_min = 1 'Flaga minut
End If
Return
-
Oldman
- Posty: 61
- Rejestracja: 19 cze 2019, 11:15
Post
autor: Oldman » 26 gru 2019, 20:12
Żeby coś zapisać do Epromu to najpierw musisz zadeklarować zmienną w tej pamięci, np:
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:
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ąć.
-
niveasoft
- Posty: 1216
- Rejestracja: 17 sie 2015, 12:13
-
Kontakt:
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
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
$regfile = "attiny2313a.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
Config Submode = New
'*******************
'Konfiguracja Timera1 dla 1s
'*******************
Config Timer1 = Timer , Prescale = 256 , Clear_timer = 1
Compare1a = 31249 '1s @8MHz/256
'*******************
'Konfiguracja portów
'*******************
Config Portb = Output : Portb = 255
Config Portd.0 = Output : Portd.0 = 0 : Pk Alias Portd.0
Config Portd.4 = Output : Portd.4 = 0 : Led_1 Alias Portd.4
Config Portd.5 = Output : Portd.5 = 0 : Led_2 Alias Portd.5
Config Pind.1 = Input : Portd.1 = 1 : Sw_1 Alias Pind.1 'podciąganie ustawia się na PORT a nie PIN!
Config Pind.2 = Input : Portd.2 = 1 : Int_ Alias Pind.2
Config Pind.3 = Input : Portd.3 = 1 : Sw_2 Alias Pind.3
'************
'Nazwy portow
'************
Seg_a Alias Portb.0
Seg_b Alias Portb.1
Seg_c Alias Portb.2
Seg_d Alias Portb.3
Seg_e Alias Portb.4
Seg_f Alias Portb.5
Seg_g Alias Portb.6
Wsp_a Alias Portb.7 ' segmenty aktywne kiedy LO
'*******
'Zmienne
'*******
Dim Cyfra_new As Byte , Cyfra_prev As Byte , Mytest As Byte
Dim Odlicz_czas As Byte , Odlicz_minute As Byte
Dim Czas_ustawiany As Byte , Czas_ustawiany_ee As Eram Byte
Czas_ustawiany = Czas_ustawiany_ee 'odczyt z eeprom
If Czas_ustawiany > 9 Then
Czas_ustawiany = 9
Czas_ustawiany_ee = Czas_ustawiany
End If
'***********
'Podprogramy
'***********
Sub Ustaw_cyfre
Select Case Cyfra_new
Case 0:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 1
Case 1:
Seg_a = 1
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 1
Seg_g = 1
Case 2:
Seg_a = 0
Seg_b = 0
Seg_c = 1
Seg_d = 0
Seg_e = 0
Seg_f = 1
Seg_g = 0
Case 3:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 1
Seg_g = 0
Case 4:
Seg_a = 1
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 0
Seg_g = 0
Case 5:
Seg_a = 0
Seg_b = 1
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 0
Seg_g = 0
Case 6:
Seg_a = 0
Seg_b = 1
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 0
Case 7:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 1
Seg_e = 1
Seg_f = 1
Seg_g = 1
Case 8:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 0
Seg_f = 0
Seg_g = 0
Case 9:
Seg_a = 0
Seg_b = 0
Seg_c = 0
Seg_d = 0
Seg_e = 1
Seg_f = 0
Seg_g = 0
End Select
End Sub
'**********************
'Początek pętli testu
'**********************
Call Ustaw_cyfre 'ustawi zero ma wyświetlaczu
Do
If Cyfra_new <> Mytest Then 'dlatego tutaj żeby nie próbował ustawić 10
Cyfra_new = Mytest
Call Ustaw_cyfre
End If
If Tifr.ocf1a = 1 Then
Tifr.ocf1a = 1
Incr Mytest
If Mytest = 9 Then
Set Pk 'dla testu ustaw przekaźnik tylko na jedną, ostatnią sekundę
Set Led_2
End If
End If
Loop Until Mytest = 10 'przejdzie od 0 do 9 i wyjdzie
Reset Pk
Reset Led_2
Set Led_1
'**********************
'Początek pętli głównej
'**********************
Cyfra_new = Czas_ustawiany
Call Ustaw_cyfre
Do
If Tifr.ocf1a = 1 Then 'tu kod co 1 sekundę
Tifr.ocf1a = 1
If Odlicz_czas > 0 Then
If Odlicz_minute > 0 Then
Decr Odlicz_minute
Else
Odlicz_minute = 59
Decr Odlicz_czas
Cyfra_new = Odlicz_czas
Call Ustaw_cyfre
End If
Toggle Wsp_a 'segmenty migaja co sekundę
If Odlicz_czas = 0 Then
Reset Pk
Reset Led_2
Reset Wsp_a 'segmenty świeca na stałe
Cyfra_new = Czas_ustawiany
Call Ustaw_cyfre
End If
End If
'end if 1s
End If
Debounce Int_ , 0 , Start_sub , Sub
Debounce Sw_1 , 0 , Plus_sub , Sub
Debounce Sw_2 , 0 , Minus_sub , Sub
Loop
End
Plus_sub:
If Czas_ustawiany < 9 Then
Incr Czas_ustawiany
Czas_ustawiany_ee = Czas_ustawiany
Cyfra_new = Czas_ustawiany
Call Ustaw_cyfre
If Odlicz_czas > 0 Then
Gosub Start_sub
End If
End If
Return
Minus_sub:
If Czas_ustawiany > 1 Then
Decr Czas_ustawiany
Czas_ustawiany_ee = Czas_ustawiany
Cyfra_new = Czas_ustawiany
Call Ustaw_cyfre
If Odlicz_czas > 0 Then
Gosub Start_sub
End If
End If
Return
Start_sub:
Odlicz_czas = Czas_ustawiany
Odlicz_minute = 59
Set Pk
Set Led_2
Return
-
Rafał Piwowarczyk
- Posty: 8
- Rejestracja: 18 gru 2016, 17:36
Post
autor: Rafał Piwowarczyk » 28 gru 2019, 19:24
Dzięki serdeczne ale program działa wyśmienicie. Dzięki za pomoc. Pozdrawiam serdecznie