Enterprise
03.03.2010, 22:12
Hallo zusammen,
ich möchte über I2C Daten auslesen und senden.
1. von einem Srf08 Ausgabe auf dem Uart RS232
2. von einem Slave Atmel8 ohne Quartz
3. Display LCD03
Mit dem Script vom Master kann ich den Srf08 auslesen.
Nun habe ich das Script von RN Wissen für Slave genommen.
Beim Slave soll eine LED Blinken, im selben Rhythmus wie die LED bei Master.
Das macht es nicht.
Beim Slave blinkt die LED schneller.
Wenn das dann funktioniert möchte ich noch Tasten und Schalter auslesen.
Diese sollte erst später besprochen werden.
Die Displayansteuerung ist nicht implementiert.
Das zweite Problem ist wenn der Slave angesteckt wird, dann misst der Srf08 nicht mehr.
Hier mein Master Script:
$crystal = 16000000
'$crystal = 3868000
$regfile = "m8def.dat"
$baud = 9600
Declare Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
Declare Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
Declare Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
Declare Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
Declare Sub Addieren
Declare Sub Subtrahieren
Config Portb = Output
Config Scl = Portc.5
Config Sda = Portc.4
Portc.1 = 1 'Taster Addieren
Portc.2 = 1 'Taster Subtrahieren
Const Adr_ta1_w = 6
Const Adr_modul_led_w = &H40 'Slave Adresse LED schreiben
Const Adr_modul_led_r = &H41 'Slave Adresse LED lesen
Const Displ_w = 198 'Display Adresse zum Schreiben
Const Displ_r = 199
Led Alias Portb.5
Dim Text As String * 20 'hier kommt der Anzeige-Text rein
Dim Stemp As String * 20
Dim B As Byte 'Variable zur Bestimmung der Textlänge
Dim C As Byte 'Hilfsvariable für FOR Schleife
Dim D As Byte 'D-Position auf dem Display
Dim E As Byte 'E-Position auf dem Display
Dim F As Byte 'Zählvariable für die Leuchtdauer des Displays
Dim G As Byte 'Zählvariable auf 1Sekunde für die Ausgabe Srf08
Dim Wert1 As Byte 'Wert1
Dim Wertled1 As Byte 'WertLed1
Dim Entfernung As Integer 'Srf08 Entfernung
Dim V As Byte 'Srf08 Verstärkung
Dim Tasblo(10) As Byte
Dim Ledgr As Byte 'LEDgr zum Slave Senden
Print
Print "I2C-Mastermodul von Enterprise V1.1"
Print
Wait 3 'Warte 3 Sekunden
I2cinit
Print " "
Print "SRF 08 Firmware Version: " ; Srf08_firmware(&He2)
Print " "
Srf08_reichweite &HE2 , 1000 'Reichweite in Zentimetern festlegen
' Verstärkungsfaktor ändern
' Srf08_verstaerkung &HE2 , 10 'Verstärkungsfaktor
V = 1
G = 1
Wert1 = 1
Wertled1 = 1
'************************************************* ******************************
'------------------- Hauptschleife ----------------------
Do
Waitms 100
Toggle Led ' LED Rot blinkt alle 100ms
Toggle Wertled1 ' Der Wert1 ändert alle 100ms von 1 auf 254
Gosub Slaveled1
' Srf08
If G = 10 Then
Entfernung = Srf08_entfernung(&He2)
Srf08_verstaerkung &HE2 , V 'Verstärkungsfaktor
Print "Verstaerkung: " ; V ; " " ; "Entfernung: " ; Entfernung ; " cm"
' V = V + 3
G = 1
Else
G = G + 1
End If
Loop
End
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'************************************************* ******************************
'------------------------ Slave LED senden 1 ---------------------
Slaveled1:
I2cstart
I2cwbyte Adr_modul_led_w
I2cwbyte 0
I2cwbyte Wertled1
I2cstop
Return
'-----------------------------------------------------------------
'-------------- SRF08 --------------------------------------------
'-----------------------------------------------------------------
Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Local Firmware As Byte
Local Temp As Byte
Local Srf08_slaveid_read As Byte
Srf08_slaveid_read = Srf08_slaveid + 1
'Messvorgang in starten
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 0
I2cwbyte 81 'In Zentimetern Messen
I2cstop
Warteaufmessung:
Waitms 1
Firmware = Srf08_firmware(&He2)
If Firmware = 255 Then Goto Warteaufmessung
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop
I2cstart
I2cwbyte Srf08_slaveid_read
I2crbyte Hib , Ack
I2crbyte Lob , Nack
I2cstop
Srf08_entfernung = Makeint(lob , Hib)
End Function
'Messreichweite in cm festlegen
Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
Local Wert As Word
Local Temp As Byte
Wert = Reichweite / 4 'Ungefähre Registerberechnung
Temp = Low(wert)
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 2 'Register
I2cwbyte Temp
I2cstop
End Sub
'Verstärung festlegen
Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 1 'Register
I2cwbyte Srf08_verstaerkung
I2cstop
End Sub
Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
Local Firmware As Byte
Local Srf08_slaveid_read As Byte
Srf08_slaveid_read = Srf08_slaveid + 1
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 0 'Leseregister festlegen
I2cstop
I2cstart
I2cwbyte Srf08_slaveid_read
I2crbyte Firmware , Nack
I2cstop
Srf08_firmware = Firmware
End Function
Und hier das Slave Script:
$regfile = "m8def.dat" ' the used chip
'$crystal = 7372800 ' frequency used
'$baud = 9600 ' keine baud rate angeben !
Config Portd = Output ' kompletter PortD als Ausgang
Dim Twi_control As Byte ' Controlregister lokale kopie
Dim Twi_status As Byte
Dim Twi_data As Byte
Dim Neuesbyte As Byte ' Bytemerker
Declare Sub Twi_init_slave
Twi_data = 0
Call Twi_init_slave ' TWI aktivieren
' alle LEDs ein
Portd = 0
' Hauptschleife
Do
' hier könnte ihr Code stehen
' Merker zurücksetzen
Neuesbyte = 0
' schauen ob TWINT gesetzt ist
Twi_control = Twcr And &H80 ' Bit7 von Controlregister
If Twi_control = &H80 Then
Twi_status = Twsr And &HF8 ' Status
' wurde ein Byte geschickt
If Twi_status = &H80 Or Twi_status = &H88 Then
Twi_data = Twdr ' neue Daten merken
Neuesbyte = 1 ' merken das ein neues Byte da ist
End If
' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
' wenn ein neues Byte gekommen ist, dieses an PortD ausgeben
If Neuesbyte <> 0 Then
' Portd = Twi_data ' Daten auf PortD ausgeben
Print
If Twi_data = 254 Then
Portd.0 = 0
End If
End If
Loop
End
' Unterprogramme
' TWI als slave aktivieren
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H40 ' Slaveadresse setzen
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
End Sub
Kann mir da jemand weiter helfen.
mfg
Enterprise
ich möchte über I2C Daten auslesen und senden.
1. von einem Srf08 Ausgabe auf dem Uart RS232
2. von einem Slave Atmel8 ohne Quartz
3. Display LCD03
Mit dem Script vom Master kann ich den Srf08 auslesen.
Nun habe ich das Script von RN Wissen für Slave genommen.
Beim Slave soll eine LED Blinken, im selben Rhythmus wie die LED bei Master.
Das macht es nicht.
Beim Slave blinkt die LED schneller.
Wenn das dann funktioniert möchte ich noch Tasten und Schalter auslesen.
Diese sollte erst später besprochen werden.
Die Displayansteuerung ist nicht implementiert.
Das zweite Problem ist wenn der Slave angesteckt wird, dann misst der Srf08 nicht mehr.
Hier mein Master Script:
$crystal = 16000000
'$crystal = 3868000
$regfile = "m8def.dat"
$baud = 9600
Declare Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
Declare Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
Declare Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
Declare Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
Declare Sub Addieren
Declare Sub Subtrahieren
Config Portb = Output
Config Scl = Portc.5
Config Sda = Portc.4
Portc.1 = 1 'Taster Addieren
Portc.2 = 1 'Taster Subtrahieren
Const Adr_ta1_w = 6
Const Adr_modul_led_w = &H40 'Slave Adresse LED schreiben
Const Adr_modul_led_r = &H41 'Slave Adresse LED lesen
Const Displ_w = 198 'Display Adresse zum Schreiben
Const Displ_r = 199
Led Alias Portb.5
Dim Text As String * 20 'hier kommt der Anzeige-Text rein
Dim Stemp As String * 20
Dim B As Byte 'Variable zur Bestimmung der Textlänge
Dim C As Byte 'Hilfsvariable für FOR Schleife
Dim D As Byte 'D-Position auf dem Display
Dim E As Byte 'E-Position auf dem Display
Dim F As Byte 'Zählvariable für die Leuchtdauer des Displays
Dim G As Byte 'Zählvariable auf 1Sekunde für die Ausgabe Srf08
Dim Wert1 As Byte 'Wert1
Dim Wertled1 As Byte 'WertLed1
Dim Entfernung As Integer 'Srf08 Entfernung
Dim V As Byte 'Srf08 Verstärkung
Dim Tasblo(10) As Byte
Dim Ledgr As Byte 'LEDgr zum Slave Senden
Print "I2C-Mastermodul von Enterprise V1.1"
Wait 3 'Warte 3 Sekunden
I2cinit
Print " "
Print "SRF 08 Firmware Version: " ; Srf08_firmware(&He2)
Print " "
Srf08_reichweite &HE2 , 1000 'Reichweite in Zentimetern festlegen
' Verstärkungsfaktor ändern
' Srf08_verstaerkung &HE2 , 10 'Verstärkungsfaktor
V = 1
G = 1
Wert1 = 1
Wertled1 = 1
'************************************************* ******************************
'------------------- Hauptschleife ----------------------
Do
Waitms 100
Toggle Led ' LED Rot blinkt alle 100ms
Toggle Wertled1 ' Der Wert1 ändert alle 100ms von 1 auf 254
Gosub Slaveled1
' Srf08
If G = 10 Then
Entfernung = Srf08_entfernung(&He2)
Srf08_verstaerkung &HE2 , V 'Verstärkungsfaktor
Print "Verstaerkung: " ; V ; " " ; "Entfernung: " ; Entfernung ; " cm"
' V = V + 3
G = 1
Else
G = G + 1
End If
Loop
End
' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'************************************************* ******************************
'------------------------ Slave LED senden 1 ---------------------
Slaveled1:
I2cstart
I2cwbyte Adr_modul_led_w
I2cwbyte 0
I2cwbyte Wertled1
I2cstop
Return
'-----------------------------------------------------------------
'-------------- SRF08 --------------------------------------------
'-----------------------------------------------------------------
Function Srf08_entfernung(byval Srf08_slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Local Firmware As Byte
Local Temp As Byte
Local Srf08_slaveid_read As Byte
Srf08_slaveid_read = Srf08_slaveid + 1
'Messvorgang in starten
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 0
I2cwbyte 81 'In Zentimetern Messen
I2cstop
Warteaufmessung:
Waitms 1
Firmware = Srf08_firmware(&He2)
If Firmware = 255 Then Goto Warteaufmessung
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop
I2cstart
I2cwbyte Srf08_slaveid_read
I2crbyte Hib , Ack
I2crbyte Lob , Nack
I2cstop
Srf08_entfernung = Makeint(lob , Hib)
End Function
'Messreichweite in cm festlegen
Sub Srf08_reichweite(byval Srf08_slaveid As Byte , Byval Reichweite As Word)
Local Wert As Word
Local Temp As Byte
Wert = Reichweite / 4 'Ungefähre Registerberechnung
Temp = Low(wert)
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 2 'Register
I2cwbyte Temp
I2cstop
End Sub
'Verstärung festlegen
Sub Srf08_verstaerkung(byval Srf08_slaveid As Byte , Byval Srf08_verstaerkung As Byte)
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 1 'Register
I2cwbyte Srf08_verstaerkung
I2cstop
End Sub
Function Srf08_firmware(byval Srf08_slaveid As Byte) As Byte
Local Firmware As Byte
Local Srf08_slaveid_read As Byte
Srf08_slaveid_read = Srf08_slaveid + 1
I2cstart
I2cwbyte Srf08_slaveid
I2cwbyte 0 'Leseregister festlegen
I2cstop
I2cstart
I2cwbyte Srf08_slaveid_read
I2crbyte Firmware , Nack
I2cstop
Srf08_firmware = Firmware
End Function
Und hier das Slave Script:
$regfile = "m8def.dat" ' the used chip
'$crystal = 7372800 ' frequency used
'$baud = 9600 ' keine baud rate angeben !
Config Portd = Output ' kompletter PortD als Ausgang
Dim Twi_control As Byte ' Controlregister lokale kopie
Dim Twi_status As Byte
Dim Twi_data As Byte
Dim Neuesbyte As Byte ' Bytemerker
Declare Sub Twi_init_slave
Twi_data = 0
Call Twi_init_slave ' TWI aktivieren
' alle LEDs ein
Portd = 0
' Hauptschleife
Do
' hier könnte ihr Code stehen
' Merker zurücksetzen
Neuesbyte = 0
' schauen ob TWINT gesetzt ist
Twi_control = Twcr And &H80 ' Bit7 von Controlregister
If Twi_control = &H80 Then
Twi_status = Twsr And &HF8 ' Status
' wurde ein Byte geschickt
If Twi_status = &H80 Or Twi_status = &H88 Then
Twi_data = Twdr ' neue Daten merken
Neuesbyte = 1 ' merken das ein neues Byte da ist
End If
' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
' wenn ein neues Byte gekommen ist, dieses an PortD ausgeben
If Neuesbyte <> 0 Then
' Portd = Twi_data ' Daten auf PortD ausgeben
If Twi_data = 254 Then
Portd.0 = 0
End If
End If
Loop
End
' Unterprogramme
' TWI als slave aktivieren
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H40 ' Slaveadresse setzen
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
End Sub
Kann mir da jemand weiter helfen.
mfg
Enterprise