Jestem początkujący bascomowiec i mam problem . Na M8 zbudowałem sterownik do pieca i działa ok. lecz zamarzyło mi się rozbudować go o regulacje mocy nadmuchu , i nie mogę dać sobie rady chyba coś nie tak z przerwaniami czy co . Sam regulator jak i pomiar na DS osobno działa ok. ale w połączeniu z pomiarem na DS18B20 to już jest problem , zawiesza się pomiar lub resetuje w różnych okresach czasu . Podłączałem DS. na inne wyprowadzenia zmieniałem czas po pomiarze i nic . Brak mi już pomysłu, dołączam kawałek z programu, który tylko mierzy temperaturę i reguluje moc (na podstawie AVT2623)
$crystal = 8000000
Config Lcd = 16 * 2
'configuracja lcd
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.3 , Db6 = Portc.2 , Db7 = Portc.1 , E = Portc.0 , Rs = Portc.5
Config Int0 = Falling
Config Timer0 = Timer , Prescale = 256
Enable Int0
Dim Regulacja As Byte 'parametr regulacji w % od 0-100
Dim Int_counter As Byte
Dim Triak As Word 'parametr regulacji do ;icznika po przekształceniach
Declare Sub Wysw
Declare Sub Ddisplay
On Timer0 Sub_tim
Enable Interrupts
On Int0 Sub_int
Config Pind.7 = Input
Config Pind.6 = Input
Config Pind.1 = Output
'configuracja pomiaru temperatury
Config 1wire = Portb.5
Declare Sub Pomiar
Dim Sttemp As String * 10
Dim T As Integer
Dim T1 As Integer
Dim Bd(9) As Byte
Dim Temp1 As Single 'wartość temperatury po przekształceniach
Deflcdchar 1 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32 ' stopień celcjusza
Declare Sub Spraw
Dim Is_device As Bit 'zmienna wskazująca czy na magistrali jest urządzenie
Cls
Cursor Off
Regulacja = 30
Do
Call Pomiar
If Pind.7 = 0 Then
Incr Regulacja 'parametr regulacji w od 0 -100%
If Regulacja > 100 Then Regulacja = 100
If Regulacja < 1 Then Regulacja = 1
Wysw
End If
If Pind.6 = 0 Then
Decr Regulacja
If Regulacja > 100 Then Regulacja = 20
If Regulacja < 1 Then Regulacja = 1
Wysw
End If
Waitms 100
Call Wysw
Triak = Regulacja * 1.5
Loop
Sub Wysw
Cls
Locate 1 , 11
Lcd Sttemp ; Chr(1) ; "C"
Locate 1 , 1
Lcd Regulacja ; "%"
Waitms 200
End Sub
'pomiar ..............................................................
Sub Pomiar 'Dokonaj pomiaru temperatury
1wreset
Call Spraw
1wwrite &HCC
1wwrite &H44
Waitms 250
' Waitms 250
1wreset
1wwrite &HCC ' read internal RAM
1wwrite &HBE
Waitms 200
' Waitms 250 ' read 9 data bytest
Bd(1) = 1wread(9) ' read bytes in array
T = Makeint(bd(1) , Bd(2))
T = T * 10
T = T / 16
Temp1 = T * 0.1
Sttemp = Fusing(temp1 , "##.#")
End Sub
Sub Spraw 'Wywołaj urządzenie na magistrali
If Err = 1 Then 'jeżeli Błąd
Is_device = 0 ' ustaw Brak_Urządzenia
Set Portd.1
Cls
Lcd "Uszk. czujnik" ' wyświetl komunkikat
Waitms 200
End If
End Sub
Sub_int:
Enable Timer0
Timer0 = Triak
Start Timer0
Return
Sub_tim:
Reset Portd.1
Waitus 100
Set Portd.1
Return
[ Dodano: 21-01-2006, 09:10 ]
Wydaje mi że powodem tego jest to że timer0 wykorzystywany jest dla 1wire i stąd te problemy . Ale gdy zmienię na Timer1 i oczywiście Int1 to nie działa wcale ta regulacja , zdaje się że inaczej trzeba skonfigurować timer1 , ale nie wiem jak. Może ktoś by coś podpowiedział.
Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięRegulacja fazowa i DS1820
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
Nie Ty pierwszy zetknąłeś się , z tym - jakże niepożądanym - zjawiskiem.
Zjawisko to można oczywiście wyeliminować , za pomocą .... kalkulatora. Twój program , to dwa niezależne procesy , z których pierwszy steruje bramką triaka , a drugi odczytem DS-a.Na nieszczęście , każdy z tych procesów , jest ściśle uzależniony od czasu.Proces 1-szy , musi być wykonany w ściśle określonym momencie , natomiast proces drugi , w ściśle określonym czasie i tu zaczynają się schody Bywają momenty , że proces 1-szy kradnie część czasu procesowi drugiemu , a to wiąże się z jego nieprawidłowym działaniem.Jednym z rozwiązań jest synchronizacja tych procesów , a właściwie zsynchronizowanie procesu 2 z procesem 1 , czyli zsynchronizować odczyt DS-a z przerwaniem sub_int i sub_tim.Ponieważ przerwanie sub_int jest wykonywane co 10ms, to z nim nie będzie problemu.Gorsza sprawa , z przerwaniem sub_tim , ponieważ jest ono wykonywane z różnym opóźnieniem , w stosunku do momentu wykonania przerwania sub_int , ale i na to jest rada - wykorzystać wartość zapisaną w zmiennej Regulacja , która to wartość powie nam ile czasu ma upłynąć międzu wykonaniem sub_int , a sub_tim.
Tyle mądrowania , a teraz przykład:
Wprawdzie zwolnimy proces odczytu DS-a , ale to nie gra istotnej roli.
Pomiędzy wykonaniem się dowolnego z przerwań , mamy ~4ms czasu na - niczym nie zakłócony - odczyt DS-a.
Piotrek
PS
Zamiast przerwania od przepełnienia Timera , spróbuj wykorzystać jego sprzęt w postaci rejestru compare i wyjścia OCx , a wykorzystywać tylko przerwanie sub_int
Zjawisko to można oczywiście wyeliminować , za pomocą .... kalkulatora. Twój program , to dwa niezależne procesy , z których pierwszy steruje bramką triaka , a drugi odczytem DS-a.Na nieszczęście , każdy z tych procesów , jest ściśle uzależniony od czasu.Proces 1-szy , musi być wykonany w ściśle określonym momencie , natomiast proces drugi , w ściśle określonym czasie i tu zaczynają się schody Bywają momenty , że proces 1-szy kradnie część czasu procesowi drugiemu , a to wiąże się z jego nieprawidłowym działaniem.Jednym z rozwiązań jest synchronizacja tych procesów , a właściwie zsynchronizowanie procesu 2 z procesem 1 , czyli zsynchronizować odczyt DS-a z przerwaniem sub_int i sub_tim.Ponieważ przerwanie sub_int jest wykonywane co 10ms, to z nim nie będzie problemu.Gorsza sprawa , z przerwaniem sub_tim , ponieważ jest ono wykonywane z różnym opóźnieniem , w stosunku do momentu wykonania przerwania sub_int , ale i na to jest rada - wykorzystać wartość zapisaną w zmiennej Regulacja , która to wartość powie nam ile czasu ma upłynąć międzu wykonaniem sub_int , a sub_tim.
Tyle mądrowania , a teraz przykład:
Kod: Zaznacz cały
Dim Flaga As Byte
...
Sub Pomiar 'Dokonaj pomiaru temperatury
Gosub wait_for_interrupt
1wreset
Call Spraw
Gosub wait_for_interrupt
1wwrite &HCC
1wwrite &H44
Waitms 250
' Waitms 250
Gosub wait_for_interrupt
1wreset
Gosub wait_for_interrupt
1wwrite &HCC ' read internal RAM
1wwrite &HBE
Bd(1) = 1wread(2) ' read bytes in array
T = Makeint(bd(1) , Bd(2))
T = T * 10
T = T / 16
Temp1 = T * 0.1
Sttemp = Fusing(temp1 , "##.#")
End Sub
...
wait_for_interrupt:
Flaga=0
WhileFlaga=0:Wend
Return
Sub_int:
Enable Timer0
Timer0 = Triak
Start Timer0
If Regulacja >49 Then Flaga=1
Return
Sub_tim:
Reset Portd.1
Waitus 100
Set Portd.1
If Regulacja <50 Then Flaga=1
Return
Pomiędzy wykonaniem się dowolnego z przerwań , mamy ~4ms czasu na - niczym nie zakłócony - odczyt DS-a.
Piotrek
PS
Zamiast przerwania od przepełnienia Timera , spróbuj wykorzystać jego sprzęt w postaci rejestru compare i wyjścia OCx , a wykorzystywać tylko przerwanie sub_int
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 15 gości