CanBus
SwordfishUser.CanBus History
Show minor edits - Show changes to output
Deleted line 5:
Changed lines 76-79 from:
You can download source code from :
to:
You can download source code from : [[http://www.microelemente.ro/Swordfish/CAN.zip]]
In ZIP file, you have 4 examples and additional SYS_lib module.
In ZIP file, you have 4 examples and additional SYS_lib module.
Changed lines 81-94 from:
to:
{
*****************************************************************************
* Name : CAN_Echo.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : Receive CAN message for XTD id "S01", *
* : send message back to sender with XTD id "S01" *
* : and send message to Usart *
*****************************************************************************
}
Device = 18F458
*****************************************************************************
* Name : CAN_Echo.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : Receive CAN message for XTD id "S01", *
* : send message back to sender with XTD id "S01" *
* : and send message to Usart *
*****************************************************************************
}
Device = 18F458
Changed lines 98-159 from:
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
*****************************************************************************
* Name : CAN_lib.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : This module is based on Microchip sample *
* : CAN Application Note AN738 *
*****************************************************************************
}
Module CAN_lib
to:
Include "CAN_lib"
Include "usart"
Include "usart"
Changed lines 102-115 from:
CAN
CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10
CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11
CAN_TX_FRAME_BIT = %00001000,
CAN_TX_STD_FRAME = %11111111, // XXXXX1XX
CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX
CAN_TX_RTR_BIT = %01000000,
CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX
CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX
to:
Dim Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags, Rx_Data_Len, i As Byte,
RxTx_Data(8) As Byte,
Tx_ID, Rx_ID As LongWord,
Msg_Rcvd, Msg_Sent As Boolean
RxTx_Data(8) As Byte,
Tx_ID, Rx_ID As LongWord,
Msg_Rcvd, Msg_Sent As Boolean
Changed lines 108-127 from:
CAN_RX_FILTER_5 = %00000100,
CAN_RX_FILTER_6 = %00000101,
CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared
CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared
CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared
CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared
CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered
CAN_OP_MODE_BITS = %11100000,
CAN_OP_MODE_NORMAL = %00000000,
CAN_OP_MODE_SLEEP = %00100000,
CAN_OP_MODE_LOOP = %01000000,
CAN_OP_MODE_LISTEN = %01100000,
CAN_OP_MODE_CONFIG = %10000000,
to:
ADCON1 = %11000110 // AD off
CMCON = $07 // Comparator off
WDTCON = 1
CMCON = $07 // Comparator off
WDTCON = 1
Changed lines 112-188 from:
CAN_CONFIG_PHSEG2_PRG_BIT = %00000001,
CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1
CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0
CAN_CONFIG_LINE_FILTER_BIT = %00000010,
CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X
CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X
CAN_CONFIG_SAMPLE_BIT = %00000100,
CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX
CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX
CAN_CONFIG_MSG_TYPE_BIT = %00001000,
CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX
CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX
CAN_CONFIG_DBL_BUFFER_BIT = %00010000,
CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX
CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX
CAN_CONFIG_MSG_BITS = %01100000,
CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX
CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX
CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX
CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX
CAN_MASK_B1 = 1,
CAN_MASK_B2 = 2,
CAN_FILTER_B1_F1 = 1,
CAN_FILTER_B1_F2 = 2,
CAN_FILTER_B2_F1 = 3,
CAN_FILTER_B2_F2 = 4,
CAN_FILTER_B2_F3 = 5,
CAN_FILTER_B2_F4 = 6
Const
// BRGCON3
WAKFIL = 6,
// BRGCON2
SEG2PHTS = 7,
SAM = 6,
// COMSTAT
RX1OVFL = 7,
RXB0OVFL = 7,
TXBO = 5,
TXBP = 4,
RXBP = 3,
// PIR3
IRXIF = 7,
RXB1IF = 1,
RXB0IF = 0,
// CANCON
ABAT = 4,
// RXBnCON
RXFUL = 7,
RXB0DBEN = 2,
// RXBnDLC
RXRTR = 6,
// RXBnSIDL
EXID = 3,
// TXBnCON
TXREQ = 3
Dim
RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN),
BRGCON2_SAM As BRGCON2.Bits(SAM),
BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS),
BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL),
PIR3_RXB0IF As PIR3.Bits(RXB0IF),
COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL),
PIR3_RXB1IF As PIR3.Bits(RXB1IF),
COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL),
RXB0DLC_RTR As RXB0DLC.Bits(RXRTR),
RXB0SIDL_EXID As RXB0SIDL.Bits(EXID),
PIR3_IRXIF As PIR3.Bits(IRXIF),
to:
ClrWDT
SetBaudrate(br115200)
SetBaudrate(br115200)
Changed lines 115-134 from:
COMSTAT
// RXB1CON_RXFUL
//
//
//
{
****************************************************************************
* Name
* Purpose : Given mode byte is copied to CANCON
*
****************************************************************************
}
Public Sub CANSetOperationMode(mode As Byte)
to:
Can_Init_Flags = 0
Can_Send_Flags = 0
Can_Rcv_Flags = 0
Can_Send_Flags = CAN_TX_PRIORITY_0 And // Form value to be used
CAN_TX_XTD_FRAME And // with CANSendMessage
CAN_TX_NO_RTR_FRAME
Can_Init_Flags = CAN_CONFIG_SAMPLE_THRICE And // Form value to be used
CAN_CONFIG_PHSEG2_PRG_ON And // with CANInitialize
CAN_CONFIG_XTD_MSG And
CAN_CONFIG_DBL_BUFFER_ON And
CAN_CONFIG_ALL_VALID_MSG
CANInitialize(1, 10, 7, 6, 2, Can_Init_Flags) // initialize CAN at 250 Kbps
CANSetOperationMode(CAN_OP_MODE_CONFIG) // set CONFIGURATION mode
Rx_ID = $FFFFFFFF
CANSetMask(CAN_MASK_B1, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask1 bits to ones
CANSetMask(CAN_MASK_B2, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask2 bits to ones
Rx_ID = String2ID("S01")
Tx_ID = String2ID("S01")
CANSetFilter(CAN_FILTER_B1_F1, Rx_ID, CAN_CONFIG_XTD_MSG) // set id of filter B1_F1 to "S01"
CANSetOperationMode(CAN_OP_MODE_NORMAL) // set NORMAL mode
While true
Can_Send_Flags = 0
Can_Rcv_Flags = 0
Can_Send_Flags = CAN_TX_PRIORITY_0 And // Form value to be used
CAN_TX_XTD_FRAME And // with CANSendMessage
CAN_TX_NO_RTR_FRAME
Can_Init_Flags = CAN_CONFIG_SAMPLE_THRICE And // Form value to be used
CAN_CONFIG_PHSEG2_PRG_ON And // with CANInitialize
CAN_CONFIG_XTD_MSG And
CAN_CONFIG_DBL_BUFFER_ON And
CAN_CONFIG_ALL_VALID_MSG
CANInitialize(1, 10, 7, 6, 2, Can_Init_Flags) // initialize CAN at 250 Kbps
CANSetOperationMode(CAN_OP_MODE_CONFIG) // set CONFIGURATION mode
Rx_ID = $FFFFFFFF
CANSetMask(CAN_MASK_B1, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask1 bits to ones
CANSetMask(CAN_MASK_B2, Rx_ID, CAN_CONFIG_XTD_MSG) // set all mask2 bits to ones
Rx_ID = String2ID("S01")
Tx_ID = String2ID("S01")
CANSetFilter(CAN_FILTER_B1_F1, Rx_ID, CAN_CONFIG_XTD_MSG) // set id of filter B1_F1 to "S01"
CANSetOperationMode(CAN_OP_MODE_NORMAL) // set NORMAL mode
While true
Changed lines 142-143 from:
End Sub
to:
Msg_Rcvd = CANReceiveMessage(Rx_ID , RxTx_Data , Rx_Data_Len, Can_Rcv_Flags)
If Msg_Rcvd Then
WriteByte(Rx_ID.Byte2)
WriteByte(Rx_ID.Byte1)
WriteByte(Rx_ID.Byte0)
WriteByte(" ")
i = 0
While i < Rx_Data_Len
WriteByte(RxTx_Data(i))
Inc(i)
Wend
Write($0D, $0A)
Msg_Sent = CANSendMessage(Tx_ID, RxTx_Data, Rx_Data_Len, Can_Send_Flags) // send data back
If Msg_Sent Then
Write("CANSendMessage Success", $0D, $0A)
Else
Write("CANSendMessage Error", $0D, $0A)
End If
End If
Wend
=]
!!!Module Code
=code [=
If Msg_Rcvd Then
WriteByte(Rx_ID.Byte2)
WriteByte(Rx_ID.Byte1)
WriteByte(Rx_ID.Byte0)
WriteByte(" ")
i = 0
While i < Rx_Data_Len
WriteByte(RxTx_Data(i))
Inc(i)
Wend
Write($0D, $0A)
Msg_Sent = CANSendMessage(Tx_ID, RxTx_Data, Rx_Data_Len, Can_Send_Flags) // send data back
If Msg_Sent Then
Write("CANSendMessage Success", $0D, $0A)
Else
Write("CANSendMessage Error", $0D, $0A)
End If
End If
Wend
=]
!!!Module Code
=code [=
Changed lines 166-181 from:
****************************************************************************
* Name : CANSetBaudRate *
* Purpose : Given values are bit adjusted to fit in 18CXX8 *
* BRGCONx registers and copied. *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
* Purpose : Given values are bit adjusted to fit in 18CXX8
*
* Input
*
*
*
*
*
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
to:
*****************************************************************************
* Name : CAN_lib.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : This module is based on Microchip sample *
* : CAN Application Note AN738 *
*****************************************************************************
* Name : CAN_lib.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : This module is based on Microchip sample *
* : CAN Application Note AN738 *
*****************************************************************************
Changed lines 177-197 from:
Dec(SJW)
Dec(BRP)
Dec(PHSEG1)
Dec(PHSEG2)
Dec(PROPSEG)
BRGCON1 = SJW << 6
BRGCON1 = BRGCON1 Or BRP
BRGCON2 = PHSEG1 << 3
BRGCON2 = BRGCON2 Or PROPSEG
If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then
BRGCON2_SAM = 1
End If
If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then
BRGCON2_SEG2PHTS = 1
End If
BRGCON3 = PHSEG2
If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then
BRGCON3_WAKFIL = 1
End If
End Sub
to:
Module CAN_lib
Include "SYS_lib"
Public Const
CAN_TX_PRIORITY_BITS= %00000011,
CAN_TX_PRIORITY_0 = %11111100, // XXXXXX00
CAN_TX_PRIORITY_1 = %11111101, // XXXXXX01
CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10
CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11
CAN_TX_FRAME_BIT = %00001000,
CAN_TX_STD_FRAME = %11111111, // XXXXX1XX
CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX
CAN_TX_RTR_BIT = %01000000,
CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX
CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX
CAN_RX_FILTER_BITS = %00000111,
CAN_RX_FILTER_1 = %00000000,
CAN_RX_FILTER_2 = %00000001,
CAN_RX_FILTER_3 = %00000010,
CAN_RX_FILTER_4 = %00000011,
CAN_RX_FILTER_5 = %00000100,
CAN_RX_FILTER_6 = %00000101,
CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared
CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared
CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared
CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared
CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered
CAN_OP_MODE_BITS = %11100000,
CAN_OP_MODE_NORMAL = %00000000,
CAN_OP_MODE_SLEEP = %00100000,
CAN_OP_MODE_LOOP = %01000000,
CAN_OP_MODE_LISTEN = %01100000,
CAN_OP_MODE_CONFIG = %10000000,
CAN_CONFIG_DEFAULT = %11111111, // 11111111
CAN_CONFIG_PHSEG2_PRG_BIT = %00000001,
CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1
CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0
CAN_CONFIG_LINE_FILTER_BIT = %00000010,
CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X
CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X
CAN_CONFIG_SAMPLE_BIT = %00000100,
CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX
CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX
CAN_CONFIG_MSG_TYPE_BIT = %00001000,
CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX
CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX
CAN_CONFIG_DBL_BUFFER_BIT = %00010000,
CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX
CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX
CAN_CONFIG_MSG_BITS = %01100000,
CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX
CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX
CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX
CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX
CAN_MASK_B1 = 1,
CAN_MASK_B2 = 2,
CAN_FILTER_B1_F1 = 1,
CAN_FILTER_B1_F2 = 2,
CAN_FILTER_B2_F1 = 3,
CAN_FILTER_B2_F2 = 4,
CAN_FILTER_B2_F3 = 5,
CAN_FILTER_B2_F4 = 6
Const
// BRGCON3
WAKFIL = 6,
// BRGCON2
SEG2PHTS = 7,
SAM = 6,
// COMSTAT
RX1OVFL = 7,
RXB0OVFL = 7,
TXBO = 5,
TXBP = 4,
RXBP = 3,
// PIR3
IRXIF = 7,
RXB1IF = 1,
RXB0IF = 0,
// CANCON
ABAT = 4,
// RXBnCON
RXFUL = 7,
RXB0DBEN = 2,
// RXBnDLC
RXRTR = 6,
// RXBnSIDL
EXID = 3,
// TXBnCON
TXREQ = 3
Dim
RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN),
BRGCON2_SAM As BRGCON2.Bits(SAM),
BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS),
BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL),
PIR3_RXB0IF As PIR3.Bits(RXB0IF),
COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL),
PIR3_RXB1IF As PIR3.Bits(RXB1IF),
COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL),
RXB0DLC_RTR As RXB0DLC.Bits(RXRTR),
RXB0SIDL_EXID As RXB0SIDL.Bits(EXID),
PIR3_IRXIF As PIR3.Bits(IRXIF),
COMSTAT_TXB0 As COMSTAT.Bits(TXBO),
COMSTAT_TXBP As COMSTAT.Bits(TXBP),
COMSTAT_RXBP As COMSTAT.Bits(RXBP),
CANCON_ABAT As CANCON.Bits(ABAT),
RXB0CON_RXFUL As RXB0CON.Bits(RXFUL)
// RXB1CON_RXFUL As RXB1CON.Bits(RXFUL),
// TXB0CON_TXREQ As TXB0CON.Bits(TXREQ),
// TXB1CON_TXREQ As TXB1CON.Bits(TXREQ),
// TXB2CON_TXREQ As TXB2CON.Bits(TXREQ)
Include "SYS_lib"
Public Const
CAN_TX_PRIORITY_BITS= %00000011,
CAN_TX_PRIORITY_0 = %11111100, // XXXXXX00
CAN_TX_PRIORITY_1 = %11111101, // XXXXXX01
CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10
CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11
CAN_TX_FRAME_BIT = %00001000,
CAN_TX_STD_FRAME = %11111111, // XXXXX1XX
CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX
CAN_TX_RTR_BIT = %01000000,
CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX
CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX
CAN_RX_FILTER_BITS = %00000111,
CAN_RX_FILTER_1 = %00000000,
CAN_RX_FILTER_2 = %00000001,
CAN_RX_FILTER_3 = %00000010,
CAN_RX_FILTER_4 = %00000011,
CAN_RX_FILTER_5 = %00000100,
CAN_RX_FILTER_6 = %00000101,
CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared
CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared
CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared
CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared
CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered
CAN_OP_MODE_BITS = %11100000,
CAN_OP_MODE_NORMAL = %00000000,
CAN_OP_MODE_SLEEP = %00100000,
CAN_OP_MODE_LOOP = %01000000,
CAN_OP_MODE_LISTEN = %01100000,
CAN_OP_MODE_CONFIG = %10000000,
CAN_CONFIG_DEFAULT = %11111111, // 11111111
CAN_CONFIG_PHSEG2_PRG_BIT = %00000001,
CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1
CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0
CAN_CONFIG_LINE_FILTER_BIT = %00000010,
CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X
CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X
CAN_CONFIG_SAMPLE_BIT = %00000100,
CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX
CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX
CAN_CONFIG_MSG_TYPE_BIT = %00001000,
CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX
CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX
CAN_CONFIG_DBL_BUFFER_BIT = %00010000,
CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX
CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX
CAN_CONFIG_MSG_BITS = %01100000,
CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX
CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX
CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX
CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX
CAN_MASK_B1 = 1,
CAN_MASK_B2 = 2,
CAN_FILTER_B1_F1 = 1,
CAN_FILTER_B1_F2 = 2,
CAN_FILTER_B2_F1 = 3,
CAN_FILTER_B2_F2 = 4,
CAN_FILTER_B2_F3 = 5,
CAN_FILTER_B2_F4 = 6
Const
// BRGCON3
WAKFIL = 6,
// BRGCON2
SEG2PHTS = 7,
SAM = 6,
// COMSTAT
RX1OVFL = 7,
RXB0OVFL = 7,
TXBO = 5,
TXBP = 4,
RXBP = 3,
// PIR3
IRXIF = 7,
RXB1IF = 1,
RXB0IF = 0,
// CANCON
ABAT = 4,
// RXBnCON
RXFUL = 7,
RXB0DBEN = 2,
// RXBnDLC
RXRTR = 6,
// RXBnSIDL
EXID = 3,
// TXBnCON
TXREQ = 3
Dim
RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN),
BRGCON2_SAM As BRGCON2.Bits(SAM),
BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS),
BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL),
PIR3_RXB0IF As PIR3.Bits(RXB0IF),
COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL),
PIR3_RXB1IF As PIR3.Bits(RXB1IF),
COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL),
RXB0DLC_RTR As RXB0DLC.Bits(RXRTR),
RXB0SIDL_EXID As RXB0SIDL.Bits(EXID),
PIR3_IRXIF As PIR3.Bits(IRXIF),
COMSTAT_TXB0 As COMSTAT.Bits(TXBO),
COMSTAT_TXBP As COMSTAT.Bits(TXBP),
COMSTAT_RXBP As COMSTAT.Bits(RXBP),
CANCON_ABAT As CANCON.Bits(ABAT),
RXB0CON_RXFUL As RXB0CON.Bits(RXFUL)
// RXB1CON_RXFUL As RXB1CON.Bits(RXFUL),
// TXB0CON_TXREQ As TXB0CON.Bits(TXREQ),
// TXB1CON_TXREQ As TXB1CON.Bits(TXREQ),
// TXB2CON_TXREQ As TXB2CON.Bits(TXREQ)
Changed lines 307-312 from:
* Name : CANIDToRegs *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are updated *
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL *
* Purpose : If given id is standard identifier,
*
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL
to:
* Name : CANSetOperationMode *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
Changed lines 312-326 from:
Sub CANIDToRegs(CANreg As Word, value As LongWord, flags As Byte)
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0>
POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5>
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
If (flags And
POSTINC2 = INDF2 Or (value
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
to:
Public Sub CANSetOperationMode(mode As Byte)
CANCON = mode // Request desired mode.
While((CANSTAT And CAN_OP_MODE_BITS) <> mode)
ClrWDT
Wend // Wait till desired mode is set.
CANCON = mode // Request desired mode.
While((CANSTAT And CAN_OP_MODE_BITS) <> mode)
ClrWDT
Wend // Wait till desired mode is set.
Changed lines 320-325 from:
* Name : RegsToCANID *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are used *
* If given id is extended identifier, *
* EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> *
* SIDH And SIDL is copied To bits value<28:18> *
* Purpose : If given id is standard identifier,
*
*
*
*
to:
* Name : CANSetBaudRate *
* Purpose : Given values are bit adjusted to fit in 18CXX8 *
* BRGCONx registers and copied. *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
* Purpose : Given values are bit adjusted to fit in 18CXX8 *
* BRGCONx registers and copied. *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
Changed lines 336-352 from:
result.Byte3 = $00
Else // Extended Identifier
result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21>
result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25>
result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16>
result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18>
result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8>
result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0>
End If
End Function
to:
Sub CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dec(SJW)
Dec(BRP)
Dec(PHSEG1)
Dec(PHSEG2)
Dec(PROPSEG)
BRGCON1 = SJW << 6
BRGCON1 = BRGCON1 Or BRP
BRGCON2 = PHSEG1 << 3
BRGCON2 = BRGCON2 Or PROPSEG
If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then
BRGCON2_SAM = 1
End If
If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then
BRGCON2_SEG2PHTS = 1
End If
BRGCON3 = PHSEG2
If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then
BRGCON3_WAKFIL = 1
End If
End Sub
Dec(SJW)
Dec(BRP)
Dec(PHSEG1)
Dec(PHSEG2)
Dec(PROPSEG)
BRGCON1 = SJW << 6
BRGCON1 = BRGCON1 Or BRP
BRGCON2 = PHSEG1 << 3
BRGCON2 = BRGCON2 Or PROPSEG
If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then
BRGCON2_SAM = 1
End If
If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then
BRGCON2_SEG2PHTS = 1
End If
BRGCON3 = PHSEG2
If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then
BRGCON3_WAKFIL = 1
End If
End Sub
Changed lines 359-361 from:
* Name : CANSetMask *
* Purpose :Given value is bit adjusted to appropriate buffer *
* mask registers. *
* Purpose :
*
to:
* Name : CANIDToRegs *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are updated *
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are updated *
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL *
Deleted lines 365-382:
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Save(FSR1, FSR2)
If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value.
buf = AddressOf(RXM0SIDH)
Else
buf = AddressOf(RXM1SIDH)
End If
CANIDToRegs(buf, value, flags)
Restore
End Sub
{
****************************************************************************
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
****************************************************************************
Changed lines 367-386 from:
Save(FSR1, FSR2)
Case
End Sub
to:
Sub CANIDToRegs(CANreg As Word, value As LongWord, flags As Byte)
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0>
POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5>
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
End Sub
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0>
POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5>
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
End Sub
Changed lines 385-397 from:
* Name : CANInitialize *
* Purpose :Initialize CAN module, Filters, Mask *
*Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
* Purpose :
*
*
*
*
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS
to:
* Name : RegsToCANID *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are used *
* If given id is extended identifier, *
* EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> *
* SIDH And SIDL is copied To bits value<28:18> *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are used *
* If given id is extended identifier, *
* EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> *
* SIDH And SIDL is copied To bits value<28:18> *
Changed lines 393-395 from:
Dim FilterConfig1 As Byte,
FilterConfig2 As Byte
to:
Function RegsToCANID(CANreg As Word, flags As Byte) As LongWord
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
result.Byte0 = INDF2 << 3 // Copy SIDH<4:0> to SID<7:3>
result.Byte1 = POSTINC2 >> 5 // Copy SIDH<7:5> to SID<10:8>
result.Byte0 = result.Byte0 Or (INDF2 >> 5) // Copy SIDL<7:6> to SID<2:0>
result.Byte2 = $00
result.Byte3 = $00
Else // Extended Identifier
result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21>
result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25>
result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16>
result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18>
result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8>
result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0>
End If
End Function
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
Dim buf As Word
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
result.Byte0 = INDF2 << 3 // Copy SIDH<4:0> to SID<7:3>
result.Byte1 = POSTINC2 >> 5 // Copy SIDH<7:5> to SID<10:8>
result.Byte0 = result.Byte0 Or (INDF2 >> 5) // Copy SIDL<7:6> to SID<2:0>
result.Byte2 = $00
result.Byte3 = $00
Else // Extended Identifier
result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21>
result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25>
result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16>
result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18>
result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8>
result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0>
End If
End Function
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Changed lines 420-437 from:
TRISG.0 = 0 'TX CAN
TRISG.2 = 1 'RX CAN
#endif
CIOCON = 0
CANSetOperationMode
#if _device in (18F248, 18F258, 18F448, 18F458)
Nop
#else
ECANCON = ECANCON And %00111111
#endif
CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate.
RXB0CON = flags And CAN_CONFIG_MSG_BITS
If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then
RXB0CON_RX0DBEN = 1
to:
If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value.
buf = AddressOf(RXM0SIDH)
Else
buf = AddressOf(RXM1SIDH)
buf = AddressOf(RXM0SIDH)
Else
buf = AddressOf(RXM1SIDH)
Changed lines 425-445 from:
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG)
Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS)))
Case CAN_CONFIG_VALID_XTD_MSG
FilterConfig1 = CAN_CONFIG_XTD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
Case CAN_CONFIG_VALID_STD_MSG
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_STD_MSG
Else
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
End Select
CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored.
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1)
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2)
CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode.
to:
CANIDToRegs(buf, value, flags)
Changed lines 430-433 from:
* Name : CANSendMessage *
* Purpose :If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
* Purpose :
*
* If none found FALSE value is returned.
to:
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
Changed lines 434-436 from:
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte
Public Function CANSendMessage
Dim i As Byte
to:
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Changed lines 438-448 from:
If INDF2.bits(TXREQ) = 0 Then
//
CANCON = CANCON Or %00001000
Else
FSR2 =
If INDF2.bits(TXREQ) = 0 Then
// If TXB1CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1
CANCON = CANCON Or %00000110
to:
Select filter
Case CAN_FILTER_B1_F1
buf = AddressOf(RXF0SIDH)
Case CAN_FILTER_B1_F2
buf = AddressOf(RXF1SIDH)
Case CAN_FILTER_B2_F1
buf = AddressOf(RXF2SIDH)
Case CAN_FILTER_B2_F2
buf = AddressOf(RXF3SIDH)
Case CAN_FILTER_B2_F3
buf = AddressOf(RXF4SIDH)
Case CAN_FILTER_B1_F1
buf = AddressOf(RXF0SIDH)
Case CAN_FILTER_B1_F2
buf = AddressOf(RXF1SIDH)
Case CAN_FILTER_B2_F1
buf = AddressOf(RXF2SIDH)
Case CAN_FILTER_B2_F2
buf = AddressOf(RXF3SIDH)
Case CAN_FILTER_B2_F3
buf = AddressOf(RXF4SIDH)
Changed lines 450-482 from:
If INDF2.bits(TXREQ) = 0 Then
// If TXB2CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2
CANCON = CANCON Or %00000100
Else
result = false // None of the transmit buffers were empty.
Exit
End If
End If
End If
RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority.
If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired.
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG)
Else
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG)
End If
RXB0DLC = DataLen
If (flags And CAN_TX_RTR_BIT) = 0 Then
RXB0DLC = RXB0DLC Or %01000000
End If
i = 0
FSR2 = AddressOf(RXB0D0) // Populate data values.
FSR1 = AddressOf(Data)
While i < DataLen
POSTINC2 = POSTINC1
Inc(i)
Wend
ASM
bsf RXB0CON, 3
End ASM
CANCON = CANCON And %11110001
result = true
to:
buf = AddressOf(RXF5SIDH)
End Select
CANIDToRegs(buf, value, flags)
End Select
CANIDToRegs(buf, value, flags)
Changed line 454 from:
End Function
to:
End Sub
Changed lines 457-460 from:
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
* Purpose : If at least one full receive buffer is found
*
*
to:
* Name : CANInitialize *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
Changed lines 471-474 from:
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i, buf As Byte,
lbIsItBuffer0 As Boolean
Public Function CANReceiveMessage
Dim i
lbIsItBuffer0 As Boolean
to:
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
FilterConfig2 As Byte
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
FilterConfig2 As Byte
Changed lines 476-506 from:
CANCON = CANCON And %11110001
End If
If RXB0CON
flags =
// If RXB1CON
CANCON = CANCON And %11110001 // RXBuffer1 is full
CANCON = CANCON Or %00001010
lbIsItBuffer0 = false
PIR3
If COMSTAT
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX1OVFL = 0
End If
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
flags = (flags Or INDF2) And CAN_RX_FILTER_BITS
// flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS
If flags < $02 Then
flags = flags Or CAN_RX_DBL_BUFFERED
End If
to:
#if _device in (18F248, 18F258, 18F448, 18F458, 18F2480, 18F2580, 18F4480, 18F4580, 18F2682, 18F2685, 18F4682, 18F4685)
TRISB.2 = 0 'TX CAN
TRISB.3 = 1 'RX CAN
#else
TRISG.0 = 0 'TX CAN
TRISG.2 = 1 'RX CAN
#endif
CIOCON = 0
CANSetOperationMode(CAN_OP_MODE_CONFIG) // In order to setup necessary config parameters of CAN module, it must be in Config mode.
#if _device in (18F248, 18F258, 18F448, 18F458)
Nop
#else
ECANCON = ECANCON And %00111111
#endif
CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate.
RXB0CON = flags And CAN_CONFIG_MSG_BITS
If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then
RXB0CON_RX0DBEN = 1
End If
RXB1CON = RXB0CON
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG) // Set default filter and mask registers for all receive buffers.
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG)
Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS)))
Case CAN_CONFIG_VALID_XTD_MSG
FilterConfig1 = CAN_CONFIG_XTD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
Case CAN_CONFIG_VALID_STD_MSG
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_STD_MSG
TRISB.2 = 0 'TX CAN
TRISB.3 = 1 'RX CAN
#else
TRISG.0 = 0 'TX CAN
TRISG.2 = 1 'RX CAN
#endif
CIOCON = 0
CANSetOperationMode(CAN_OP_MODE_CONFIG) // In order to setup necessary config parameters of CAN module, it must be in Config mode.
#if _device in (18F248, 18F258, 18F448, 18F458)
Nop
#else
ECANCON = ECANCON And %00111111
#endif
CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate.
RXB0CON = flags And CAN_CONFIG_MSG_BITS
If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then
RXB0CON_RX0DBEN = 1
End If
RXB1CON = RXB0CON
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG) // Set default filter and mask registers for all receive buffers.
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG)
Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS)))
Case CAN_CONFIG_VALID_XTD_MSG
FilterConfig1 = CAN_CONFIG_XTD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
Case CAN_CONFIG_VALID_STD_MSG
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_STD_MSG
Changed lines 506-516 from:
DataLen = RXB0DLC And %00001111 // Retrieve message length.
If RXB0DLC_RTR = 1 Then
flags = flags Or
to:
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
End Select
CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored.
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1)
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2)
CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode.
Restore
End Sub
{
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte
Save(FSR1, FSR2)
FSR2 = AddressOf(TXB0CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then // Find the first empty transmitter.
// If TXB0CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer0 is empty. Set WIN bits to point to TXB0
CANCON = CANCON Or %00001000
FilterConfig2 = CAN_CONFIG_XTD_MSG
End Select
CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored.
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1)
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2)
CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode.
Restore
End Sub
{
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte
Save(FSR1, FSR2)
FSR2 = AddressOf(TXB0CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then // Find the first empty transmitter.
// If TXB0CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer0 is empty. Set WIN bits to point to TXB0
CANCON = CANCON Or %00001000
Changed lines 535-536 from:
End If
to:
FSR2 = AddressOf(TXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB1CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1
CANCON = CANCON Or %00000110
Else
FSR2 = AddressOf(TXB2CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB2CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2
CANCON = CANCON Or %00000100
Else
result = false // None of the transmit buffers were empty.
Exit
End If
End If
End If
RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority.
If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired.
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG)
Else
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG)
End If
RXB0DLC = DataLen
If (flags And CAN_TX_RTR_BIT) = 0 Then
RXB0DLC = RXB0DLC Or %01000000
End If
If INDF2.bits(TXREQ) = 0 Then
// If TXB1CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1
CANCON = CANCON Or %00000110
Else
FSR2 = AddressOf(TXB2CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB2CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2
CANCON = CANCON Or %00000100
Else
result = false // None of the transmit buffers were empty.
Exit
End If
End If
End If
RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority.
If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired.
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG)
Else
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG)
End If
RXB0DLC = DataLen
If (flags And CAN_TX_RTR_BIT) = 0 Then
RXB0DLC = RXB0DLC Or %01000000
End If
Changed lines 563-566 from:
FSR1 = AddressOf(RXB0D0)
FSR2 = AddressOf(Data)
While i < buf
to:
FSR2 = AddressOf(RXB0D0) // Populate data values.
FSR1 = AddressOf(Data)
While i < DataLen
FSR1 = AddressOf(Data)
While i < DataLen
Changed lines 568-580 from:
Wend
CANCON = CANCON And %11110001 // Restore default RXB0 mapping.
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
to:
Wend
ASM
bsf RXB0CON, 3
End ASM
CANCON = CANCON And %11110001
ASM
bsf RXB0CON, 3
End ASM
CANCON = CANCON And %11110001
Changed lines 578-579 from:
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
* Purpose : Transform 3 Char String into LongWord id
to:
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
Added lines 583-661:
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i, buf As Byte,
lbIsItBuffer0 As Boolean
Save(FSR1, FSR2)
flags = 0 // Start with no error or flags set.
If RXB0CON_RXFUL = 1 Then // Find which buffer is ready.
CANCON = CANCON And %11110001 // RXBuffer0 is full.
lbIsItBuffer0 = true
PIR3_RXB0IF = 0 // Clear the received flag.
If COMSTAT_RX0OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX0OVFL = 0
End If
If RXB0CON_RX0DBEN = 1 Then
flags = (flags Or RXB0CON) And CAN_RX_FILTER_BITS
flags = flags And $01
End If
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(RXFUL) = 1 Then
// If RXB1CON_RXFUL = 1 Then
CANCON = CANCON And %11110001 // RXBuffer1 is full
CANCON = CANCON Or %00001010
lbIsItBuffer0 = false
PIR3_RXB1IF = 0 // Clear the received flag.
If COMSTAT_RX1OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX1OVFL = 0
End If
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
flags = (flags Or INDF2) And CAN_RX_FILTER_BITS
// flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS
If flags < $02 Then
flags = flags Or CAN_RX_DBL_BUFFERED
End If
Else
result = false
Exit
End If
End If
DataLen = RXB0DLC And %00001111 // Retrieve message length.
If RXB0DLC_RTR = 1 Then // Determine whether this was RTR or not.
flags = flags Or CAN_RX_RTR_FRAME
End If
If RXB0SIDL_EXID = 1 Then // Retrieve EIDX bytes only if this is extended message
flags = flags Or CAN_RX_XTD_FRAME
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_XTD_MSG)
Else
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG)
End If
i = 0
buf = DataLen // Get message data itself
FSR1 = AddressOf(RXB0D0)
FSR2 = AddressOf(Data)
While i < buf
POSTINC2 = POSTINC1
Inc(i)
Wend
CANCON = CANCON And %11110001 // Restore default RXB0 mapping.
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
result = true
Restore
End Function
{
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i, buf As Byte,
lbIsItBuffer0 As Boolean
Save(FSR1, FSR2)
flags = 0 // Start with no error or flags set.
If RXB0CON_RXFUL = 1 Then // Find which buffer is ready.
CANCON = CANCON And %11110001 // RXBuffer0 is full.
lbIsItBuffer0 = true
PIR3_RXB0IF = 0 // Clear the received flag.
If COMSTAT_RX0OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX0OVFL = 0
End If
If RXB0CON_RX0DBEN = 1 Then
flags = (flags Or RXB0CON) And CAN_RX_FILTER_BITS
flags = flags And $01
End If
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(RXFUL) = 1 Then
// If RXB1CON_RXFUL = 1 Then
CANCON = CANCON And %11110001 // RXBuffer1 is full
CANCON = CANCON Or %00001010
lbIsItBuffer0 = false
PIR3_RXB1IF = 0 // Clear the received flag.
If COMSTAT_RX1OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX1OVFL = 0
End If
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
flags = (flags Or INDF2) And CAN_RX_FILTER_BITS
// flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS
If flags < $02 Then
flags = flags Or CAN_RX_DBL_BUFFERED
End If
Else
result = false
Exit
End If
End If
DataLen = RXB0DLC And %00001111 // Retrieve message length.
If RXB0DLC_RTR = 1 Then // Determine whether this was RTR or not.
flags = flags Or CAN_RX_RTR_FRAME
End If
If RXB0SIDL_EXID = 1 Then // Retrieve EIDX bytes only if this is extended message
flags = flags Or CAN_RX_XTD_FRAME
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_XTD_MSG)
Else
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG)
End If
i = 0
buf = DataLen // Get message data itself
FSR1 = AddressOf(RXB0D0)
FSR2 = AddressOf(Data)
While i < buf
POSTINC2 = POSTINC1
Inc(i)
Wend
CANCON = CANCON And %11110001 // Restore default RXB0 mapping.
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
result = true
Restore
End Function
{
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
Changed lines 50-74 from:
to:
{
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
{
****************************************************************************
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
{
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
}
Public Function String2ID(str_in As String) As LongWord
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
{
****************************************************************************
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
{
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
}
Public Function String2ID(str_in As String) As LongWord
Changed lines 136-147 from:
******************************************************************************
* Name : Sensirion.BAS *
* Author :Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date :9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
* Author :
* Notice : Copyright (c) 2007 -YO2LIO
* : All Rights Reserved
* Date :
*
*
*
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
*
to:
*****************************************************************************
* Name : CAN_lib.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : This module is based on Microchip sample *
* : CAN Application Note AN738 *
*****************************************************************************
* Name : CAN_lib.BAS *
* Author : Florin Andrei Medrea *
* Notice : Copyright (c) 2007 - YO2LIO - *
* : All Rights Reserved *
* Date : 10/26/2007 *
* Version : 1.0 *
* Notes : This module is based on Microchip sample *
* : CAN Application Note AN738 *
*****************************************************************************
Changed lines 147-168 from:
Module Sensirion
Include "math"
Include "system"
ConstNoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Include "
Const
End Structure
Structure TPort
End Structure
to:
Module CAN_lib
Include "SYS_lib"
Public Const
CAN_TX_PRIORITY_BITS= %00000011,
CAN_TX_PRIORITY_0 = %11111100, // XXXXXX00
CAN_TX_PRIORITY_1 = %11111101, // XXXXXX01
CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10
CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11
CAN_TX_FRAME_BIT = %00001000,
CAN_TX_STD_FRAME = %11111111, // XXXXX1XX
CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX
CAN_TX_RTR_BIT = %01000000,
CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX
CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX
Include "SYS_lib"
Public Const
CAN_TX_PRIORITY_BITS= %00000011,
CAN_TX_PRIORITY_0 = %11111100, // XXXXXX00
CAN_TX_PRIORITY_1 = %11111101, // XXXXXX01
CAN_TX_PRIORITY_2 = %11111110, // XXXXXX10
CAN_TX_PRIORITY_3 = %11111111, // XXXXXX11
CAN_TX_FRAME_BIT = %00001000,
CAN_TX_STD_FRAME = %11111111, // XXXXX1XX
CAN_TX_XTD_FRAME = %11110111, // XXXXX0XX
CAN_TX_RTR_BIT = %01000000,
CAN_TX_NO_RTR_FRAME = %11111111, // X1XXXXXX
CAN_TX_RTR_FRAME = %10111111, // X0XXXXXX
Changed lines 166-170 from:
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
to:
CAN_RX_FILTER_BITS = %00000111,
CAN_RX_FILTER_1 = %00000000,
CAN_RX_FILTER_2 = %00000001,
CAN_RX_FILTER_3 = %00000010,
CAN_RX_FILTER_4 = %00000011,
CAN_RX_FILTER_5 = %00000100,
CAN_RX_FILTER_6 = %00000101,
CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared
CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared
CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared
CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared
CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered
CAN_OP_MODE_BITS = %11100000,
CAN_OP_MODE_NORMAL = %00000000,
CAN_OP_MODE_SLEEP = %00100000,
CAN_OP_MODE_LOOP = %01000000,
CAN_OP_MODE_LISTEN = %01100000,
CAN_OP_MODE_CONFIG = %10000000,
CAN_CONFIG_DEFAULT = %11111111, // 11111111
CAN_CONFIG_PHSEG2_PRG_BIT = %00000001,
CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1
CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0
CAN_CONFIG_LINE_FILTER_BIT = %00000010,
CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X
CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X
CAN_CONFIG_SAMPLE_BIT = %00000100,
CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX
CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX
CAN_CONFIG_MSG_TYPE_BIT = %00001000,
CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX
CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX
CAN_CONFIG_DBL_BUFFER_BIT = %00010000,
CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX
CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX
CAN_CONFIG_MSG_BITS = %01100000,
CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX
CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX
CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX
CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX
CAN_MASK_B1 = 1,
CAN_MASK_B2 = 2,
CAN_FILTER_B1_F1 = 1,
CAN_FILTER_B1_F2 = 2,
CAN_FILTER_B2_F1 = 3,
CAN_FILTER_B2_F2 = 4,
CAN_FILTER_B2_F3 = 5,
CAN_FILTER_B2_F4 = 6
Const
// BRGCON3
WAKFIL = 6,
// BRGCON2
SEG2PHTS = 7,
SAM = 6,
// COMSTAT
RX1OVFL = 7,
RXB0OVFL = 7,
TXBO = 5,
TXBP = 4,
RXBP = 3,
// PIR3
IRXIF = 7,
RXB1IF = 1,
RXB0IF = 0,
// CANCON
ABAT = 4,
// RXBnCON
RXFUL = 7,
RXB0DBEN = 2,
// RXBnDLC
RXRTR = 6,
// RXBnSIDL
EXID = 3,
// TXBnCON
TXREQ = 3
Dim
RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN),
BRGCON2_SAM As BRGCON2.Bits(SAM),
BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS),
BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL),
PIR3_RXB0IF As PIR3.Bits(RXB0IF),
COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL),
PIR3_RXB1IF As PIR3.Bits(RXB1IF),
COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL),
RXB0DLC_RTR As RXB0DLC.Bits(RXRTR),
RXB0SIDL_EXID As RXB0SIDL.Bits(EXID),
PIR3_IRXIF As PIR3.Bits(IRXIF),
COMSTAT_TXB0 As COMSTAT.Bits(TXBO),
COMSTAT_TXBP As COMSTAT.Bits(TXBP),
COMSTAT_RXBP As COMSTAT.Bits(RXBP),
CANCON_ABAT As CANCON.Bits(ABAT),
RXB0CON_RXFUL As RXB0CON.Bits(RXFUL)
// RXB1CON_RXFUL As RXB1CON.Bits(RXFUL),
// TXB0CON_TXREQ As TXB0CON.Bits(TXREQ),
// TXB1CON_TXREQ As TXB1CON.Bits(TXREQ),
// TXB2CON_TXREQ As TXB2CON.Bits(TXREQ)
{
****************************************************************************
* Name : CANSetOperationMode *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
****************************************************************************
}
Public Sub CANSetOperationMode(mode As Byte)
CANCON = mode // Request desired mode.
While((CANSTAT And CAN_OP_MODE_BITS) <> mode)
CAN_RX_FILTER_1 = %00000000,
CAN_RX_FILTER_2 = %00000001,
CAN_RX_FILTER_3 = %00000010,
CAN_RX_FILTER_4 = %00000011,
CAN_RX_FILTER_5 = %00000100,
CAN_RX_FILTER_6 = %00000101,
CAN_RX_OVERFLOW = %00001000, // Set if Overflowed else cleared
CAN_RX_INVALID_MSG = %00010000, // Set if invalid else cleared
CAN_RX_XTD_FRAME = %00100000, // Set if XTD message else cleared
CAN_RX_RTR_FRAME = %01000000, // Set if RTR message else cleared
CAN_RX_DBL_BUFFERED = %10000000, // Set if this message was hardware double-buffered
CAN_OP_MODE_BITS = %11100000,
CAN_OP_MODE_NORMAL = %00000000,
CAN_OP_MODE_SLEEP = %00100000,
CAN_OP_MODE_LOOP = %01000000,
CAN_OP_MODE_LISTEN = %01100000,
CAN_OP_MODE_CONFIG = %10000000,
CAN_CONFIG_DEFAULT = %11111111, // 11111111
CAN_CONFIG_PHSEG2_PRG_BIT = %00000001,
CAN_CONFIG_PHSEG2_PRG_ON = %11111111, // XXXXXXX1
CAN_CONFIG_PHSEG2_PRG_OFF = %11111110, // XXXXXXX0
CAN_CONFIG_LINE_FILTER_BIT = %00000010,
CAN_CONFIG_LINE_FILTER_ON = %11111111, // XXXXXX1X
CAN_CONFIG_LINE_FILTER_OFF = %11111101, // XXXXXX0X
CAN_CONFIG_SAMPLE_BIT = %00000100,
CAN_CONFIG_SAMPLE_ONCE = %11111111, // XXXXX1XX
CAN_CONFIG_SAMPLE_THRICE = %11111011, // XXXXX0XX
CAN_CONFIG_MSG_TYPE_BIT = %00001000,
CAN_CONFIG_STD_MSG = %11111111, // XXXX1XXX
CAN_CONFIG_XTD_MSG = %11110111, // XXXX0XXX
CAN_CONFIG_DBL_BUFFER_BIT = %00010000,
CAN_CONFIG_DBL_BUFFER_ON = %11111111, // XXX1XXXX
CAN_CONFIG_DBL_BUFFER_OFF = %11101111, // XXX0XXXX
CAN_CONFIG_MSG_BITS = %01100000,
CAN_CONFIG_ALL_MSG = %11111111, // X11XXXXX
CAN_CONFIG_VALID_XTD_MSG = %11011111, // X10XXXXX
CAN_CONFIG_VALID_STD_MSG = %10111111, // X01XXXXX
CAN_CONFIG_ALL_VALID_MSG = %10011111, // X00XXXXX
CAN_MASK_B1 = 1,
CAN_MASK_B2 = 2,
CAN_FILTER_B1_F1 = 1,
CAN_FILTER_B1_F2 = 2,
CAN_FILTER_B2_F1 = 3,
CAN_FILTER_B2_F2 = 4,
CAN_FILTER_B2_F3 = 5,
CAN_FILTER_B2_F4 = 6
Const
// BRGCON3
WAKFIL = 6,
// BRGCON2
SEG2PHTS = 7,
SAM = 6,
// COMSTAT
RX1OVFL = 7,
RXB0OVFL = 7,
TXBO = 5,
TXBP = 4,
RXBP = 3,
// PIR3
IRXIF = 7,
RXB1IF = 1,
RXB0IF = 0,
// CANCON
ABAT = 4,
// RXBnCON
RXFUL = 7,
RXB0DBEN = 2,
// RXBnDLC
RXRTR = 6,
// RXBnSIDL
EXID = 3,
// TXBnCON
TXREQ = 3
Dim
RXB0CON_RX0DBEN As RXB0CON.Bits(RXB0DBEN),
BRGCON2_SAM As BRGCON2.Bits(SAM),
BRGCON2_SEG2PHTS As BRGCON2.Bits(SEG2PHTS),
BRGCON3_WAKFIL As BRGCON3.Bits(WAKFIL),
PIR3_RXB0IF As PIR3.Bits(RXB0IF),
COMSTAT_RX0OVFL As COMSTAT.Bits(RXB0OVFL),
PIR3_RXB1IF As PIR3.Bits(RXB1IF),
COMSTAT_RX1OVFL As COMSTAT.Bits(RX1OVFL),
RXB0DLC_RTR As RXB0DLC.Bits(RXRTR),
RXB0SIDL_EXID As RXB0SIDL.Bits(EXID),
PIR3_IRXIF As PIR3.Bits(IRXIF),
COMSTAT_TXB0 As COMSTAT.Bits(TXBO),
COMSTAT_TXBP As COMSTAT.Bits(TXBP),
COMSTAT_RXBP As COMSTAT.Bits(RXBP),
CANCON_ABAT As CANCON.Bits(ABAT),
RXB0CON_RXFUL As RXB0CON.Bits(RXFUL)
// RXB1CON_RXFUL As RXB1CON.Bits(RXFUL),
// TXB0CON_TXREQ As TXB0CON.Bits(TXREQ),
// TXB1CON_TXREQ As TXB1CON.Bits(TXREQ),
// TXB2CON_TXREQ As TXB2CON.Bits(TXREQ)
{
****************************************************************************
* Name : CANSetOperationMode *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
****************************************************************************
}
Public Sub CANSetOperationMode(mode As Byte)
CANCON = mode // Request desired mode.
While((CANSTAT And CAN_OP_MODE_BITS) <> mode)
Changed lines 286-299 from:
SPort
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
to:
Wend // Wait till desired mode is set.
Changed lines 288-304 from:
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
to:
{
****************************************************************************
* Name : CANSetBaudRate *
* Purpose : Given values are bit adjusted to fit in 18CXX8 *
* BRGCONx registers and copied. *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Sub CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dec(SJW)
Dec(BRP)
Dec(PHSEG1)
Dec(PHSEG2)
Dec(PROPSEG)
BRGCON1 = SJW << 6
BRGCON1 = BRGCON1 Or BRP
BRGCON2 = PHSEG1 << 3
BRGCON2 = BRGCON2 Or PROPSEG
If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then
BRGCON2_SAM = 1
End If
If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then
BRGCON2_SEG2PHTS = 1
End If
BRGCON3 = PHSEG2
If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then
BRGCON3_WAKFIL = 1
End If
****************************************************************************
* Name : CANSetBaudRate *
* Purpose : Given values are bit adjusted to fit in 18CXX8 *
* BRGCONx registers and copied. *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Sub CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dec(SJW)
Dec(BRP)
Dec(PHSEG1)
Dec(PHSEG2)
Dec(PROPSEG)
BRGCON1 = SJW << 6
BRGCON1 = BRGCON1 Or BRP
BRGCON2 = PHSEG1 << 3
BRGCON2 = BRGCON2 Or PROPSEG
If (flags And CAN_CONFIG_SAMPLE_BIT) = 0 Then
BRGCON2_SAM = 1
End If
If (flags And CAN_CONFIG_PHSEG2_PRG_BIT) <> 0 Then
BRGCON2_SEG2PHTS = 1
End If
BRGCON3 = PHSEG2
If (flags And CAN_CONFIG_LINE_FILTER_BIT) <> 0 Then
BRGCON3_WAKFIL = 1
End If
Changed lines 327-343 from:
INDF2 = INDF2 And SClock.PinMask
to:
{
****************************************************************************
* Name : CANIDToRegs *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are updated *
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL *
****************************************************************************
}
Sub CANIDToRegs(CANreg As Word, value As LongWord, flags As Byte)
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0>
POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5>
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
****************************************************************************
* Name : CANIDToRegs *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are updated *
* If given id is extended identifier, *
* bits value<17:0> is copied to EIDH, EIDL and SIDH<1:0> *
* bits value<28:18> is copied to SIDH and SIDL *
****************************************************************************
}
Sub CANIDToRegs(CANreg As Word, value As LongWord, flags As Byte)
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
INDF2 = value.Byte0 >> 3 // Copy SID<7:3> to SIDH<4:0>
POSTINC2 = INDF2 Or (value.Byte1 << 5) // Copy SID<10:8> to SIDH<7:5>
INDF2 = value.Byte0 << 5 // Copy SID<2:0> to SIDL<7:5>
Else // Extended Identifier
INDF2 = value.Byte2 >> 5 // Copy EID<23:21> to SIDH<2:0>
POSTINC2 = INDF2 Or (value.Byte3 << 3) // Copy EID<28:24> to SIDH<7:3>
INDF2 = (value.Byte2 << 3) And $E0 // Copy EID<20:18> to SIDL<7:5>
INDF2 = INDF2 Or %00001000 // Set EXIDEN bit to SIDL<3>
POSTINC2 = INDF2 Or (value.Byte2 And $03) // Copy EID<17:16> to SIDL<1:0>
POSTINC2 = value.Byte1 // Copy EID<15:8> to EIDH<7:0>
INDF2 = value.Byte0 // Copy EID<7:0> to EIDL<7:0>
End If
Changed lines 353-376 from:
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
to:
{
****************************************************************************
* Name : RegsToCANID *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are used *
* If given id is extended identifier, *
* EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> *
* SIDH And SIDL is copied To bits value<28:18> *
****************************************************************************
}
Function RegsToCANID(CANreg As Word, flags As Byte) As LongWord
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
result.Byte0 = INDF2 << 3 // Copy SIDH<4:0> to SID<7:3>
result.Byte1 = POSTINC2 >> 5 // Copy SIDH<7:5> to SID<10:8>
result.Byte0 = result.Byte0 Or (INDF2 >> 5) // Copy SIDL<7:6> to SID<2:0>
result.Byte2 = $00
result.Byte3 = $00
Else // Extended Identifier
result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21>
result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25>
result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16>
result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18>
result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8>
result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0>
End If
End Function
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Save(FSR1, FSR2)
If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value.
buf = AddressOf(RXM0SIDH)
Else
buf = AddressOf(RXM1SIDH)
End If
CANIDToRegs(buf, value, flags)
Restore
End Sub
{
****************************************************************************
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
****************************************************************************
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Save(FSR1, FSR2)
Select filter
Case CAN_FILTER_B1_F1
buf = AddressOf(RXF0SIDH)
Case CAN_FILTER_B1_F2
buf = AddressOf(RXF1SIDH)
Case CAN_FILTER_B2_F1
buf = AddressOf(RXF2SIDH)
Case CAN_FILTER_B2_F2
buf = AddressOf(RXF3SIDH)
Case CAN_FILTER_B2_F3
buf = AddressOf(RXF4SIDH)
****************************************************************************
* Name : RegsToCANID *
* Purpose : If given id is standard identifier, *
* only SIDH and SIDL are used *
* If given id is extended identifier, *
* EIDH, EIDL And SIDH<1:0> is copied To bits value<17:0> *
* SIDH And SIDL is copied To bits value<28:18> *
****************************************************************************
}
Function RegsToCANID(CANreg As Word, flags As Byte) As LongWord
FSR2 = CANreg
If (flags And CAN_CONFIG_MSG_TYPE_BIT) <> 0 Then // Standard Identifier
result.Byte0 = INDF2 << 3 // Copy SIDH<4:0> to SID<7:3>
result.Byte1 = POSTINC2 >> 5 // Copy SIDH<7:5> to SID<10:8>
result.Byte0 = result.Byte0 Or (INDF2 >> 5) // Copy SIDL<7:6> to SID<2:0>
result.Byte2 = $00
result.Byte3 = $00
Else // Extended Identifier
result.Byte2 = INDF2 << 5 // Copy SIDH<2:0> to EID<23:21>
result.Byte3 = POSTINC2 >> 3 // Copy SIDH<7:3> to EID<29:25>
result.Byte2 = result.Byte2 Or (INDF2 And $03) // Copy SIDH<1:0> to EID<17:16>
result.Byte2 = result.Byte2 Or ((POSTINC2 And $E0) >> 3) // Copy SIDL<7:6> to EID<20:18>
result.Byte1 = POSTINC2 // Copy EIDH<15:8> to EID<15:8>
result.Byte0 = INDF2 // Copy EIDH<7:0> to EID<7:0>
End If
End Function
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Save(FSR1, FSR2)
If mask = CAN_MASK_B1 Then // Select appropriate starting address based on given CAN_MASK value.
buf = AddressOf(RXM0SIDH)
Else
buf = AddressOf(RXM1SIDH)
End If
CANIDToRegs(buf, value, flags)
Restore
End Sub
{
****************************************************************************
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
****************************************************************************
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
Dim buf As Word
Save(FSR1, FSR2)
Select filter
Case CAN_FILTER_B1_F1
buf = AddressOf(RXF0SIDH)
Case CAN_FILTER_B1_F2
buf = AddressOf(RXF1SIDH)
Case CAN_FILTER_B2_F1
buf = AddressOf(RXF2SIDH)
Case CAN_FILTER_B2_F2
buf = AddressOf(RXF3SIDH)
Case CAN_FILTER_B2_F3
buf = AddressOf(RXF4SIDH)
Changed lines 420-476 from:
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
DelayUS(1)
End Function
Dim i As Byte
While i < 9
DelayUS(1)
to:
buf = AddressOf(RXF5SIDH)
End Select
CANIDToRegs(buf, value, flags)
Restore
End Sub
{
****************************************************************************
* Name : CANInitialize *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
FilterConfig2 As Byte
Save(FSR1, FSR2)
#if _device in (18F248, 18F258, 18F448, 18F458, 18F2480, 18F2580, 18F4480, 18F4580, 18F2682, 18F2685, 18F4682, 18F4685)
TRISB.2 = 0 'TX CAN
TRISB.3 = 1 'RX CAN
#else
TRISG.0 = 0 'TX CAN
TRISG.2 = 1 'RX CAN
#endif
CIOCON = 0
CANSetOperationMode(CAN_OP_MODE_CONFIG) // In order to setup necessary config parameters of CAN module, it must be in Config mode.
#if _device in (18F248, 18F258, 18F448, 18F458)
Nop
#else
ECANCON = ECANCON And %00111111
#endif
CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate.
RXB0CON = flags And CAN_CONFIG_MSG_BITS
If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then
RXB0CON_RX0DBEN = 1
End If
RXB1CON = RXB0CON
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG) // Set default filter and mask registers for all receive buffers.
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG)
Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS)))
Case CAN_CONFIG_VALID_XTD_MSG
FilterConfig1 = CAN_CONFIG_XTD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
Case CAN_CONFIG_VALID_STD_MSG
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_STD_MSG
Else
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
End Select
CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored.
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1)
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2)
CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode.
Restore
End Select
CANIDToRegs(buf, value, flags)
Restore
End Sub
{
****************************************************************************
* Name : CANInitialize *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
Dim FilterConfig1 As Byte,
FilterConfig2 As Byte
Save(FSR1, FSR2)
#if _device in (18F248, 18F258, 18F448, 18F458, 18F2480, 18F2580, 18F4480, 18F4580, 18F2682, 18F2685, 18F4682, 18F4685)
TRISB.2 = 0 'TX CAN
TRISB.3 = 1 'RX CAN
#else
TRISG.0 = 0 'TX CAN
TRISG.2 = 1 'RX CAN
#endif
CIOCON = 0
CANSetOperationMode(CAN_OP_MODE_CONFIG) // In order to setup necessary config parameters of CAN module, it must be in Config mode.
#if _device in (18F248, 18F258, 18F448, 18F458)
Nop
#else
ECANCON = ECANCON And %00111111
#endif
CANSetBaudRate(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags) // Now set the baud rate.
RXB0CON = flags And CAN_CONFIG_MSG_BITS
If (flags And CAN_CONFIG_DBL_BUFFER_BIT) = CAN_CONFIG_DBL_BUFFER_ON Then
RXB0CON_RX0DBEN = 1
End If
RXB1CON = RXB0CON
CANSetMask(CAN_MASK_B1, 0, CAN_CONFIG_XTD_MSG) // Set default filter and mask registers for all receive buffers.
CANSetMask(CAN_MASK_B2, 0, CAN_CONFIG_XTD_MSG)
Select ((flags And CAN_CONFIG_MSG_BITS) Or (Not(CAN_CONFIG_MSG_BITS)))
Case CAN_CONFIG_VALID_XTD_MSG
FilterConfig1 = CAN_CONFIG_XTD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
Case CAN_CONFIG_VALID_STD_MSG
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_STD_MSG
Else
FilterConfig1 = CAN_CONFIG_STD_MSG
FilterConfig2 = CAN_CONFIG_XTD_MSG
End Select
CANSetFilter(CAN_FILTER_B1_F1, 0, FilterConfig1) // By default, there will be no mask on any receive filters, hence filter value of '0' will be ignored.
CANSetFilter(CAN_FILTER_B1_F2, 0, FilterConfig1)
CANSetFilter(CAN_FILTER_B2_F1, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F2, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F3, 0, FilterConfig2)
CANSetFilter(CAN_FILTER_B2_F4, 0, FilterConfig2)
CANSetOperationMode(CAN_OP_MODE_NORMAL) // Restore to Normal mode.
Restore
Changed lines 488-491 from:
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
to:
{
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte
Save(FSR1, FSR2)
FSR2 = AddressOf(TXB0CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then // Find the first empty transmitter.
// If TXB0CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer0 is empty. Set WIN bits to point to TXB0
CANCON = CANCON Or %00001000
Else
FSR2 = AddressOf(TXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB1CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1
CANCON = CANCON Or %00000110
Else
FSR2 = AddressOf(TXB2CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB2CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2
CANCON = CANCON Or %00000100
Else
result = false // None of the transmit buffers were empty.
Exit
End If
End If
End If
RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority.
If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired.
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG)
Else
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG)
End If
RXB0DLC = DataLen
If (flags And CAN_TX_RTR_BIT) = 0 Then
RXB0DLC = RXB0DLC Or %01000000
End If
i = 0
FSR2 = AddressOf(RXB0D0) // Populate data values.
FSR1 = AddressOf(Data)
While i < DataLen
POSTINC2 = POSTINC1
Inc(i)
Wend
ASM
bsf RXB0CON, 3
End ASM
CANCON = CANCON And %11110001
result = true
Restore
****************************************************************************
* Name : CANSendMessage *
* Purpose : If at least one empty transmit buffer is found, *
* given message is queued to be transmitted. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANSendMessage(id As LongWord, ByRef Data() As Byte, DataLen, flags As Byte) As Boolean
Dim i As Byte
Save(FSR1, FSR2)
FSR2 = AddressOf(TXB0CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then // Find the first empty transmitter.
// If TXB0CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer0 is empty. Set WIN bits to point to TXB0
CANCON = CANCON Or %00001000
Else
FSR2 = AddressOf(TXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB1CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer1 is empty. Set WIN bits to point to TXB1
CANCON = CANCON Or %00000110
Else
FSR2 = AddressOf(TXB2CON) // For compatibility with SwordfishSE
If INDF2.bits(TXREQ) = 0 Then
// If TXB2CON_TXREQ = 0 Then
CANCON = CANCON And %11110001 // TxBuffer2 is empty. Set WIN bits to point to TXB2
CANCON = CANCON Or %00000100
Else
result = false // None of the transmit buffers were empty.
Exit
End If
End If
End If
RXB0CON = flags And CAN_TX_PRIORITY_BITS // Set transmit priority.
If (flags And CAN_TX_FRAME_BIT) = 0 Then // Populate Extended identifier information only if it is desired.
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_XTD_MSG)
Else
CANIDToRegs(AddressOf(RXB0SIDH), id, CAN_CONFIG_STD_MSG)
End If
RXB0DLC = DataLen
If (flags And CAN_TX_RTR_BIT) = 0 Then
RXB0DLC = RXB0DLC Or %01000000
End If
i = 0
FSR2 = AddressOf(RXB0D0) // Populate data values.
FSR1 = AddressOf(Data)
While i < DataLen
POSTINC2 = POSTINC1
Inc(i)
Wend
ASM
bsf RXB0CON, 3
End ASM
CANCON = CANCON And %11110001
result = true
Restore
Changed lines 546-551 from:
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
to:
{
****************************************************************************
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i, buf As Byte,
lbIsItBuffer0 As Boolean
Save(FSR1, FSR2)
flags = 0 // Start with no error or flags set.
If RXB0CON_RXFUL = 1 Then // Find which buffer is ready.
CANCON = CANCON And %11110001 // RXBuffer0 is full.
lbIsItBuffer0 = true
PIR3_RXB0IF = 0 // Clear the received flag.
If COMSTAT_RX0OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX0OVFL = 0
End If
If RXB0CON_RX0DBEN = 1 Then
flags = (flags Or RXB0CON) And CAN_RX_FILTER_BITS
flags = flags And $01
End If
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(RXFUL) = 1 Then
// If RXB1CON_RXFUL = 1 Then
CANCON = CANCON And %11110001 // RXBuffer1 is full
CANCON = CANCON Or %00001010
lbIsItBuffer0 = false
PIR3_RXB1IF = 0 // Clear the received flag.
If COMSTAT_RX1OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX1OVFL = 0
End If
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
flags = (flags Or INDF2) And CAN_RX_FILTER_BITS
// flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS
If flags < $02 Then
flags = flags Or CAN_RX_DBL_BUFFERED
End If
Else
result = false
Exit
End If
End If
DataLen = RXB0DLC And %00001111 // Retrieve message length.
If RXB0DLC_RTR = 1 Then // Determine whether this was RTR or not.
flags = flags Or CAN_RX_RTR_FRAME
End If
If RXB0SIDL_EXID = 1 Then // Retrieve EIDX bytes only if this is extended message
flags = flags Or CAN_RX_XTD_FRAME
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_XTD_MSG)
Else
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG)
End If
i = 0
buf = DataLen // Get message data itself
FSR1 = AddressOf(RXB0D0)
FSR2 = AddressOf(Data)
While i < buf
POSTINC2 = POSTINC1
Inc(i)
Wend
CANCON = CANCON And %11110001 // Restore default RXB0 mapping.
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
result = true
Restore
****************************************************************************
* Name : CANReceiveMessage *
* Purpose : If at least one full receive buffer is found, *
* it is extrated and returned. *
* If none found FALSE value is returned. *
****************************************************************************
}
Public Function CANReceiveMessage(ByRef id As LongWord, ByRef Data(), DataLen, flags As Byte) As Boolean
Dim i, buf As Byte,
lbIsItBuffer0 As Boolean
Save(FSR1, FSR2)
flags = 0 // Start with no error or flags set.
If RXB0CON_RXFUL = 1 Then // Find which buffer is ready.
CANCON = CANCON And %11110001 // RXBuffer0 is full.
lbIsItBuffer0 = true
PIR3_RXB0IF = 0 // Clear the received flag.
If COMSTAT_RX0OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX0OVFL = 0
End If
If RXB0CON_RX0DBEN = 1 Then
flags = (flags Or RXB0CON) And CAN_RX_FILTER_BITS
flags = flags And $01
End If
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
If INDF2.bits(RXFUL) = 1 Then
// If RXB1CON_RXFUL = 1 Then
CANCON = CANCON And %11110001 // RXBuffer1 is full
CANCON = CANCON Or %00001010
lbIsItBuffer0 = false
PIR3_RXB1IF = 0 // Clear the received flag.
If COMSTAT_RX1OVFL = 1 Then // Record and forget any previous overflow
flags = flags Or CAN_RX_OVERFLOW
COMSTAT_RX1OVFL = 0
End If
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
flags = (flags Or INDF2) And CAN_RX_FILTER_BITS
// flags = (flags Or RXB1CON) And CAN_RX_FILTER_BITS
If flags < $02 Then
flags = flags Or CAN_RX_DBL_BUFFERED
End If
Else
result = false
Exit
End If
End If
DataLen = RXB0DLC And %00001111 // Retrieve message length.
If RXB0DLC_RTR = 1 Then // Determine whether this was RTR or not.
flags = flags Or CAN_RX_RTR_FRAME
End If
If RXB0SIDL_EXID = 1 Then // Retrieve EIDX bytes only if this is extended message
flags = flags Or CAN_RX_XTD_FRAME
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_XTD_MSG)
Else
id = RegsToCANID(AddressOf(RXB0SIDH), CAN_CONFIG_STD_MSG)
End If
i = 0
buf = DataLen // Get message data itself
FSR1 = AddressOf(RXB0D0)
FSR2 = AddressOf(Data)
While i < buf
POSTINC2 = POSTINC1
Inc(i)
Wend
CANCON = CANCON And %11110001 // Restore default RXB0 mapping.
If PIR3_IRXIF = 1 Then // Record and Clear any previous invalid message bit flag.
flags = flags Or CAN_RX_INVALID_MSG
PIR3_IRXIF = 0
End If
If lbIsItBuffer0 = true Then
RXB0CON_RXFUL = 0
Else
FSR2 = AddressOf(RXB1CON) // For compatibility with SwordfishSE
INDF2.bits(RXFUL) = 0
// RXB1CON_RXFUL = 0
End If
result = true
Restore
Deleted lines 626-797:
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
=] : 2 Home Made, MCU PIC18F458, MCP2515 CAN transceiver.
'''Available functions'''
=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]
For initialization you can choice between Sensirion_Init or Sensirion_Init_
You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
Changed lines 628-639 from:
******************************************************************************
*Name : Sensirion.BAS *
* Author : Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
*
*
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
**
to:
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
* Name : String2ID *
* Purpose : Transform 3 Char String into LongWord id *
****************************************************************************
Changed lines 633-909 from:
Include "math"
Include "system"
Const NoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pData) // get pin address
SPort.AddrTRIS = SPort.AddrPort + 18 // get pin TRIS address
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Sub Sensirion_Start()
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SData.PinMask // clear pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 Or SData.Pin // set pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
End Sub
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
Else
INDF2 = INDF2 Or SData.Pin // Set pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
result = buf
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
FSR2 = SPort.AddrPort
i = 0
While i < 8
If (data And 128) > 0 Then
INDF2 = INDF2 Or SData.Pin // Set pin SData
Else
INDF2 = INDF2 And SData.PinMask // clear pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then data = data << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) = 0 Then
result = true
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
End Function
Sub Sensirion_Reset()
Dim i As Byte
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
i = 0
While i < 9
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
Wend
Sensirion_Start
End Sub
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
End Function
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
to:
Public Function String2ID(str_in As String) As LongWord
Save(FSR2)
FSR2 = AddressOf(str_in)
result.Byte3 = 0
result.Byte2 = POSTINC2
result.Byte1 = POSTINC2
result.Byte0 = INDF2
Restore
End Function
Save(FSR2)
FSR2 = AddressOf(str_in)
result.Byte3 = 0
result.Byte2 = POSTINC2
result.Byte1 = POSTINC2
result.Byte0 = INDF2
Restore
End Function
Changed lines 8-12 from:
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
to:
{
****************************************************************************
* Name : CANInitialize *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
{
****************************************************************************
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
****************************************************************************
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
{
****************************************************************************
* Name : CANSetOperationMode *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
****************************************************************************
}
Public Sub CANSetOperationMode(mode As Byte)
****************************************************************************
* Name : CANInitialize *
* Purpose : Initialize CAN module, Filters, Mask *
* Input : SJW - SJW value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 4) *
* BRP - BRP value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 64) *
* PHSEG1 - PHSEG1 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PHSEG2 - PHSEG2 value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* PROPSEG - PROPSEG value as defined in 18CXX8 datasheet *
* (Must be between 1 thru 8) *
* flags - Value of CAN_CONFIG_FLAGS *
****************************************************************************
}
Public Sub CANInitialize(SJW, BRP, PHSEG1, PHSEG2, PROPSEG, flags As Byte)
{
****************************************************************************
* Name : CANSetFilter *
* Purpose : Given value is bit adjusted to appropriate buffer *
* filter registers. *
****************************************************************************
}
Public Sub CANSetFilter(filter As Byte, value As LongWord, flags As Byte)
{
****************************************************************************
* Name : CANSetMask *
* Purpose : Given value is bit adjusted to appropriate buffer *
* mask registers. *
****************************************************************************
}
Public Sub CANSetMask(mask As Byte, value As LongWord, flags As Byte)
{
****************************************************************************
* Name : CANSetOperationMode *
* Purpose : Given mode byte is copied to CANCON *
* and made sure that requested mode is set. *
****************************************************************************
}
Public Sub CANSetOperationMode(mode As Byte)
Added lines 1-725:
CAN BUS module available for Swordfish.
Test equipment : 2 Home Made boards, MCU PIC18F458, MCP2551 CAN transceiver.
'''Available functions'''
=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]
For initialization you can choice between Sensirion_Init or Sensirion_Init_
You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
* Name : Sensirion.BAS *
* Author : Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
}
Module Sensirion
Include "math"
Include "system"
Const NoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pData) // get pin address
SPort.AddrTRIS = SPort.AddrPort + 18 // get pin TRIS address
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Sub Sensirion_Start()
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SData.PinMask // clear pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 Or SData.Pin // set pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
End Sub
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
Else
INDF2 = INDF2 Or SData.Pin // Set pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
result = buf
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
FSR2 = SPort.AddrPort
i = 0
While i < 8
If (data And 128) > 0 Then
INDF2 = INDF2 Or SData.Pin // Set pin SData
Else
INDF2 = INDF2 And SData.PinMask // clear pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then data = data << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) = 0 Then
result = true
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
End Function
Sub Sensirion_Reset()
Dim i As Byte
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
i = 0
While i < 9
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
Wend
Sensirion_Start
End Sub
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
End Function
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
=] : 2 Home Made, MCU PIC18F458, MCP2515 CAN transceiver.
'''Available functions'''
=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]
For initialization you can choice between Sensirion_Init or Sensirion_Init_
You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
* Name : Sensirion.BAS *
* Author : Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
}
Module Sensirion
Include "math"
Include "system"
Const NoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pData) // get pin address
SPort.AddrTRIS = SPort.AddrPort + 18 // get pin TRIS address
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Sub Sensirion_Start()
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SData.PinMask // clear pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 Or SData.Pin // set pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
End Sub
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
Else
INDF2 = INDF2 Or SData.Pin // Set pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
result = buf
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
FSR2 = SPort.AddrPort
i = 0
While i < 8
If (data And 128) > 0 Then
INDF2 = INDF2 Or SData.Pin // Set pin SData
Else
INDF2 = INDF2 And SData.PinMask // clear pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then data = data << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) = 0 Then
result = true
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
End Function
Sub Sensirion_Reset()
Dim i As Byte
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
i = 0
While i < 9
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
Wend
Sensirion_Start
End Sub
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
End Function
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
=]
Test equipment : 2 Home Made boards, MCU PIC18F458, MCP2551 CAN transceiver.
'''Available functions'''
=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]
For initialization you can choice between Sensirion_Init or Sensirion_Init_
You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
* Name : Sensirion.BAS *
* Author : Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
}
Module Sensirion
Include "math"
Include "system"
Const NoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pData) // get pin address
SPort.AddrTRIS = SPort.AddrPort + 18 // get pin TRIS address
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Sub Sensirion_Start()
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SData.PinMask // clear pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 Or SData.Pin // set pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
End Sub
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
Else
INDF2 = INDF2 Or SData.Pin // Set pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
result = buf
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
FSR2 = SPort.AddrPort
i = 0
While i < 8
If (data And 128) > 0 Then
INDF2 = INDF2 Or SData.Pin // Set pin SData
Else
INDF2 = INDF2 And SData.PinMask // clear pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then data = data << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) = 0 Then
result = true
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
End Function
Sub Sensirion_Reset()
Dim i As Byte
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
i = 0
While i < 9
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
Wend
Sensirion_Start
End Sub
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
End Function
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
=] : 2 Home Made, MCU PIC18F458, MCP2515 CAN transceiver.
'''Available functions'''
=code [=
Sub Sensirion_Init(ByRef Port.(Data_Pin) As Bit, ByRef Port.(Clock_Pin) As Bit)
Sub Sensirion_Init_(ByRef Port As Byte, Data_Pin, Clock_Pin As Byte)
Function Sensirion_Get_Temp_Hum(ByRef temperature, humidity As Float) As Boolean
Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean // result will be multiplied by 100
Function Sensirion_Get_Dew_Point(ByRef temperature, humidity As Float) As Float
=]
For initialization you can choice between Sensirion_Init or Sensirion_Init_
You can download source code from : [[http://www.microelemente.ro/Swordfish/Sensirion.zip]]
!!!Example Code
=code [=
Device = 18F8520
Clock = 40
Config OSC = HSPLL
// some LCD options...
#option LCD_DATA = PORTH.4
#option LCD_RS = PORTH.2
#option LCD_EN = PORTH.3
// import LCD library...
Include "LCD.bas"
Include "Sensirion"
Include "convert.bas"
Dim NoError As Boolean
Dim temperature, humidity, dew_point As Float
Dim TempA, TempB As Byte
Dim buf As Integer
ADCON0 = 0
CMCON = $07 // turn off comparators
ADCON1 = $0F // turn off analog inputs
MEMCON.7 = 1 // disable external memory bus
Cls
//Sensirion.Sensirion_Init(PORTC.1, PORTC.2)
// Sensirion.Sensirion_Init(Port.(Data Pin), Port.(Clock pin))
// Data an Clock Pin must be at the same Port
// This is a wrong configuration :
// Sensirion.Sensirion_Init(PORTB.1, PORTD.2)
Sensirion.Sensirion_Init_(PORTC, 0, 1) // Sensirion.Sensirion_Init(Port, Data Pin, Clock Pin)
While true
NoError = Sensirion.Sensirion_Get_Temp_Hum(temperature, humidity)
If NoError Then
buf = temperature * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(1,1, " TS = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," ", 223, "C ")
buf = humidity * 100
TempA = buf / 100
TempB = buf Mod 100
LCD.WriteAt(2,1, " Rh = ",DecToStr(TempA,2),".",DecToStr(TempB,2)," "," % ")
dew_point = Sensirion.Sensirion_Get_Dew_Point(temperature, humidity)
Else
LCD.WriteAt(1,1, " Error detected ")
LCD.WriteAt(2,1, " Error detected ")
End If
DelayMS(2000)
Wend
=]
!!!Module Code
=code [=
{
******************************************************************************
* Name : Sensirion.BAS *
* Author : Medrea Florin Andrei *
* Notice : Copyright (c) 2007 -YO2LIO- *
* : All Rights Reserved *
* Date : 9/26/2007 *
* *
* Copyright Notice *
* *
* This library For the SHT temperature And humidity sensors is based on the *
* application datasheet Sample Code humidity sensor SHTxx from Sensirion. *
******************************************************************************
}
Module Sensirion
Include "math"
Include "system"
Const NoACK As Byte = 1,
ACK As Byte = 0,
CMD_STATUS_REG_W As Byte = $06,
CMD_STATUS_REG_R As Byte = $07,
CMD_TEMP As Byte = $03,
CMD_HUMIDITY As Byte = $05,
CMD_RESET As Byte = $1E
Structure TPin
Pin As Byte
PinMask As Byte
End Structure
Structure TPort
AddrPort As Word
AddrTRIS As Word
End Structure
Dim SData,SClock As TPin
Dim SPort As TPort
Dim data_h,data_l,data_cksum As Byte
Public Sub Sensirion_Init(ByRef pData As Bit, ByRef pClock As Bit)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pData) // get pin address
SPort.AddrTRIS = SPort.AddrPort + 18 // get pin TRIS address
SData.Pin = BitOf(pData) // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = BitOf(pClock) // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Public Sub Sensirion_Init_(ByRef pPort As Byte, pData, pClock As Byte)
ClrWDT
DelayMS(100)
ClrWDT
SPort.AddrPort = AddressOf(pPort) // get port address
SPort.AddrTRIS = SPort.AddrPort + 18 // get port TRIS address
SData.Pin = 1 << pData // get pin number
SData.PinMask = Not SData.Pin // create pin number mask
SClock.Pin = 1 << pClock // get pin number
SClock.PinMask = Not SClock.Pin // create pin number mask
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin
INDF2 = INDF2 And SClock.PinMask // clear pin
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
INDF2 = INDF2 And SClock.PinMask // make output SClock
End Sub
Sub Sensirion_Start()
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SData.PinMask // clear pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 Or SData.Pin // set pin SData
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
End Sub
Function Sensirion_Get_Byte(ack_ As Byte) As Byte
Dim i,buf As Byte
buf = 0
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
While i < 8
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) > 0 Then
buf = buf Or 1
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then buf = buf << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
If ack_ = 0 Then
INDF2 = INDF2 And SData.PinMask // clear pin SData
Else
INDF2 = INDF2 Or SData.Pin // Set pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
result = buf
End Function
Function Sensirion_Put_Byte(data As Byte) As Boolean
Dim i As Byte
result = false
FSR2 = SPort.AddrPort
i = 0
While i < 8
If (data And 128) > 0 Then
INDF2 = INDF2 Or SData.Pin // Set pin SData
Else
INDF2 = INDF2 And SData.PinMask // clear pin SData
End If
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
If i < 8 Then data = data << 1 End If
Wend
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
If (INDF2 And SData.Pin) = 0 Then
result = true
End If
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
End Function
Sub Sensirion_Reset()
Dim i As Byte
FSR2 = SPort.AddrPort
INDF2 = INDF2 Or SData.Pin // set pin SData
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
i = 0
While i < 9
INDF2 = INDF2 Or SClock.Pin // set pin SClock
DelayUS(1)
INDF2 = INDF2 And SClock.PinMask // clear pin SClock
DelayUS(1)
Inc(i)
Wend
Sensirion_Start
End Sub
Function Sensirion_Soft_Reset() As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_RESET)
End Function
Function Sensirion_Read_Status(ByRef sensirion_status, sensirion_cksum As Byte) As Boolean
Sensirion_Reset
result = Sensirion_Put_Byte(CMD_STATUS_REG_R)
sensirion_status = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Function Sensirion_Write_Status(data As Byte) As Boolean
Dim result1 As Boolean
Sensirion_Reset
result1 = Sensirion_Put_Byte(CMD_STATUS_REG_W)
result = result1 And Sensirion_Put_Byte(data)
End Function
Function Sensirion_Get(data As Byte, ByRef result_h,result_l,sensirion_cksum As Byte) As Boolean
Dim i As Word
result = false
Sensirion_Reset
Select data
Case CMD_TEMP result = Sensirion_Put_Byte(CMD_TEMP)
Case CMD_HUMIDITY result = Sensirion_Put_Byte(CMD_HUMIDITY)
Else Exit
End Select
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 Or SData.Pin // make input SData
FSR2 = SPort.AddrPort
i = 0
Repeat
ClrWDT
If (INDF2 And SData.Pin) = 0 Then
Break
End If
Inc(i)
DelayMS(1)
Until i > 500
If i > 500 Then
result = false
Exit
End If
FSR2 = SPort.AddrTRIS
INDF2 = INDF2 And SData.PinMask // make output SData
FSR2 = SPort.AddrPort
INDF2 = INDF2 And SData.PinMask // clear pin SData
result_h = Sensirion_Get_Byte(ACK)
result_l = Sensirion_Get_Byte(ACK)
sensirion_cksum = Sensirion_Get_Byte(NoACK)
End Function
Public Function Sensirion_Get_Temp_Hum(ByRef temp, hum As Float) As Boolean
Const T1 As Float = 0.01,
T2 As Float = 0.00008,
C1 As Float = -4.0,
C2 As Float = 0.0405,
C3 As Float = -0.0000028
Dim rh_lin, rh_true, tx As Float
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
buf.Byte0 = data_l
buf.Byte1 = data_h
tx = (buf * 0.01) - 40.0
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp = 0
hum = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (C3 * buf * buf) + (C2 * buf) + C1
rh_true = ((tx - 25.0) * (T1 + T2 * buf)) + rh_lin
If rh_true > 99.9 Then rh_true = 99.9 End If
If rh_true < 0.0 Then rh_true = 0.0 End If
temp = tx + 0.00001
hum = rh_true
End Function
Public Function Sensirion_Get_Temp_Hum_Dec(ByRef temp_d, hum_d As Integer) As Boolean
Const C1d As LongInt = -40000,
C2d As LongInt = 405,
C3d As LongInt = -28
Dim rh_lin, rh_true As LongInt
Dim result1 As Boolean
Dim buf As Word
result1 = Sensirion_Get(CMD_TEMP, data_h, data_l, data_cksum)
temp_d.Byte0 = data_l
temp_d.Byte1 = data_h
temp_d = temp_d - 4000
result = result1 And Sensirion_Get(CMD_HUMIDITY, data_h, data_l, data_cksum)
If result = false Then
temp_d = 0
hum_d = 0
Exit
End If
buf.Byte0 = data_l
buf.Byte1 = data_h
rh_lin = (((C3d * buf * buf) / 1000) + (C2d * buf) + C1d) / 100
rh_true = (((temp_d - 2500) * buf) / 12500) + rh_lin
If rh_true > 9999 Then rh_true = 9999 End If
If rh_true < 0 Then rh_true = 0 End If
hum_d = Integer(rh_true)
End Function
Public Function Sensirion_Get_Dew_Point(ByRef temp, hum As Float) As Float
Dim k As Float
k = ((log10(hum) - 2.0) / 0.4343) + ((17.62 * temp) / (243.12 + temp))
result = (243.12 * k) / (17.62 - k)
End Function
=]