$regfile = "m8def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
Config Submode = New
' Kompilator automatycznie obliczy wszystko na podstawie podanego taktownia
Const Na_jedna_sekunde = _xtal / 1024 '15625 @16MHz /2=7812,5
' Przykład : Taktowanie 16000000 czyli 16MHz oznacza że robi tyle ticków na 1s
' Kiedy podzielimy taktowanie prescalerem 1024 to na sekundę zrobi tylko 15625 ticków (dla Timera)
' Przypuśćmy że odmierzyliśmy 500ms, w Timer1 będzie wartość połowy z 15625 czyli ~7812
' Obliczenia (7812*1000)/15625=500 czyli wynik prawidłowy 500ms
'
' Prescaler 1024 sprawia że wynik i tak jest dokładniejszy o jeden rząd wielkości
' Sekunda ma 1000ms a Timer jest taktowany 15tyś/sec
'********************************************
'* STOP BUTTON PIN ICP PORTB.0 *
'********************************************
Portb.0 = 1 'ENABLE PULLUPS
'********************************************
'* START BUTTON INT0 *
'********************************************
Portd.2 = 1 'ENABLE PULLUPS
'********************************************
'* RESTART BUTTON *
'********************************************
Config Portd.4 = Input : Restart_sw Alias Pind.4 : Set Portd.4
'********************************************
'* INDICATING LED *
'********************************************
Config Portd.5 = Output : Led Alias Portd.5 '
'********************************************
'* CALIBRATION PIN *
'********************************************
Config Portd.0 = Input : Calib_pin Alias Pind.0 : Set Portd.0
Dim Helpd As Dword , Helpd2 As Dword , Help_w As Word , Overflows As Word
Dim Min_ As Byte , Sec_ As Byte , Miliseconds As Word , Old_flag As Byte
Dim Reszta As Word , Flaga_pomiar As Byte , Ms As Byte , Restart As Byte
Dim Pos As Byte , Helpw1 As Word , Helpw2 As Word
'*********************************************
'* MAX 7219 CONTROLS *
'*********************************************
Config Portc.2 = Output : Cs_enable Alias Portc.2 : Set Cs_enable
Config Portc.1 = Output : Ser_clk Alias Portc.1
Config Portc.0 = Output : Ser_data Alias Portc.0
Dim Disp_buff As Word
Dim Disp_num As Byte At Disp_buff + 1 Overlay
Dim Disp_data As Byte At Disp_buff Overlay
Dim Disp(8) As Byte
Dim Hours As Byte At Disp(1) Overlay
Dim Md As Byte At Disp(2) Overlay
Dim Mj As Byte At Disp(3) Overlay
Dim Sd As Byte At Disp(4) Overlay
Dim Sj As Byte At Disp(5) Overlay
Dim Mss As Byte At Disp(6) Overlay
Dim Msd As Byte At Disp(7) Overlay
Dim Msj As Byte At Disp(8) Overlay
Dim N As Byte
Sub Disp_write
'Reset Ser_data
'Reset Ser_clk
Reset Cs_enable
Shiftout Ser_data , Ser_clk , Disp_buff , 1
Set Cs_enable
End Sub
'Max7219_setup:
Disp_num = &H0C : Disp_data = 0 '&H0C Power mode, 0-OFF,1-ON
Call Disp_write
Disp_num = &H9 : Disp_data = &B1111_1111 'Jeden bit na jeden wyswietlacz,wlaczaja dekodowanie cyfr
'10 - (kreska)'11 E '12 H '13 L '14 P '15 " " (pusty)
Call Disp_write
Disp_num = &H0A : Disp_data = &H0F 'jasnosc 16 krokow, wartosci od &H00 do &H0F
Call Disp_write
Disp_num = &H0B : Disp_data = 7 'ile ma obsługiwac cyfr, wartosci od 0 do 7
Call Disp_write
Disp_num = &H0F : Disp_data = 0 'Test wyswietlacza, 0-OFF, 1-TEST ON
Call Disp_write
Disp_num = &H0C : Disp_data = 1 '&H0C Power mode, 0-OFF,1-ON
Call Disp_write
'------------------------------------------
' -START- -
'------------------------------------------
Decimal_point Alias 7 'włacza kropeczkę, przecinek (ustawia 7 bit)
Dim Calosc As Dword
Dim Mod_sec As Dword
Dim Above_sec As Dword
Sub Show_result
For N = 1 To 8
Disp_num = 9 - N
Disp_data = Disp(n)
Select Case N
Case 1 : Disp_data.decimal_point = 1
Case 3 : Disp_data.decimal_point = 1
Case 5 : Disp_data.decimal_point = 1
End Select
Call Disp_write
Next
End Sub
Sub Calculate
Calosc = Overflows 'ilośc przepełnień
Shift Calosc , Left , 16 'pomnóż x 65536 (16 bitów)
Calosc = Calosc + Reszta 'dodaj wartość reszty z Timera
'w zmiennej Calosc ilosc taktow na sekunde
'Układ generuje tyle ticków na sekunde ile ma zmienna "Na_jedna_sekunde"
'Teoretycznie wiec podzielenie przez te liczbe daje absolutna wartosc sekund
'a reszta to ilośc milisekund
'Milisekund w sekundzie jest tysiąc więc mnożenie x1000 i dzielenie przez 1s (Na_jedna_sekunde)
Mod_sec = Calosc Mod Na_jedna_sekunde
'w zmiennej Mod_sec reszta z dzielenia przez sekundy
Above_sec = Calosc / Na_jedna_sekunde
'w zmiennej Above_sec liczba sekund
'obliczenia milisekund
'--------------------------------------------------------------------
Helpd = Mod_sec * 1000
Helpd2 = Helpd / Na_jedna_sekunde
Miliseconds = Helpd2 'rzutowanie Dword na Word
Helpw1 = Miliseconds / 100
Mss = Helpw1 'setne milisekund
Helpw2 = Miliseconds Mod 100
Helpw1 = Helpw2 / 10
Msd = Helpw1 'dziesietne milisekund
Helpw1 = Helpw2 Mod 10
Msj = Helpw1 'jednosci milisekund
'--------------------------------------------------------------------
Helpd = Above_sec Mod 60 'sekundy to reszta z dzielenia przez 60
Sec_ = Helpd 'rzutowanie z Dword na Byte
Sd = Sec_ / 10
Sj = Sec_ Mod 10
'pozbywany sie sekund
Helpd2 = Above_sec / 60
Helpd = Helpd2 Mod 60 'obliczanie ilosci minut
Min_ = Helpd 'rzutowanie z Dword na Word
Md = Min_ / 10
Mj = Min_ Mod 10
Helpd = Helpd2 / 60 'obliczanie godzin
Hours = Helpd
End Sub
Sub Test_displ
'wyswietl 12345678
'--------------------
For N = 1 To 8
Disp_num = 9 - N
Disp_data = N
Call Disp_write
Next
End Sub
Sub Cls_displ
For N = 1 To 8
Disp_num = N
Disp_data = 15 '&HF czysci
Call Disp_write
Next
End Sub
'************************************************************************
'** PROGRAM START **
'************************************************************************
Call Test_displ
Wait 2
Call Cls_displ
'wait for thermostat
Do
Incr Pos
If Pos = 9 Then
Pos = 0
Call Cls_displ
Else
Disp_num = 9 - Pos
Disp_data = 10 '10 daje kreseczke
Call Disp_write
End If
Waitms 200
Loop Until Calib_pin = 1
'cls niepotrzebne bo zmienne puste i pokaże zera
Call Show_result 'pokaz juz z kropkami(przecinkami)
'^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
' DOPIERO TERAZ ODBLOKOWANIE PRZERWAŃ
'------------------------------------------
Config Int0 = Falling : On Int0 Int0_isr Nosave : Enable Int0
'*********************************************
'* TIMER CONFIG OVERFLOWS AND CAPTURE *
'*********************************************
'NOISE CANCEL MOŻNA WŁACZYĆ ALE ZABIERA 4 TAKTY
Config Timer1 = Timer , Prescale = 1024 , Capture_edge = Falling ', Noise_cancel = 1
Stop Timer1
Enable Timer1 : On Timer1 Timer1_isr Nosave
On Capture1 Capture1_isr Nosave
'*********************************************
'*********************************************
'Sfior.psr10 = 1
Enable Interrupts
Do
If Flaga_pomiar = 1 Then
Reszta = Timer1
Call Calculate
Call Show_result
Old_flag = 1 'ustaw flage że mierzyliśmy
Set Led
Waitms 100
Else
If Old_flag = 1 Then
Old_flag = 0
Call Calculate
Call Show_result
Restart = 1
End If
If Restart_sw = 0 Then
If Restart = 1 Then
Restart = 0
Min_ = 0 : Sec_ = 0 : Miliseconds = 0 : Overflows = 0
N = Memcopy(sec_ , Disp(1) , 8 , 2)
Call Show_result
Gifr.intf0 = 1
Tifr.icf1 = 1
Enable Int0
Timer1 = 0
Reset Led
End If
End If
End If
Loop
End
Timer1_isr:
$asm
PUSH R26
PUSH R27
PUSH R30
PUSH R31
PUSH R24
!in R24, sreg
PUSH R24
$end Asm
Incr Overflows
' Tuned with NoSave Tool
$asm
POP R24
!out sreg, r24
POP R24
POP R31
POP R30
POP R27
POP R26
$end Asm
Return
Int0_isr:
$asm
PUSH R23
PUSH R24
!in R24, sreg
PUSH R24
$end Asm
Start Timer1
Sfior.psr10 = 1 '<<<<<< DODANE
Disable Int0
Enable Capture1
Flaga_pomiar = 1
' Tuned with NoSave Tool
$asm
POP R24
!out sreg, r24
POP R24
POP R23
$end Asm
Return
Capture1_isr:
$asm
PUSH R23
PUSH R24
PUSH R25
PUSH R26
PUSH R27
!in R24, sreg
PUSH R24
$end Asm
Stop Timer1
Disable Capture1
Reszta = Capture1
Flaga_pomiar = 0
' Tuned with NoSave Tool
$asm
POP R24
!out sreg, r24
POP R27
POP R26
POP R25
POP R24
POP R23
$end Asm
Return
'Po Włączeniu:
'1.
'2.
'3. Program W Pętli Czeka Na Aż Pojawi Sie Poziom 1 Na Pd0 Ok 2min Z Termostatu
' W Tym Czasie Wyswietlają Się Kreseczki Od Lewej Do Prawej Co 200ms
'4. Napis "KALIBRACJA OK" Wait2
'5. Napis "0.00.00.000 (minuty,sekundy i reszta)"
'6. Czekamy Na Impuls 0 Na Pd2 Do Startu , Zbocze Opadające(impuls Będzie Od 0.1ms Do 100ms)
'7. Pomiary I Obliczenia , Jak Się Da Co 100ms Wynik Na Lcd , Zapala Się Led Na Pd5
'8. Czekamy Na Impuls 0 Na Pd3 Stop Zbocze Opadające(impuls Od 0.1ms Do 100ms)
'9. Wyswietla Się Się Cały Wynik , Led Świeci Nadal
'10. Po Podaniu 0 Na Pd4 Reset , Led Gasnie I Wracamy Do Punktu 5