Murus
30.07.2007, 16:53
Hallihallo zusammen,
ich möchte bei einem Mega8 das hardwareseitige I2C-Interface benutzen.
Momentan läuft die Sache mit dem Software-I2C von Bascom. Dies möchte ich ändern und stattdessen den Code umschreiben, damit das AVR interne Modul verwendet wird.
Angesprochen wird ein Temperatursensor (DS1631Z)
Leider funktioniert die Hardware-Version nicht und ich weiss nicht wieso, hier die Codes:
Auszug aus dem funktionierenden Code:
' I2C initialisieren:
Config Scl = Portc.5 'Is serial clock SCL
Config Sda = Portc.4
Const Schreiben = &B10010000 ' Schreibadresse
Const Lesen = &B10010001 ' Leseadresse
.
.
.
' Thermometer soll Temperatur messen:
I2cstart
I2cwbyte Schreiben
I2cwbyte &H51 ' Befehl fürs Temperaturmessen schicken
I2cstop
Waitms 30
' Thermometer soll Temperatur an den AVR schicken:
I2cstart
I2cwbyte Schreiben
I2cwbyte &HAA 'Temperaturausgabe-Befehl schicken
I2cstart
I2cwbyte Lesen
I2crbyte Twidaten1 , Ack
I2crbyte Twidaten2 , Nack
I2cstop
Dieser Code funktioniert wunderbar, die beiden Bytes Twidaten1 und Twidaten2 enthalten dann die Temperatur des Thermometers. Die Routine zum Ansprechen des Temperatursensors stimmt auch, das klappt also.
Dieses Vorgehen möchte ich nun mit der Hardware-Lösung machen. Hier das momentane, leider nicht funktionale Listing:
'Das I2C-Interface initialisieren:
Twsr = &B00000000 ' Prescaler = 1
Twbr = 10 ' Frequenz des TWi: 10,4kHz
.
.
.
'Befehl zum Messen ausgeben:
Twcr = &B10100100 ' Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010000 ' Slave Adresse senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B1010001 ' Befehl zum Messen senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B10010100 ' Stop
Waitms 30
'Temperaturwert einlesen:
Twcr = &B10100100 ' Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010000 ' Slave Adresse senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10101010 ' Befehl senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B10100100 ' Erneut Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010001 ' Slave Adresse senden (lesen)
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B11000100 ' Ack erzeugen
Gosub Twiloopsub
Twidaten1 = Twdr
Twcr = &B10000100 ' Nack erzeugen
Gosub Twiloopsub
Twidaten2 = Twdr
Twcr = &B10010100 ' Stop
' Twidaten1/2 enthalten den Temperaturwert.
Twiloopsub:
Do : Loop Until Twcr.twint = 1 ' Dann ist TWI-Aktion beendet.
Return
Diese beiden Listings sollten genau das Gleiche machen, dem Sensor sagen, er soll messen und dann den Wert abrufen.
Nur klappt das mit der zweiten Variante gar nicht.
Twidaten1 enthält immer den Wert 196 und Twidaten2 den Wert 0. Eine Kommunikation zum Sensor findet also nicht statt.
Sieht jemand gerade eine Lösung für dieses Problem?
Herzlichen Gruss und vielen Dank
Mario
ich möchte bei einem Mega8 das hardwareseitige I2C-Interface benutzen.
Momentan läuft die Sache mit dem Software-I2C von Bascom. Dies möchte ich ändern und stattdessen den Code umschreiben, damit das AVR interne Modul verwendet wird.
Angesprochen wird ein Temperatursensor (DS1631Z)
Leider funktioniert die Hardware-Version nicht und ich weiss nicht wieso, hier die Codes:
Auszug aus dem funktionierenden Code:
' I2C initialisieren:
Config Scl = Portc.5 'Is serial clock SCL
Config Sda = Portc.4
Const Schreiben = &B10010000 ' Schreibadresse
Const Lesen = &B10010001 ' Leseadresse
.
.
.
' Thermometer soll Temperatur messen:
I2cstart
I2cwbyte Schreiben
I2cwbyte &H51 ' Befehl fürs Temperaturmessen schicken
I2cstop
Waitms 30
' Thermometer soll Temperatur an den AVR schicken:
I2cstart
I2cwbyte Schreiben
I2cwbyte &HAA 'Temperaturausgabe-Befehl schicken
I2cstart
I2cwbyte Lesen
I2crbyte Twidaten1 , Ack
I2crbyte Twidaten2 , Nack
I2cstop
Dieser Code funktioniert wunderbar, die beiden Bytes Twidaten1 und Twidaten2 enthalten dann die Temperatur des Thermometers. Die Routine zum Ansprechen des Temperatursensors stimmt auch, das klappt also.
Dieses Vorgehen möchte ich nun mit der Hardware-Lösung machen. Hier das momentane, leider nicht funktionale Listing:
'Das I2C-Interface initialisieren:
Twsr = &B00000000 ' Prescaler = 1
Twbr = 10 ' Frequenz des TWi: 10,4kHz
.
.
.
'Befehl zum Messen ausgeben:
Twcr = &B10100100 ' Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010000 ' Slave Adresse senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B1010001 ' Befehl zum Messen senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B10010100 ' Stop
Waitms 30
'Temperaturwert einlesen:
Twcr = &B10100100 ' Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010000 ' Slave Adresse senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10101010 ' Befehl senden
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B10100100 ' Erneut Start erzeugen
Gosub Twiloopsub ' Warten bis fertig
Twdr = &B10010001 ' Slave Adresse senden (lesen)
Twcr = &B10000100 ' Aktion auslösen
Gosub Twiloopsub ' Warten bis fertig
Twcr = &B11000100 ' Ack erzeugen
Gosub Twiloopsub
Twidaten1 = Twdr
Twcr = &B10000100 ' Nack erzeugen
Gosub Twiloopsub
Twidaten2 = Twdr
Twcr = &B10010100 ' Stop
' Twidaten1/2 enthalten den Temperaturwert.
Twiloopsub:
Do : Loop Until Twcr.twint = 1 ' Dann ist TWI-Aktion beendet.
Return
Diese beiden Listings sollten genau das Gleiche machen, dem Sensor sagen, er soll messen und dann den Wert abrufen.
Nur klappt das mit der zweiten Variante gar nicht.
Twidaten1 enthält immer den Wert 196 und Twidaten2 den Wert 0. Eine Kommunikation zum Sensor findet also nicht statt.
Sieht jemand gerade eine Lösung für dieses Problem?
Herzlichen Gruss und vielen Dank
Mario