Hi,
dann wolln wir doch mal ...
Ich nutze übrigens den internen Oszillator. Es hängt
zusätzl. ein uhrenquarz dran um die Soft clock zu nutzen, das ist aber erst
einmal nebensächlich.
Ja, ich arbeite mit beiden Interrupts. Der Nullduchgang gelangt über einen Optokoppler an Int0. Standard Triac Phasenanschnittsteuerung.
Softclock bringt zusätzliche Interrupts über einen Timer rein. Das würfelt dir
noch mehr durcheinander. Du wirst die Netzfrequenz- und die Softclock-INTs
nicht synchron bekommen und deine Messung dazwischen platzieren können.
Softclock und Netzfrequenz/Dimmer-Interrupts werden wie bei einer
Schwebung von 2 Tönen durcheinanderlaufen und dir die Messungen
zerbrezeln. Also entweder Dimmer oder Softclock oder du mußt deine
Messung vergessen.
Jetzt aber mal zum Code ...
Code:
'#############################################################################
'$sim
$regfile = "m8def.dat"
$crystal = 1000000
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
Config Lcdbus = 4 ' LCD konfigurieren
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5
Config Lcd = 16 * 2
Cursor Off
' I/O konfigurieren
Config Portc.5 = Output 'Dimmer out
Config Portd = Input
Portd = &B11011111 ' PORT D alle Pull Up auf EIN
' ausser INT0
Config 1wire = Portc.0 ' onewire kofigurieren
Config Timer1 = Timer , Prescale = 1 ' Timer1 für Dimmer
On Timer1 Triac_zuenden 'konfigurieren
Enable Timer1
Config Int0 = Rising ' Interrupt für Nulldurchgang
On Int0 Timer_start ' konfigurieren
Enable Int0
Enable Interrupts
Deflcdchar 1 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32 ' Grad -zeichen
Deflcdchar 2 , 32 , 32 , 10 , 32 , 4 , 4 , 17 , 14 ' Smilie
Dim Ar(2) As Integer
Dim Temp_int As Integer
Dim Temperatur As Integer
Dim Hell As Word ' Wert fuer Dimmer
Dim T As Word ' Zeitintervall für Temp. Messung
Cls
Hell = 57000 ' Dimmer Licht
soweit der Teil vor der Hauptschleife. Sieht auf den ersten Blick OK aus.
Code:
' ############################## main ######################################
Do
Home
Lcd " moin "
Lowerline
Locate 2 , 1
Lcd Temperatur ; Chr(1) ; "C " ; T ; " "
Select Case T
Case 10:
Home
Lcd T ' um zu sehen ob die case erreicht wird
1wreset
Case 30:
1wwrite &HCC
1wwrite &H44
Case 150:
1wreset
Case 170:
1wwrite &HCC
1wwrite &HBE
Ar(1) = 1wread(2)
Temp_int = Makeint(ar(1) , Ar(2))
Shift Ar(1) , Right , 1
Temperatur = Temp_int / 2
Case 180:
T = 0
End Select
If T > 185 Then T = 0
Loop
und da ist ein ganz dicker Wurm drin. Die LCD-Routinen sind mächtige
Zeitfresser ! Mach die dahin wo sie mit sicherheit dein Timing nicht
durcheinanderbringen. Erst die wichtigen Sachen (1Wire) und dann dein
Debugging (LCD). NICHT andersrum.
Code:
'################## SUB Temperaturmessung ##########################
Tempmes:
Disable Interrupts
Enable Interrupts
Return
Der nächste Wurm.
Wenn du die Interrupts bei nem Dimmer abschaltest dann zerbrezelt es dir
die Synchronität mit der Netzfrequenz und deine Helligkeitswerte passen
nicht mehr. Alles kommt aus dem Tritt.
Deine Routine für INT0 (Nulldurchgänge)
Code:
'################## Timer1 INT Dimmer ##########################
Timer_start:
Portc.5 = 0
Stop Timer1
Timer1 = Hell
Start Timer1
T = T + 1
Return
Deine Routine für den Zündimpuls (Timer1)
Code:
'################## Dimmer Triac zuenden ##########################
Triac_zuenden:
Stop Timer1
' Pulseout Portc , 0 , 100
Portc.5 = 1
Return
End
Wie Du siehst habe ich bei case: 10 eine LCD Anzeige eingebaut. So wie ich das im Moment sehe wird die case Select Abfrage gar nicht erreicht. D.h. 'T' wird auch nicht bei case: 180 zurückgesetzt
mach mal folgendes ...
- deine Select-Case für die Messungsteile baust du in eine Subroutine.
- Beim INT0 läßt du einen Zähler um 1 hochzählen (Bytevariable reicht)
- Wenn dein Zündimpuls näher am Nulldurchgang ist (vor dem Sinusscheitel)
dann rufst du die Sub in der ISR des Zündimpulses auf.
- Wenn dein Zündimpuls hinter dem Sinusscheitel ist dann rufst du deine
Messung in der ISR vom INT0 am Schluß auf.
- Nimm mal die Zählerwerte die ich bei meinem Beispiel genommen habe.
Also 1,2,104,105,106,107.
Also nochmal "ASCII-grafisch"
0 = Nulldurchgang (INT0)
Z = Zündimpuls (Timer1)
S = Sinusscheitel (90° oder 50%)
T = Temperaturmessung
0-----ZT--S----------|
0T---------S-----Z----|
Siehst du ungefähr was ich meine ? Die Teile der Temperaturmessung da
hinpacken wo sie am meißten Zeit zur Verfügung haben.
Gruß
Dino