PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PCint probleme



Carlos31
29.05.2010, 13:07
Guten Tag
Ich benutze ein Avr Butterfly , und möchte 3 schnelle zähler haben , deswegen hab ich den pcint benutzt , ich benutze pinb.0 bis pinb.2 für das , mein problem ist wenn ich die eingänge parallel hänge jeder pin zählt was anderes , pinb.0 zum beispiel zählt das doppelte wie pinb.1 ,
der pcint unterprogramm heist isr_int kann jemand da reinschauen und mir ein tip geben was ich da machen kann ?


$regfile = "M169DEF.DAT"
$crystal = 8000000
$baud = 19200

Config Watchdog = 512
Config Portb.5 = Output
Config Portb.7 = Output
Freq_slave_r Alias Portb.5
Freq_slave_l Alias Portb.6
Config Pinb.0 = Input
Config Pinb.1 = Input
Config Pinb.2 = Input
Portb.1 = 1
Portb.2 = 1
Portb.3 = 1
Master_bit Alias Pinb.0
Slave_l Alias Pinb.1
Slave_r Alias Pinb.2

Config Timer0 = Timer , Prescale = 64
Enable Timer0
On Timer0 Isr_timer0

Config Timer2 = Timer , Prescale = 64
Enable Timer2
On Timer2 Isr_timer2

Enable Pcint1 'pcint einschalten
On Pcint1 Isr_int
Pcmsk1 = &B00000111 'maske zum einschalten von pcint für pinb 0,1,2
Enable Interrupts

Dim Master As Word

Dim Slave_links As Word
Dim Slave_rechts As Word
Dim Frequenz_r As Byte
Dim Frequenz_l As Byte
Dim Zeit_re As Word
Dim Zeit_li As Word
Dim Nullen As Byte
Dim Abstuerze As Word

Dim Wert As String * 5
Dim Buchstabe As String * 3
Dim Resultat As String * 1
Dim A As Word
Dim Wert1 As String * 5
Dim Buchstabe1 As String * 3
Dim Resultat1 As String * 1
Dim B As Word
Dim Wert2 As String * 5
Dim Buchstabe2 As String * 3
Dim Resultat2 As String * 1
Dim C As Word
Dim Wert3 As String * 5
Dim Buchstabe3 As String * 3
Dim Resultat3 As String * 1
Dim D As Word
Const Zeit_mot_re = 100 'constante für wiederholungsrate motor rechts
Const Zeit_mot_li = 100 'constante für wiederholungsrate motor links
Incr Abstuerze 'anzahl abstürze zählen
Wait 1
Do
Start Watchdog

Wert = Str(abstuerze)
Buchstabe = "A"
Resultat = Buchstabe + Wert
Print Resultat
Waitms 100
Stop Watchdog
Start Watchdog
Wert1 = Str(master)
Buchstabe1 = "B"
Resultat1 = Buchstabe1 + Wert1
Print Resultat1
Waitms 100
Stop Watchdog
Start Watchdog
Wert2 = Str(slave_rechts)
Buchstabe2 = "C"
Resultat2 = Buchstabe2 + Wert2
Print Resultat2
Waitms 100
Stop Watchdog
Start Watchdog
Wert3 = Str(slave_links)
Buchstabe3 = "D"
Resultat3 = Buchstabe3 + Wert3
Print Resultat3
Waitms 100
Stop Watchdog
Start Watchdog
If Master > 40000 Then
Nullen.0 = 1
End If
If Slave_rechts > 40000 Then
Nullen.2 = 1
End If
If Slave_links > 40000 Then
Nullen.3 = 1
End If
If Nullen = 7 Then 'wenn alle zählerstände grösser sind als 40000 dann wird auf alle zählerstände 40000 substraiert
Nullen = 0
Master = Master - 40000
Slave_rechts = Slave_rechts - 40000
Slave_links = Slave_links - 40000
End If
Stop Watchdog


Loop


Isr_int:
If Master_bit = 0 Then
Incr Master 'zählen impulse motor master für motor slave links 'zählen impulse motor master für motor slave recht
End If
If Slave_l = 0 Then
Incr Slave_links
'zählen impulse motor slave links
End If
If Slave_r = 0 Then
Incr Slave_rechts
'zählen impulse motor slave rechts
End If


Return



Isr_timer0:
'timer 0 subroutine
If Frequenz_r > 220 Then 'frequenz limits
Frequenz_r = 220
End If
If Frequenz_r < 1 Then
Frequenz_r = 1
End If
Incr Zeit_re 'wiederholungsrate von konstante abhängig
If Zeit_re = Zeit_mot_re Then
Zeit_re = 0 'regelung
If Master > Slave_rechts Then
Incr Frequenz_r
End If
If Master < Slave_rechts Then
Decr Frequenz_r
End If
End If
Timer0 = Frequenz_r
Toggle Freq_slave_r
Return
'timer 2 subroutine
Isr_timer2: 'frequenz limits
If Frequenz_l > 220 Then
Frequenz_l = 220
End If
If Frequenz_l < 1 Then
Frequenz_l = 1
End If
Incr Zeit_li 'wiederholungsrate von konstante abhängig
If Zeit_li = Zeit_mot_li Then
Zeit_li = 0
If Master > Slave_links Then
Incr Frequenz_l
End If
If Master < Slave_links Then
Decr Frequenz_l
End If
End If
Timer2 = Frequenz_l
Toggle Freq_slave_l
Return

for_ro
29.05.2010, 15:16
Isr_int:
If Master_bit = 0 Then
Incr Master
End If
If Slave_l = 0 Then
Incr Slave_links
End If
If Slave_r = 0 Then
Incr Slave_rechts
End If
Return

Ich nehme an, dass du hiermit unterscheiden möchtest, welcher Pin ausgelöst hat und einschränken willst, dass nur die fallende Flanke zählen soll.
Für eine robuste Erkennung wird dies aber nicht reichen.
Stell dir nur vor, PinB.0 geht auf 0, die anderen bleiben auf 1. Dann wird die ISR aufgerufen und da PinB.0 = 0 ist, wird die Master Variable erhöht.
Wenn jetzt später PinB.1 auf 0 geht, wird wieder die ISR aufgerufen. Wenn PinB.0 jetzt immer noch auf 0 ist, wird Master wieder erhöht. Danach wird dann Slave_links auch erhöht.
Damit dies nicht passiert, könntest du dir z.B. den aktuellen Status der Pins merken und beim nächsten Aufruf der ISR überprüfen, ob der Status sich geändert hat. Nur dann wird die entsprechende Variable inkrementiert.

Ist das eigentlich gewollt, dass du nicht den PullUp von PinB.0 sondern den von PinB.3 einschaltest?

Carlos31
29.05.2010, 15:48
Danke for_ro
hier ist meine änderung , ich nehem jetzt eine byte variable und nutze die erste 3 bits , zum auswerten , leider kein erfolg , das mit den pullup ist nicht gewollt :-) , danke.
hier ist meine änderung am isr_int , ich hoffe das du es so gemeint hast
Isr_int:
Pin_b.0 = Pinb.0
Pin_b.1 = Pinb.1
Pin_b.2 = Pinb.2
If Pin_b = &B00000110 Then
Incr Master
End If
If Pin_b = &B00000101 Then
Incr Slave_rechts
End If
If Pin_b = &B00000011 Then
Incr Slave_links
End If
If Pin_b = &B00000100 Then
Incr Master
Incr Slave_rechts
End If
If Pin_b = &B00000001 Then
Incr Slave_links
Incr Slave_rechts
End If
If Pin_b = &B00000010 Then
Incr Slave_links
Incr Master
End If
If Pin_b = &B00000000 Then
Incr Master
Incr Slave_links
Incr Slave_rechts
End If
Return

Carlos31
29.05.2010, 16:36
Jetzt hab ich es gelöst denke ich , jetzt hab ich jedesmal eine bit variable das gesetzt wird wenn der pin o war und die wird wieder 0 wenn der pin wieder auf 1 war, jetzt von 1000 impulse werden 2 oder 3 geschluckt, muss ich glücklich damit werden ? oder kann ich es noch besser machen ?
Isr_int:
If Master_bit = 1 Then
Master_bit1 = 0
End If
If Master_bit1 = 0 Then
If Master_bit = 0 Then
Incr Master
Master_bit1 = 1
End If
End If
If Slave_r = 1 Then
Slave_r1 = 0
End If
If Slave_r1 = 0 Then
If Slave_r = 0 Then
Incr Slave_rechts
Slave_r1 = 1
End If
End If
If Slave_l = 1 Then
Slave_l1 = 0
End If
If Slave_l1 = 0 Then
If Slave_l = 0 Then
Incr Slave_links
Slave_l1 = 1
End If
End If
Return

for_ro
29.05.2010, 16:36
Ich denke, dass macht wirklich keinen Unterschied.
Ich meinte das so (pseudo code):

Isr_int:
Pinb_neu=pinB
if pinB_neu.0 = 0 And Pinb_alt.0 = 1 Then
Incr Master
End If
... 'das gleiche für die anderen
PinB_alt=PinB_neu
Return

Carlos31
29.05.2010, 16:47
ups wir haben in die gleiche minute geschrieben denke ich for_ro
schau mal bitte mein meine antwort davor , ich hab immer noch ganz kleine unterschiede bei der zählerstände , kann ich da noch was optimieren ?