sechsrad
16.01.2008, 09:18
ich habe hier 2 twi-routinen aud diesem forum. twi-master und twi-slave. beide können senden umd empfangen.
dieses funktoniert auch tadellos.
nun möchte ich auch damit ein kompassmodul cmps03 auslesen. für dieses unterfangen fehlen mir die fachkenntnisse.
das cmps-modul ist so geschaltet das es mit den i2c-befehlen von bascom funktioniert.
nun möchte ich es mit den unteren routinen machen.
das modul hat die adresse : &HC0
so sieht die routine in bascom aus:
Cmps_slaveid = &HC0
Cmps_slaveid_read = Cmps_slaveid + 1
'Register auswählen
I2cstart
I2cwbyte Cmps_slaveid
I2cwbyte 2
I2cstop
I2cstart
I2cwbyte Cmps_slaveid_read
I2crbyte Hi-byte , Ack
I2crbyte Lo-byte , Nack
I2cstop
dieses sind die selbstgestrickten routinen !
master-send-empfang :
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200
Declare Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
Declare Function Twi_read_byte(byval Slave As Byte) As Byte
Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte
Enable Interrupts
Twcr = &B00000100 ' erstmal nur TWI aktivieren
Twsr = 0 ' Status und Prescaler Register
Twbr = 72 ' Bit Rate Register, 100kHz
Waitms 500
Twi_data_se = 145
Do
Call Twi_send_byte(&H50 , Twi_data_se)
Waitms 250
Twi_data_em = Twi_read_byte(&H50)
Waitms 250
Print Twi_data_em
Loop
End
Function Twi_read_byte(byval Slave As Byte) As Byte
Twi_read_byte = 0 ' Wert vorbelegen
' Startbedingung
Twcr = &B10100100 ' TWINT
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave Or &H01 ' slave adresse + Read
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' Slave hat sich gemeldet
If Twi_status = &H40 Then
Twcr = &B10000100 ' TWINT löschen, Byte senden
Gosub Twi_wait_int
' ein Byte wurde empfangen
If Twi_status = &H58 Or Twi_status = &H50 Then
Twi_read_byte = Twdr ' Daten lesen
End If
End If
Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
End If
End Function
Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
' Startbedingung
Twcr = &B10100100 ' TWINT
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave And &HFE ' slave adresse + Write
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' Slave hat sich gemeldet
If Twi_status = &H18 Or Twi_status = &H20 Then
Twdr = Zeichen ' Daten
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
End If
Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
End If
End Sub
Twi_wait_int:
Do
Twi_control = Twcr And &H80
Loop Until Twi_control = &H80
Twi_status = Twsr And &HF8
Return
slave-empfang-send :
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
Config Lcd = 20 * 2
Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte
Declare Sub Twi_sla_se_em()
Declare Sub Twi_init_slave()
Enable Interrupts
Twi_data_em = 0
Twi_data_se = 77
Call Twi_init_slave
Cls
Do
Waitms 300
Call Twi_sla_se_em()
Cls
Lcd Twi_data_em
Loop
End
Sub Twi_sla_se_em()
' 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_em = Twdr ' neue Daten merken
End If
' will der Master ein Byte haben
If Twi_status = &HA8 Or Twi_status = &HB8 Then
Twdr = Twi_data_se ' neue Daten ausgeben
End If
' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
End Sub
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H50 ' Slaveadresse setzen
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
End Sub
dieses funktoniert auch tadellos.
nun möchte ich auch damit ein kompassmodul cmps03 auslesen. für dieses unterfangen fehlen mir die fachkenntnisse.
das cmps-modul ist so geschaltet das es mit den i2c-befehlen von bascom funktioniert.
nun möchte ich es mit den unteren routinen machen.
das modul hat die adresse : &HC0
so sieht die routine in bascom aus:
Cmps_slaveid = &HC0
Cmps_slaveid_read = Cmps_slaveid + 1
'Register auswählen
I2cstart
I2cwbyte Cmps_slaveid
I2cwbyte 2
I2cstop
I2cstart
I2cwbyte Cmps_slaveid_read
I2crbyte Hi-byte , Ack
I2crbyte Lo-byte , Nack
I2cstop
dieses sind die selbstgestrickten routinen !
master-send-empfang :
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200
Declare Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
Declare Function Twi_read_byte(byval Slave As Byte) As Byte
Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte
Enable Interrupts
Twcr = &B00000100 ' erstmal nur TWI aktivieren
Twsr = 0 ' Status und Prescaler Register
Twbr = 72 ' Bit Rate Register, 100kHz
Waitms 500
Twi_data_se = 145
Do
Call Twi_send_byte(&H50 , Twi_data_se)
Waitms 250
Twi_data_em = Twi_read_byte(&H50)
Waitms 250
Print Twi_data_em
Loop
End
Function Twi_read_byte(byval Slave As Byte) As Byte
Twi_read_byte = 0 ' Wert vorbelegen
' Startbedingung
Twcr = &B10100100 ' TWINT
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave Or &H01 ' slave adresse + Read
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' Slave hat sich gemeldet
If Twi_status = &H40 Then
Twcr = &B10000100 ' TWINT löschen, Byte senden
Gosub Twi_wait_int
' ein Byte wurde empfangen
If Twi_status = &H58 Or Twi_status = &H50 Then
Twi_read_byte = Twdr ' Daten lesen
End If
End If
Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
End If
End Function
Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
' Startbedingung
Twcr = &B10100100 ' TWINT
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave And &HFE ' slave adresse + Write
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
' Slave hat sich gemeldet
If Twi_status = &H18 Or Twi_status = &H20 Then
Twdr = Zeichen ' Daten
Twcr = &B10000100 ' TWINT löschen, Byte senden
' warten bis TWINT gesetzt ist
Gosub Twi_wait_int
End If
Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
End If
End Sub
Twi_wait_int:
Do
Twi_control = Twcr And &H80
Loop Until Twi_control = &H80
Twi_status = Twsr And &HF8
Return
slave-empfang-send :
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 32
$framesize = 64
$baud = 19200
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.6 , Rs = Portc.7
Config Lcd = 20 * 2
Dim Twi_control As Byte
Dim Twi_status As Byte
Dim Twi_data_em As Byte
Dim Twi_data_se As Byte
Declare Sub Twi_sla_se_em()
Declare Sub Twi_init_slave()
Enable Interrupts
Twi_data_em = 0
Twi_data_se = 77
Call Twi_init_slave
Cls
Do
Waitms 300
Call Twi_sla_se_em()
Cls
Lcd Twi_data_em
Loop
End
Sub Twi_sla_se_em()
' 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_em = Twdr ' neue Daten merken
End If
' will der Master ein Byte haben
If Twi_status = &HA8 Or Twi_status = &HB8 Then
Twdr = Twi_data_se ' neue Daten ausgeben
End If
' TWINT muss immer gelöscht werden, damit es auf dem Bus weiter geht
Twcr = &B11000100 ' TWINT löschen, erzeugt ACK
End If
End Sub
Sub Twi_init_slave
Twsr = 0 ' status und Prescaler auf 0
Twdr = &HFF ' default
Twar = &H50 ' Slaveadresse setzen
Twcr = &B01000100 ' TWI aktivieren, ACK einschalten
End Sub