I got a VB6 source code that reads correctly the temperature and when I translated into PB code, my return value is not correct.
Here are the functions in VB6 :
Code: Select all
Option Explicit
Dim MSComm1 As Object
Public Function open_iic_bus(serial_port As Object) As Integer
Set MSComm1 = serial_port
If Not MSComm1.PortOpen Then
MSComm1.PortOpen = True
MSComm1.RTSEnable = True
MSComm1.DTREnable = True
End If
open_iic_bus = NO_ERROR
Exit Function
End Function
Public Sub close_iic_bus()
If MSComm1.PortOpen Then
MSComm1.PortOpen = False
End If
End Sub
Public Sub IIC_start()
SDA_output
SDA_high
SCL_high
SDA_low
End Sub
Public Sub IIC_stop()
SDA_output
SDA_low
SCL_high
SDA_high
End Sub
Public Function IIC_tx_byte(ByVal B As Long) As Integer
Dim i As Integer
For i = 0 To 7
If (B And &H80) Then
IIC_tx_bit_1
Else
IIC_tx_bit_0
End If
B = B * 2
Next
IIC_tx_byte = IIC_rx_bit
End Function
Public Function IIC_rx_byte(ByVal acknowledge As Integer) As Integer
Dim i As Integer
Dim retval As Integer
For i = 0 To 7
retval = retval * 2
If IIC_rx_bit() Then
retval = retval + 1
End If
Next
If acknowledge Then
IIC_tx_bit_0
Else
IIC_tx_bit_1
End If
IIC_rx_byte = retval
End Function
Private Sub IIC_tx_bit_1()
SCL_low
SDA_output
SDA_high
SCL_high
SCL_low
End Sub
Private Sub IIC_tx_bit_0()
SCL_low
SDA_output
SDA_low
SCL_high
SCL_low
End Sub
Private Function IIC_rx_bit() As Integer
Dim retval As Integer
SDA_input
SCL_low
SCL_high
retval = SDA_value()
SCL_low
IIC_rx_bit = retval
End Function
Private Sub SDA_output()
'there is no real difference between SDA_output
'and SDA_input, because we have two unidirectional
'lines instead of a single bidirectional one
'This call is left here for compatibility with
'other hardware implementations
MSComm1.DTREnable = True
End Sub
Private Sub SDA_input()
'since DATA is open-collector, putting DTR high sets it as PC input
MSComm1.DTREnable = True
End Sub
Private Sub SCL_high()
MSComm1.RTSEnable = True
iic_wait
End Sub
Private Sub SCL_low()
MSComm1.RTSEnable = False
iic_wait
End Sub
Private Sub SDA_high()
MSComm1.DTREnable = True
iic_wait
End Sub
Private Sub SDA_low()
MSComm1.DTREnable = False
iic_wait
End Sub
Private Function SDA_value() As Integer
SDA_value = MSComm1.CTSHolding
End Function
Private Sub iic_wait()
'void , insert here wait code for very fast systems
'actual measured speed is 1,5 kbps on a P90...
End Sub
Code: Select all
Private Function temperature(ByVal address As Integer) As Double
Dim temperature_int As Long
Dim temperature_frac As Long
'For I2C bus communication, addresses are shifted one place to left,
'as the least significant bit is used for the R/W flag.
'In binary, shifting to left is equivalent to multiplying by two
address = address * 2
On Error GoTo errors
open_iic_bus MSComm1.object
'an extra stop doesn't hurt...and ensures we start from a clean bus condition
IIC_stop
'read sequence, as per DS1621 datasheet
IIC_start 'Bus Master initiates a START condition.
IIC_tx_byte address 'Bus Master sends DS1621 address; R/ W= 0 (DS1621 generates acknowledge bit).
IIC_tx_byte &H22 'Bus Master sends Access Config command protocol.DS1621 generates acknowledge bit.
IIC_stop
IIC_start 'Bus Master initiates a START condition.
IIC_tx_byte address 'Bus Master sends DS1621 address; R/ W= 0 (DS1621 generates acknowledge bit).
IIC_tx_byte &HAC 'Bus Master sends Access Config command protocol.DS1621 generates acknowledge bit.
IIC_tx_byte (12)
IIC_stop 'DS1621 generates acknowledge bit.
IIC_start 'Bus Master generates a repeated START condition.
IIC_tx_byte address 'Bus Master sends DS1621 address; R/ W= 0.DS1621 generates acknowledge bit.
IIC_tx_byte &H51 'Bus Master sends Start Convert T command protocol.DS1621 generates acknowledge bit.
IIC_stop 'Bus Master initiates STOP condition.
IIC_start 'Bus Master initiates a START condition.
IIC_tx_byte address 'Bus Master sends DS1621 address; R/ W= 0 (DS1621 generates acknowledge bit).
IIC_tx_byte &HAA 'Bus Master sends Read Temperature command protocol.DS1621 generates acknowledge bit.
IIC_start 'Bus Master generates a repeated START condition.
IIC_tx_byte address + 1 'Bus Master sends DS1621 address; R/ W= 1 = READING (DS1621 generates acknowledge bit).
temperature_int = IIC_rx_byte(1) 'Bus Master receives first byte of data and generates acknowledge.
temperature_frac = IIC_rx_byte(1) 'Bus Master receives second byte of data from DS162 and does not generate acknowledge to signal end of reception.
IIC_stop 'Bus Master initiates STOP condition.
'some bynary math to convert to a data format Visual Basic can understand
temperature = (temperature_int * 256 + temperature_frac) / 128 * 5 / 10
If temperature_int >= 128 Then
temperature = temperature - 256
End If
Exit Function
errors:
temperature = ERROR_TEMPERATURE_NOT_READ
End Function
Code: Select all
;Procedure SDA_Value()
Procedure.i open_iic_bus()
comport.s = "COM1"
OpenSerialPort(0, comport, 9600, #PB_SerialPort_NoParity, 7, 1, #PB_SerialPort_RtsCtsHandshake, 1024, 1024)
EndProcedure
Procedure close_iic_bus()
CloseSerialPort(0)
EndProcedure
Procedure iic_wait()
EndProcedure
Procedure SDA_value()
sda_value = GetSerialPortStatus(0, #PB_SerialPort_CTS)
ProcedureReturn sda_value
EndProcedure
Procedure SDA_low()
SetSerialPortStatus(0, #PB_SerialPort_DTR, 0)
EndProcedure
Procedure SDA_high()
SetSerialPortStatus(0, #PB_SerialPort_DTR, 1)
EndProcedure
Procedure SCL_low()
SetSerialPortStatus(0, #PB_SerialPort_RTS, 0)
EndProcedure
Procedure SCL_high()
SetSerialPortStatus(0, #PB_SerialPort_RTS, 1)
EndProcedure
Procedure SDA_input()
SetSerialPortStatus(0, #PB_SerialPort_DTR, 1)
EndProcedure
Procedure SDA_output()
SetSerialPortStatus(0, #PB_SerialPort_DTR, 1)
EndProcedure
Procedure IIC_rx_bit()
SDA_input()
SCL_low()
SCL_high()
retval = SDA_value()
SCL_low()
IIC_rx_bit = retval
ProcedureReturn IIC_rx_bit
EndProcedure
Procedure IIC_tx_bit_0()
SCL_low()
SDA_output()
SDA_low()
SCL_high()
SCL_low()
EndProcedure
Procedure IIC_tx_bit_1()
SCL_low()
SDA_output()
SDA_high()
SCL_high()
SCL_low()
EndProcedure
Procedure IIC_rx_byte(acknowledge.l)
For i=0 To 7
retval = retval * 2
If IIC_rx_bit()
retval = retval + 1
EndIf
Next i
If acknowledge
IIC_tx_bit_0()
Else
IIC_tx_bit_1()
EndIf
IIC_rx_byte = retval
ProcedureReturn IIC_rx_byte
EndProcedure
Procedure IIC_tx_byte(B.l)
For i=0 To 7
If B And $80
IIC_tx_bit_1()
Else
IIC_tx_bit_0()
EndIf
B = B * 2
Next i
IIC_tx_byte = IIC_rx_bit
ProcedureReturn IIC_tx_byte
EndProcedure
Procedure IIC_stop()
SDA_output()
SDA_low()
SCL_high()
SDA_high()
EndProcedure
Procedure IIC_start()
SDA_output()
SDA_high()
SCL_high()
SDA_low()
EndProcedure
Procedure.d temperature(adress.l)
adress = adress * 2
; Debug adress
open_iic_bus()
IIC_stop()
IIC_start()
IIC_tx_byte(adress)
IIC_tx_byte($22)
IIC_stop()
IIC_start()
IIC_tx_byte(adress)
IIC_tx_byte($AC)
IIC_tx_byte($C)
IIC_stop()
IIC_start()
IIC_tx_byte(adress)
IIC_tx_byte($51)
IIC_stop()
Delay(1000)
IIC_start()
IIC_tx_byte(adress)
IIC_tx_byte($AA)
Delay(1000)
IIC_start()
ass=adress+1
IIC_tx_byte(ass)
Delay(1000)
temperature_int.l = IIC_rx_byte(1)
temperature_frac.l = IIC_rx_byte(1)
IIC_stop()
Debug temperature_int
Debug temperature_frac
temperature = ((temperature_int * 256 + temperature_frac) / (128 * 5 ))/ 10
If temperature_int >= 128
temperature = temperature - 256
EndIf
ProcedureReturn temperature
EndProcedure
For i=1 To 5
Debug temperature($48)
Delay(1000)
Next i
Thanks in advance !