PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : subrutine behindert I2C



chaoscrack
18.11.2007, 01:13
Hallo zusammen

Mit dem folgenden Code möchte ich 2 Motoren ansteuern.

If Entfernung < 100 Then
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1

Portb.0 = 1
Portb.1 = 0
Portd.5 = 1
Else
Portc.6 = 0
Portc.7 = 1
Portd.4 = 1

Portb.0 = 0
Portb.1 = 1
Portd.5 = 1
End If
Es funktioniert so auch einwandfrei. Wenn ich die Else-Anweisung jedoch in eine Sub-Routine stecke und aufrufe behindere ich den I2C. Genauer gesagt wird die I2C Sensorabfrage erst nach mehreren Dutzend Sekunden ausgelöst und dann noch nicht einmal kontinuierlich wie mit dem alten Code.

Hier der Code mit der Sub-Routine:
If Entfernung < 100 Then
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1

Portb.0 = 1
Portb.1 = 0
Portd.5 = 1
Else
Call Fahren()
End If

Loop
End

Sub Fahren()
Portc.6 = 0
Portc.7 = 1
Portd.4 = 1

Portb.0 = 0
Portb.1 = 1
Portd.5 = 1
End Sub

Woran liegt das?


Danke für eure Hilfe

PicNick
18.11.2007, 09:37
Behaupte, aus dem gezeigten Code läßt sich das nicht erklären. Natürlich braucht ein "Call" einige Zyklen mehr, aber das kann's wohl nicht sein.

Man müßte über deine I2C-Routinen mehr wissen, und ob das HW oder SW-Funktionen sind.

chaoscrack
18.11.2007, 10:07
Danke für die Antwort.

Geren poste ich den kompletten Code:
Declare Function Tastenabfrage() As Byte
Declare Function Wegmessunglesen(byval Slaveid As Byte) As Integer
Declare Sub Wegmessungstart()
Declare Sub Batteriespannung()
Declare Sub Drehen()
Declare Sub Fahren()

$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 64

$crystal = 16000000 'Quarzfrequenz
$baud = 38400

'********** I2C initialisierung **********
Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1
I2cinit

'********** A/D Wandler initialisierung **********
Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung
Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1
Start Adc

'********** Variablendeklaration **********
Dim Taste As Byte
Dim Ton As Integer
Dim Volt As Single
Dim Flag_akku As Bit
Dim Flag_lcd_toggle As Bit
Dim Timerx3 As Integer
Dim Entfernung As Integer
Dim Timer_weg As Long
Dim Flag_weg As Integer
Dim Test As Integer

'********** Konstantendeklaration **********
Const Ref = 5 / 1023 'Für Batteriespannungsberechnung
Const Srf02_slaveid = &HE0 'Standard I2C Adresse von SRF02

'********** Timercofig **********
Config Timer0 = Timer , Prescale = 1024 'Konfiguriere Timer1
Enable Timer0 'schalte Den Timer1 ein
On Timer0 Isr_von_timer0 'verzweige Bei Timer1 überlauf Zu Isr_von_timer1

'********** Motorenconfig **********
Config Pinc.6 = Output
Config Pinc.7 = Output
Config Pind.4 = Output
Config Pinb.0 = Output
Config Pinb.1 = Output
Config Pind.5 = Output

'********** Start LCD config **********
Config Pinc.2 = Output
Config Pinc.4 = Output
Lcdpower Alias Portc.2
Lcd_rw Alias Portc.4
Lcd_rw = 0
Lcdpower = 0

Wait 1

Config Lcd = 20 * 4a , Chipset = Ks077
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Portc.3 , Rs = Portc.5
Config Lcdbus = 4

Initlcd
'********** Ende LCD config **********

Enable Interrupts

Cls
Locate 2 , 8
Lcd "Bereit"

'********** Initialisierung abgeschlossen **********
Sound Portd.7 , 400 , 450 'BEEP
Sound Portd.7 , 400 , 250 'BEEP
Sound Portd.7 , 400 , 450 'BEEP


'********** Programme **********

Do
If Flag_akku = 1 Then
Call Batteriespannung()
If Volt <= 9 Then
Lcdpower = 0
Flag_lcd_toggle = 1
Locate 2 , 3
Lcd "Akkus wechseln"
Else
Flag_lcd_toggle = 0
End If
Flag_akku = 0
End If


If Timer_weg > 10000 Then
Entfernung = Wegmessunglesen(srf02_slaveid)
Locate 4 , 1
Lcd "Entfernung:" ; Entfernung ; "cm"
Call Wegmessungstart()
Timer_weg = 0
Else
Incr Timer_weg
End If


If Entfernung < 100 Then
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1

Portb.0 = 1
Portb.1 = 0
Portd.5 = 1
Else
Portc.6 = 0
Portc.7 = 1
Portd.4 = 1

Portb.0 = 0
Portb.1 = 1
Portd.5 = 1
End If

Loop

End




Isr_von_timer0: 'isr Von Timer0
Incr Timerx3
If Timerx3 >= 5000 Then 'Timer0 verlangsamen
Flag_akku = 1 'Batteriespannung überprüfen
Timerx3 = 0
End If
If Flag_lcd_toggle = 1 Then 'LCD toggeln (wanrhinweis)
Toggle Lcdpower
End If
Return

Sub Drehen()
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1

Portb.0 = 1
Portb.1 = 0
Portd.5 = 1

End Sub

Sub Fahren()
Portc.6 = 1
Portc.7 = 0
Portd.4 = 1

Portb.0 = 1
Portb.1 = 0
Portd.5 = 1

End Sub

Sub Wegmessungstart()
I2cstart
I2cwbyte Srf02_slaveid
I2cwbyte 0
I2cwbyte 81 'in Zentimetern messen
I2cstop
End Sub

Function Wegmessunglesen(byval Slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Local Slaveid_read As Byte

Slaveid_read = Slaveid + 1

I2cstart
I2cwbyte Slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop


I2cstart
I2cwbyte Slaveid_read
I2crbyte Hib , Ack
I2crbyte Lob , Nack
I2cstop


Wegmessunglesen = Makeint(lob , Hib)
End Function

Sub Batteriespannung()
Local W As Word
Local T As String * 10
Cls
Start Adc
W = Getadc(6)
Volt = W * Ref
Volt = Volt * 5.236
T = Fusing(volt , "0.00")
Locate 1 , 3
Lcd "Akku: " ; T ; " Volt"
End Sub

PicNick
19.11.2007, 09:15
Moin !

Ich schau mir das noch genauer an.
Doch eines solltest du probieren:
SWSTACK ist mir 32 Byte etwas knapp. Schreib doch einfach mal =256, du hast den SRAM ja wohl bezahlt, also was soll's