Re: Dallas DS 1621 anschliessen und auslesen Kategorie: I²C-Bus (von Space_Wolfgang, http://www.strickling.net/astro.htm - 30.08.2008 8:57) | |
Als Antwort auf Re: Dallas DS 1621 anschliessen und auslesen von Thomas - 18.01.2007 14:02
| |
> Bei mir läuft das Programm nicht. Kann es sein, dass das nur für Mega32 ist und auf dem Mega128 garnicht läuft. > Andere fehler Quellen sind eigentlich auszuschliessen abgesehen von evtl. Programmier Fehlern. > > Thomas Bei mir läuft es auch nicht (Mega32 + Appl Board). Grund: Anscheinend irgendwelche Konflikte mit der Grundadresse des DS1621. Keine Probleme gibt's bei Verwendung einer anderen Geräteadresse. Au�erdem dauert die Datenkonversion laut Datenblatt im DS1621 zwischen 0.4 und 1 Sekunde. Solange muss man warten, bis die Temperatur nach einer Start_Conversion-Anweisung zur Verfügung steht. Au�erdem fehlt ein Errorhandler. Wenn der DS1621 nicht richtig antwortet oder gar nicht angeschlossen ist, kommt es zu einem fatalen Systemabsturz. Unten angehängt habe ich mal eine Reihe nützlicher I2C-Routinen und Routinen für den DS1621. Damit kann man den DS 1621 nicht nur mit 0.5 Grad Auflösung auslesen, sondern auch mit höherer Temperaturauflösung. Gru� Wolfgang ' ************************* DS1621.cbas ************************* Routinen für den DS1621 Temperatursensor ' DS1621 Konstanten #define DSAccess_TH &HA1 #define DSAccess_TL &HA2 #define DSAccessConfig &HAC #define DSRead_Counter &HA8 #define DSRead_Slope &HA9 #define DSRead_Temp &HAA #define DSStart_Convert &HEE #define DSStop_Convert &H22 #define DSSingle_Convert &H03 #define DSContin_Convert &H00 #define I2C_Read_Ack_OK &H50 #define I2C_Read_NAck_OK &H58 Sub DS1621Init(addr As Byte) I2C_Init(I2C_100kHz) SendI2CCommandByte (addr, DSAccessConfig, DSSingle_Convert) 'Comm WriteConfig Single Conversion AbsDelay (10) SendI2CCommand (addr, DSStart_Convert) 'Comm Start Conversion End Sub Sub ReadDS1621HR (addr As Byte) As Single Dim TempHR As Single Dim DSTemp, DSState As Byte Dim Count_Per_C, Count_Remain As Byte ' Wait Loop Until Conversion is done, Conversion time may take up to 1 s! Do AbsDelay (20) DSState = ReadI2CCommandByte (addr, DSAccessConfig) ' Read Stat Register If I2C_StatusCode <> I2C_Read_NAck_OK Then TempHR = -99.9 Goto ErrorExit End If Loop While (DSState And &H80) = 0 ' Loop Until Conversion is done DSTemp = ReadI2CCommandByte (addr, DSRead_Temp) ' Read MSB Temp Register Count_Remain = ReadI2CCommandByte (addr, DSRead_Counter) ' Read Counter Register Count_Per_C = ReadI2CCommandByte (addr, DSRead_Slope) ' Read Slope Register If DSTemp < &H80 Then TempHR = DSTemp Else TempHR = DSTemp -256.0 End If TempHR = TempHR -0.25 +((Count_Per_C -Count_Remain +0.0) /Count_Per_C) ' SendI2CCommand (addr, &HEE) 'Comm Start next Conversion Lab ErrorExit Return TempHR End Sub Sub ReadDS1621LR (addr As Byte) As Single 'reads Temperature in 0.5 deg steps, (low resolution mode), Error value = -99.9 Dim TempLR As Single Dim DSTemp As Word Dim DSState As Byte ' Wait Loop Until Conversion is done, Conversion time may take up to 1 s! Do AbsDelay (20) DSState = ReadI2CCommandByte (addr, DSAccessConfig) ' Read Stat Register If I2C_StatusCode <> I2C_Read_NAck_OK Then TempLR = -99.9 Goto ErrorExit End If Loop While (DSState And &H80) = 0 ' Loop Until Conversion is done DSTemp = ReadI2CCommandWord (addr, DSRead_Temp) ' Read Temp Register If I2C_StatusCode = I2C_Read_NAck_OK Then TempLR = DSTemp /256.0 If DSTemp >= &H8000 Then TempLR = TempLR -256 End If Else TempLR = -99.9 End If ' SendI2CCommand (addr, &HEE) 'Comm Start next Conversion Lab ErrorExit Return TempLR End Sub ' *************** I2C-Routinen *********************** ' Subs für I2C Protokoll Dim I2C_StatusCode As Byte ' globale Variable, zum Fehlercheck in Applikation #define I2C_Write_Ack_OK &H40 #define I2C_Write_NAck_OK &H48 #define I2C_Read_Ack_OK &H50 #define I2C_Read_NAck_OK &H58 Sub SendI2CCommand (addr As Byte, command As Byte) 'Sends 1-Byte-Command to Addr I2C_Start() I2C_Write(addr) I2C_Status() I2C_Write(command) I2C_StatusCode = I2C_Status() I2C_Stop() End Sub Sub SendI2CCommandByte (addr As Byte, command As Byte, data As Byte) 'Sends 1-Byte-Command and Byte to Addr I2C_Start() I2C_Write(addr) I2C_Status() I2C_Write(command) I2C_Write(data) I2C_StatusCode = I2C_Status() I2C_Stop() End Sub Sub SendI2CCommandWord (addr As Byte, command As Byte, data As Word) 'Sends 1-Byte-Command and Word to Addr I2C_Start() I2C_Write(addr) I2C_Status() I2C_Write(command) I2C_Status() I2C_Write(data>>8) I2C_Write(data And &HFF) I2C_StatusCode = I2C_Status() I2C_Stop() End Sub Sub ReadI2CCommandByte (addr As Byte, command As Byte) As Byte 'Sends 1-Byte-Command to and reads Byte from Addr Dim Data As Byte I2C_Start() I2C_Write(addr) I2C_StatusCode = I2C_Status() I2C_Write(command) I2C_Start() I2C_Write(addr+1) I2C_StatusCode = I2C_Status() If I2C_Status() = I2C_Write_Ack_OK Then Data = I2C_Read_NACK() I2C_StatusCode = I2C_Status() 'should be I2C_Read_NAck_OK &H58 Else Data = 0 End If I2C_Stop() Return Data End Sub Sub ReadI2CCommandWord (addr As Byte, command As Byte) As Word 'Sends 1-Byte-Command and Word to Addr Dim MSB, LSB, Status As Byte I2C_Stop() AbsDelay (10) I2C_Start() I2C_Write(addr) I2C_Write(command) I2C_Start() I2C_Write(addr+1) I2C_StatusCode = I2C_Status() If I2C_Status() = I2C_Write_Ack_OK Then MSB = I2C_Read_ACK() LSB = I2C_Read_NACK() I2C_StatusCode = I2C_Status() Else MSB = 0 LSB = 0 End If I2C_Stop() Return MSB *256 + LSB End Sub Meine Seite: http://www.strickling.net/astro.htm | |
Antwort schreiben Antworten: |
Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum