EmbeddedRelated.com
Forums

1-wire and RCM3700???

Started by erikcoenders March 19, 2008
Hello everybody!

Has someone used DS18S20 thermometer with rabbit RCM3700 and have you
had any luck?

Is there a working source code available? How will look the 1-wire
interface (schematic)?

Any help would be highly appreciated!

Regards,

Erik

About OneWire:

You can use the following code, keeping in mind that the line is PDDR3 (portD, line 3) and the frequency is 11 MHz (for RCM2300). So you have to adapt the loops for your module (RCM3700).

int OW_Reset(void)
{
int present;
present = 0;

#asm
// Make output 0
ld a, (PDDRShadow)
res 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a

// Set line to output
call OW_Output

call OW_Tick // Sync with TICK_TIMER
; call OW_Tick // Wait a full tick

// Set line to input
call OW_Input

// Wait about 60 uSec
ld b, 60
call OW_Delay

#endasm
present = !BitRdPortI ( PDDR, 3 );
#asm
; wait 420 usec
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
#endasm

return(present);
}
void OW_Write(char data)
{

#asm
; digi srl
ld h, 8

et1: rrc l
jr nc, ZERO1

ONE1: call OW_Output
ld b, 2
call OW_Delay
call OW_Input
ld b, 100
call OW_Delay
jp wr1

ZERO1: call OW_Output
ld b, 100
call OW_Delay
call OW_Input
ld b, 2
call OW_Delay

wr1: dec h
jr nz, et1
;ret

#endasm
return;
}

char OW_Read(void)
{
auto int i,a,b;
auto char data;

for(i=0; i<8; i++)
{
#asm
call OW_Output
nop
call OW_Input
ld b, 5
call OW_Delay
#endasm

a = RdPortI (PDDR);
a= a & 0x08;
if(a)
data = data | 0x80;
if(i<7)
data = data >> 1;
}
return data;
}
//
// uSec Delay, counts b down
//
#asm
OW_Delay::
nop
nop
nop
nop
nop
nop
djnz OW_Delay
ret
#endasm

//
// Make wire Output
//
#asm
OW_Output::
ld a, (PDDDRShadow) // set data direction to output (low)
set 3, a // port D3
ioi ld (PDDDR), a
ld (PDDDRShadow), a
#endasm
#asm
OW_SetOut::
ld a, (PDDRShadow) // set output low.
res 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a

ret
#endasm
//
// Make wire input
//
#asm
OW_Input::
ld a, (PDDDRShadow) // set data direction to input (high)
res 3, a // port D3
ioi ld (PDDDR), a
ld (PDDDRShadow), a
#endasm
#asm
OW_ResOut::
ld a, (PDDRShadow) // set output low.
set 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a
ret
#endasm

#asm
OW_Write1::
call OW_Output
ld b, 15
call OW_Delay
call OW_Input
ld b, 45
call OW_Delay
call OW_Input
#endasm

#asm
OW_Write0::
call OW_Output
ld b, 60
call OW_Delay
ld b, 60
call OW_Delay
call OW_Input
#endasm
//
// Wait for TICK_TIMER change
//
#asm
OW_Tick::
ld ix, TICK_TIMER
ld a, (ix + 0)

// Sync with TICK_TIMER
OW_T10:
cp (ix + 0)
jp z, OW_T10

ret
#endasm

erikcoenders wrote: Hello everybody!

Has someone used DS18S20 thermometer with rabbit RCM3700 and have you
had any luck?

Is there a working source code available? How will look the 1-wire
interface (schematic)?

Any help would be highly appreciated!

Regards,

Erik

---------------------------------
Looking for last minute shopping deals? Find them fast with Yahoo! Search.
Here is the outline for the necessary functions. It supports the DS18B20
and the DS2401. It also includes the patch file for the bug on revision
B7 silicon which lost it's calibration values internal to the device.

Adjust the timer for the various delays required. This was not written
for a Rabbit but it should be easy to port across. Just change the
output pins.

#define TwoFourZerouS 215 // 490 uS delay 438
#define OneHundreduS 74 // 100 uS delay 84
#define FiftyuS 42 // 50 uS delay
#define FortyFiveuS 34 // 45 uS delay
#define ThirtyuS 24 // 30 uS delay
#define FifteenuS 8 // 15 uS delay
#define TenuS 4 // 10 uS delay

extern unsigned char serialnum[8];
extern unsigned char packet[8];
extern unsigned char scratchpad[9];

void Delay1uS (void)
{
_NOP ();
_NOP ();
}

// Pause for exactly 'tick' number of ticks = 0.558us
void tickDelay(int tick)
{
while (tick > 0)
tick --;
}

//-----
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
//
int OWTouchReset(void)
{
int result;
_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
tickDelay(TwoFourZerouS); // Delay 240 uS
tickDelay(TwoFourZerouS); // Delay 240 uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction
tickDelay(FiftyuS); // Delay 50 uS
tickDelay(FiftyuS); // Delay 50 uS
tickDelay(FiftyuS); // Delay 50 uS
result = (!(P3IN & 0x20)); // Sample DQ
tickDelay(TwoFourZerouS - OneHundreduS);// Complete the time slot to
490 uS
tickDelay(TwoFourZerouS); // Complete the time slot to
490 uS
_EINT();
return (result);
}
//-----
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
//
int OW2401Reset(void)
{
int result;
_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
tickDelay(TwoFourZerouS); // Delay 240 uS
tickDelay(TwoFourZerouS); // Delay 240 uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
tickDelay(FiftyuS); // Delay 50 uS
result = (!(P3IN & 0x20)); // Sample DQ
tickDelay(TwoFourZerouS - OneHundreduS);// Complete the time slot to
490 uS
tickDelay(TwoFourZerouS); // Complete the time slot to
490 uS
_EINT();
return (result);
}

//-----
// Send a 1-Wire write bit. Provide 10us recovery time.
//
void OWWriteBit(unsigned char bit)
{

_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
_NOP (); // Initiate transfer by pulling
_NOP (); // DQ low for at least 1uS
_NOP ();
_NOP ();

if (bit)
P3OUT |= 0x10; // Output 3.4 high (DQ)

tickDelay(OneHundreduS); // Hold bus low for 100uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction

_EINT();
}

//-----
// Write 1-Wire data byte
//
void OWWriteByte(unsigned char data)
{
char i;
unsigned char temp;

// Loop to write each bit in the byte, LS-bit first
for (i=0; i<8; i++)
{
temp = data >> i;
temp &= 0x01;
OWWriteBit(temp);
}
tickDelay(OneHundreduS); //
}

//-----
// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
//
unsigned char OWReadBit(void)
{
unsigned char result;

_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
_NOP (); // Initiate transfer by pulling
_NOP (); // DQ low for at least 1uS
_NOP ();
_NOP ();
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction

tickDelay(TenuS); // Wait 10uS
//tickDelay(ThirtyuS); // Wait 30uS
result = (P3IN & 0x20); // Sample pulse from slave
_EINT();
return(result); // Return status of DQ
}
//-----
// Read 1-Wire data byte and return it
//
unsigned char OWReadByte(void)
{
unsigned char i;
unsigned char result;
result=0;

for (i=0; i<8; i++)
{
if (OWReadBit()) result |= 0x01 << i;
_DINT ();
tickDelay(OneHundreduS); // Wait 100uS
_EINT ();
}
return result;
}
//-----
// Read 1-Wire data
//
void OWRead(unsigned char *data, char count)
{
char cc;
for (cc=0; cc {
data[cc]=OWReadByte();

}
}

//-----
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
int loop, result=0;

for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;

// If sending a '1' then read a bit else write a '0'
if (data & 0x01)
{
if (OWReadBit())
result |= 0x80;
}
else
OWWriteBit(0);

// shift the data byte for the next bit
data >>= 1;
}
return result;
}

//-----
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
int loop;

for (loop = 0; loop < data_len; loop++)
{
data[loop] = OWTouchByte(data[loop]);
}
}
char Reset18B20(void)
{
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
return(0);
}

char ReadSerial(void)
{
unsigned char n;
unsigned char CRC;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
return 0;
}
else
return 2;
}

char Read2401Serial(void)
{
unsigned char n;
unsigned char CRC;

if (OW2401Reset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
return 0;
}
else
return 2;
}

char TestSerial(void)
{
unsigned char n;
unsigned char CRC;

ReadFromFlash (&serialnum[0],0x1084,8); // Read old Serial No
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
if (memcmp(serialnum,packet,8) != 0)
{
memcpy(serialnum,packet,(sizeof(serialnum)));
return 3;
}
else
return 0;
}
else
return 2;
}

/* This addresses a problem in the DS18B20 Rev B7 Die
The Trim values can be corrupted on startup
This routine reads the trim values and stores them to flash
On startup and if the values have been stored before
A check is made to verify the integrity of the trim values
If they are corrupted they are then replaced with the
previously stored correct values
*/

char ReadTrim(void)
{
unsigned char SavedTrim[4];
unsigned char SensorTrim[2];
unsigned char Header1,Header2;
char valid,SameSensor;

valid = 0;
Header1 = 0xAA;
Header2 = 0x55;

// Test if 18B20 has been replaced...
SameSensor = TestSerial();
// Check if Trim Values have been saved
ReadFromFlash (SavedTrim,0x1080,4);
if ( (SavedTrim[2] == Header1) && (SavedTrim[3] == Header2))
valid = 1;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x93); // SEND READ TRIM VALUE 1
OWRead(&SensorTrim[0],1); // READ TRIM VALUE 1

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x68); // SEND READ TRIM VALUE 2
OWRead(&SensorTrim[1],1); // READ TRIM VALUE 2

// Data not yet stored or 18B20 sensor replaced
if ( (valid == 0) || (SameSensor == 3) )
{
P1OUT = (P1OUT & ~0x08); // LED 3 ON
EraseFlashSector (0x1080);
WriteToFlash (&SensorTrim[0],0x1080,1);
WriteToFlash (&SensorTrim[1],0x1081,1);
WriteToFlash (&Header1,0x1082,1);
WriteToFlash (&Header2,0x1083,1);
WriteToFlash (&serialnum[0],0x1084,8);
P1OUT |= 0x08; // LED 2 OFF
}

if ( (valid == 1) && (SameSensor == 0) )
{
if ( (SensorTrim[0] != SavedTrim[0]) || (SensorTrim[1] !SavedTrim[1]) )
{

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x68); //
OWRead(scratchpad,1); // Dummy Read

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x95); // Address of Trim1
OWWriteByte(SavedTrim[0]); // SEND TRIM VALUE 1 to RAM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x63); // Address of Trim2
OWWriteByte(SavedTrim[1]); // SEND TRIM VALUE 2 to RAM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x94); // Copy to EEPROM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x48); // Copy to EEPROM

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
}
else
{
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
}
}
return(0);
}

char ReadTemp(void)
{
unsigned char CRC;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x44); // SEND START CONVERSION COMMAND
wait (100);
//_DINT ();
//tickDelay(TenuS); // Wait 10uS
//tickDelay(OneHundreduS); // Wait 100uS
//_EINT ();
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0xBE); // SEND READ SCRATCHPAD COMMAND
wait (100);
OWRead(scratchpad,9); // READ 9 BYTES

CRC = CalcCRC(scratchpad, 8); // Calculate CRC

if (CRC == scratchpad[8]) // Compare CRCs
return 0;
else
return 2;
}
unsigned char CalcCRC(unsigned char *buff, unsigned char num_vals)
{
unsigned char Shift_Reg;
unsigned char SR_lsb;
unsigned char Data_Bit;
unsigned char FB_bit;
unsigned char I;
unsigned char j,temp;

Shift_Reg = 0;
for (I=0;I {
temp = buff[I];
for (j=0;j<8;j++)
{
Data_Bit = (temp & 0x01);
SR_lsb = (Shift_Reg & 0x01);
FB_bit = ( (Data_Bit ^ SR_lsb) & 0x01);
Shift_Reg = Shift_Reg >> 1;

if (FB_bit == 1)
Shift_Reg ^= 0x8C;
temp = temp >> 1;
}
}
return(Shift_Reg);
}

Adrian Mojoatca wrote:
>
> About OneWire:
>
> You can use the following code, keeping in mind that the line is PDDR3
> (portD, line 3) and the frequency is 11 MHz (for RCM2300). So you have
> to adapt the loops for your module (RCM3700).
>
> int OW_Reset(void)
> {
> int present;
> present = 0;
>
> #asm
> // Make output 0
> ld a, (PDDRShadow)
> res 3, a // port D3
> ioi ld (PDDR), a
> ld (PDDRShadow), a
>
> // Set line to output
> call OW_Output
>
> call OW_Tick // Sync with TICK_TIMER
> ; call OW_Tick // Wait a full tick
>
> // Set line to input
> call OW_Input
>
> // Wait about 60 uSec
> ld b, 60
> call OW_Delay
>
> #endasm
> present = !BitRdPortI ( PDDR, 3 );
> #asm
> ; wait 420 usec
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> ld b, 80
> call OW_Delay
> #endasm
>
> return(present);
> }
> void OW_Write(char data)
> {
>
> #asm
> ; digi srl
> ld h, 8
>
> et1: rrc l
> jr nc, ZERO1
>
> ONE1: call OW_Output
> ld b, 2
> call OW_Delay
> call OW_Input
> ld b, 100
> call OW_Delay
> jp wr1
>
> ZERO1: call OW_Output
> ld b, 100
> call OW_Delay
> call OW_Input
> ld b, 2
> call OW_Delay
>
> wr1: dec h
> jr nz, et1
> ;ret
>
> #endasm
> return;
> }
>
> char OW_Read(void)
> {
> auto int i,a,b;
> auto char data;
>
> for(i=0; i<8; i++)
> {
> #asm
> call OW_Output
> nop
> call OW_Input
> ld b, 5
> call OW_Delay
> #endasm
>
> a = RdPortI (PDDR);
> a= a & 0x08;
> if(a)
> data = data | 0x80;
> if(i<7)
> data = data >> 1;
> }
> return data;
> }
> //
> // uSec Delay, counts b down
> //
> #asm
> OW_Delay::
> nop
> nop
> nop
> nop
> nop
> nop
> djnz OW_Delay
> ret
> #endasm
>
> //
> // Make wire Output
> //
> #asm
> OW_Output::
> ld a, (PDDDRShadow) // set data direction to output (low)
> set 3, a // port D3
> ioi ld (PDDDR), a
> ld (PDDDRShadow), a
> #endasm
> #asm
> OW_SetOut::
> ld a, (PDDRShadow) // set output low.
> res 3, a // port D3
> ioi ld (PDDR), a
> ld (PDDRShadow), a
>
> ret
> #endasm
> //
> // Make wire input
> //
> #asm
> OW_Input::
> ld a, (PDDDRShadow) // set data direction to input (high)
> res 3, a // port D3
> ioi ld (PDDDR), a
> ld (PDDDRShadow), a
> #endasm
> #asm
> OW_ResOut::
> ld a, (PDDRShadow) // set output low.
> set 3, a // port D3
> ioi ld (PDDR), a
> ld (PDDRShadow), a
> ret
> #endasm
>
> #asm
> OW_Write1::
> call OW_Output
> ld b, 15
> call OW_Delay
> call OW_Input
> ld b, 45
> call OW_Delay
> call OW_Input
> #endasm
>
> #asm
> OW_Write0::
> call OW_Output
> ld b, 60
> call OW_Delay
> ld b, 60
> call OW_Delay
> call OW_Input
> #endasm
> //
> // Wait for TICK_TIMER change
> //
> #asm
> OW_Tick::
> ld ix, TICK_TIMER
> ld a, (ix + 0)
>
> // Sync with TICK_TIMER
> OW_T10:
> cp (ix + 0)
> jp z, OW_T10
>
> ret
> #endasm
>
> */erikcoenders /* wrote:
>
> Hello everybody!
>
> Has someone used DS18S20 thermometer with rabbit RCM3700 and have you
> had any luck?
>
> Is there a working source code available? How will look the 1-wire
> interface (schematic)?
>
> Any help would be highly appreciated!
>
> Regards,
>
> Erik
>
> Looking for last minute shopping deals? Find them fast with Yahoo!
> Search.
>
Just an alternative:

You can use a table in order to make the CRC:

const byte Table[256] {0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147,205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};

... and make the CRC as follows:

unsigned char CalcCRC(unsigned char *buff, unsigned char num_vals)
{
int i;
unsigned char CRC;
CRC = 0;
for ( i = 0; i < num_vals; i++ )
{
CRC = Table[CRC^buff[i]];
}
return CRC;
}

Alexis wrote:
Here is the outline for the necessary functions. It supports the DS18B20 and the DS2401. It also includes the patch file for the bug on revision B7 silicon which lost it's calibration values internal to the device.

Adjust the timer for the various delays required. This was not written for a Rabbit but it should be easy to port across. Just change the output pins.

#define TwoFourZerouS 215 // 490 uS delay 438
#define OneHundreduS 74 // 100 uS delay 84
#define FiftyuS 42 // 50 uS delay
#define FortyFiveuS 34 // 45 uS delay
#define ThirtyuS 24 // 30 uS delay
#define FifteenuS 8 // 15 uS delay
#define TenuS 4 // 10 uS delay

extern unsigned char serialnum[8];
extern unsigned char packet[8];
extern unsigned char scratchpad[9];

void Delay1uS (void)
{
_NOP ();
_NOP ();
}

// Pause for exactly 'tick' number of ticks = 0.558us
void tickDelay(int tick)
{
while (tick > 0)
tick --;
}

//-----
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
//
int OWTouchReset(void)
{
int result;
_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
tickDelay(TwoFourZerouS); // Delay 240 uS
tickDelay(TwoFourZerouS); // Delay 240 uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction
tickDelay(FiftyuS); // Delay 50 uS
tickDelay(FiftyuS); // Delay 50 uS
tickDelay(FiftyuS); // Delay 50 uS
result = (!(P3IN & 0x20)); // Sample DQ
tickDelay(TwoFourZerouS - OneHundreduS);// Complete the time slot to 490 uS
tickDelay(TwoFourZerouS); // Complete the time slot to 490 uS
_EINT();
return (result);
}

//-----
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
//
int OW2401Reset(void)
{
int result;
_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
tickDelay(TwoFourZerouS); // Delay 240 uS
tickDelay(TwoFourZerouS); // Delay 240 uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
tickDelay(FiftyuS); // Delay 50 uS
result = (!(P3IN & 0x20)); // Sample DQ
tickDelay(TwoFourZerouS - OneHundreduS);// Complete the time slot to 490 uS
tickDelay(TwoFourZerouS); // Complete the time slot to 490 uS
_EINT();
return (result);
}

//-----
// Send a 1-Wire write bit. Provide 10us recovery time.
//
void OWWriteBit(unsigned char bit)
{

_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
_NOP (); // Initiate transfer by pulling
_NOP (); // DQ low for at least 1uS
_NOP ();
_NOP ();

if (bit)
P3OUT |= 0x10; // Output 3.4 high (DQ)

tickDelay(OneHundreduS); // Hold bus low for 100uS
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction

_EINT();
}

//-----
// Write 1-Wire data byte
//
void OWWriteByte(unsigned char data)
{
char i;
unsigned char temp;

// Loop to write each bit in the byte, LS-bit first
for (i=0; i<8; i++)
{
temp = data >> i;
temp &= 0x01;
OWWriteBit(temp);
}
tickDelay(OneHundreduS); //
}

//-----
// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
//
unsigned char OWReadBit(void)
{
unsigned char result;

_DINT();
P3DIR = 0x1B; // P3.0, 1, 3, 4 output direction
P3OUT &= ~0x10; // Output 3.4 low (DQ)
_NOP (); // Initiate transfer by pulling
_NOP (); // DQ low for at least 1uS
_NOP ();
_NOP ();
P3OUT |= 0x10; // Output 3.4 high (DQ)
P3DIR = 0x0B; // P3.0, 1, 3, output direction

tickDelay(TenuS); // Wait 10uS
//tickDelay(ThirtyuS); // Wait 30uS
result = (P3IN & 0x20); // Sample pulse from slave
_EINT();
return(result); // Return status of DQ
}

//-----
// Read 1-Wire data byte and return it
//
unsigned char OWReadByte(void)
{
unsigned char i;
unsigned char result;
result=0;

for (i=0; i<8; i++)
{
if (OWReadBit()) result |= 0x01 << i;
_DINT ();
tickDelay(OneHundreduS); // Wait 100uS
_EINT ();
}
return result;
}
//-----
// Read 1-Wire data
//
void OWRead(unsigned char *data, char count)
{
char cc;
for (cc=0; cc {
data[cc]=OWReadByte();

}
}

//-----
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
int loop, result=0;

for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;

// If sending a '1' then read a bit else write a '0'
if (data & 0x01)
{
if (OWReadBit())
result |= 0x80;
}
else
OWWriteBit(0);

// shift the data byte for the next bit
data >>= 1;
}
return result;
}

//-----
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
int loop;

for (loop = 0; loop < data_len; loop++)
{
data[loop] = OWTouchByte(data[loop]);
}
}

char Reset18B20(void)
{
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
return(0);
}

char ReadSerial(void)
{
unsigned char n;
unsigned char CRC;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
return 0;
}
else
return 2;
}

char Read2401Serial(void)
{
unsigned char n;
unsigned char CRC;

if (OW2401Reset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
return 0;
}
else
return 2;
}

char TestSerial(void)
{
unsigned char n;
unsigned char CRC;

ReadFromFlash (&serialnum[0],0x1084,8); // Read old Serial No
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0x33); // SEND READ ID COMMAND
OWRead(packet,8); // READ 8 BYTES
CRC = CalcCRC(packet, 7); // Calculate CRC
if (CRC == packet[7]) // Compare CRCs
{
if (memcmp(serialnum,packet,8) != 0)
{
memcpy(serialnum,packet,(sizeof(serialnum)));
return 3;
}
else
return 0;
}
else
return 2;
}

/* This addresses a problem in the DS18B20 Rev B7 Die
The Trim values can be corrupted on startup
This routine reads the trim values and stores them to flash
On startup and if the values have been stored before
A check is made to verify the integrity of the trim values
If they are corrupted they are then replaced with the
previously stored correct values
*/

char ReadTrim(void)
{
unsigned char SavedTrim[4];
unsigned char SensorTrim[2];
unsigned char Header1,Header2;
char valid,SameSensor;

valid = 0;
Header1 = 0xAA;
Header2 = 0x55;

// Test if 18B20 has been replaced...
SameSensor = TestSerial();
// Check if Trim Values have been saved
ReadFromFlash (SavedTrim,0x1080,4);
if ( (SavedTrim[2] == Header1) && (SavedTrim[3] == Header2))
valid = 1;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x93); // SEND READ TRIM VALUE 1
OWRead(&SensorTrim[0],1); // READ TRIM VALUE 1

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x68); // SEND READ TRIM VALUE 2
OWRead(&SensorTrim[1],1); // READ TRIM VALUE 2

// Data not yet stored or 18B20 sensor replaced
if ( (valid == 0) || (SameSensor == 3) )
{
P1OUT = (P1OUT & ~0x08); // LED 3 ON
EraseFlashSector (0x1080);
WriteToFlash (&SensorTrim[0],0x1080,1);
WriteToFlash (&SensorTrim[1],0x1081,1);
WriteToFlash (&Header1,0x1082,1);
WriteToFlash (&Header2,0x1083,1);
WriteToFlash (&serialnum[0],0x1084,8);
P1OUT |= 0x08; // LED 2 OFF
}

if ( (valid == 1) && (SameSensor == 0) )
{
if ( (SensorTrim[0] != SavedTrim[0]) || (SensorTrim[1] != SavedTrim[1]) )
{

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x68); //
OWRead(scratchpad,1); // Dummy Read

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x95); // Address of Trim1
OWWriteByte(SavedTrim[0]); // SEND TRIM VALUE 1 to RAM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x63); // Address of Trim2
OWWriteByte(SavedTrim[1]); // SEND TRIM VALUE 2 to RAM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x94); // Copy to EEPROM

P1OUT = (P1OUT & ~0x08); // LED 3 ON
if (OWTouchReset()) return 1; // CALL RESET
P1OUT |= 0x08; // LED 3 OFF
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x48); // Copy to EEPROM

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
}
else
{
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x64); // Reset 18B20
}
}
return(0);
}

char ReadTemp(void)
{
unsigned char CRC;

if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0x44); // SEND START CONVERSION COMMAND
wait (100);
//_DINT ();
//tickDelay(TenuS); // Wait 10uS
//tickDelay(OneHundreduS); // Wait 100uS
//_EINT ();
if (OWTouchReset()) return 1; // CALL RESET
OWWriteByte(0xCC); // SEND SKIP ROM COMMAND
OWWriteByte(0xBE); // SEND READ SCRATCHPAD COMMAND
wait (100);
OWRead(scratchpad,9); // READ 9 BYTES

CRC = CalcCRC(scratchpad, 8); // Calculate CRC

if (CRC == scratchpad[8]) // Compare CRCs
return 0;
else
return 2;
}

unsigned char CalcCRC(unsigned char *buff, unsigned char num_vals)
{
unsigned char Shift_Reg;
unsigned char SR_lsb;
unsigned char Data_Bit;
unsigned char FB_bit;
unsigned char I;
unsigned char j,temp;

Shift_Reg = 0;
for (I=0;I {
temp = buff[I];
for (j=0;j<8;j++)
{
Data_Bit = (temp & 0x01);
SR_lsb = (Shift_Reg & 0x01);
FB_bit = ( (Data_Bit ^ SR_lsb) & 0x01);
Shift_Reg = Shift_Reg >> 1;

if (FB_bit == 1)
Shift_Reg ^= 0x8C;
temp = temp >> 1;
}
}
return(Shift_Reg);
}

Adrian Mojoatca wrote:
About OneWire:

You can use the following code, keeping in mind that the line is PDDR3 (portD, line 3) and the frequency is 11 MHz (for RCM2300). So you have to adapt the loops for your module (RCM3700).

int OW_Reset(void)
{
int present;
present = 0;

#asm
// Make output 0
ld a, (PDDRShadow)
res 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a

// Set line to output
call OW_Output

call OW_Tick // Sync with TICK_TIMER
; call OW_Tick // Wait a full tick

// Set line to input
call OW_Input

// Wait about 60 uSec
ld b, 60
call OW_Delay

#endasm
present = !BitRdPortI ( PDDR, 3 );
#asm
; wait 420 usec
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
ld b, 80
call OW_Delay
#endasm

return(present);
}

void OW_Write(char data)
{

#asm
; digi srl
ld h, 8

et1: rrc l
jr nc, ZERO1

ONE1: call OW_Output
ld b, 2
call OW_Delay
call OW_Input
ld b, 100
call OW_Delay
jp wr1

ZERO1: call OW_Output
ld b, 100
call OW_Delay
call OW_Input
ld b, 2
call OW_Delay

wr1: dec h
jr nz, et1
;ret

#endasm
return;
}

char OW_Read(void)
{
auto int i,a,b;
auto char data;

for(i=0; i<8; i++)
{
#asm
call OW_Output
nop
call OW_Input
ld b, 5
call OW_Delay
#endasm

a = RdPortI (PDDR);
a= a & 0x08;
if(a)
data = data | 0x80;
if(i<7)
data = data >> 1;
}
return data;
}

//
// uSec Delay, counts b down
//
#asm
OW_Delay::
nop
nop
nop
nop
nop
nop
djnz OW_Delay
ret
#endasm

//
// Make wire Output
//
#asm
OW_Output::
ld a, (PDDDRShadow) // set data direction to output (low)
set 3, a // port D3
ioi ld (PDDDR), a
ld (PDDDRShadow), a
#endasm
#asm
OW_SetOut::
ld a, (PDDRShadow) // set output low.
res 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a

ret
#endasm

//
// Make wire input
//
#asm
OW_Input::
ld a, (PDDDRShadow) // set data direction to input (high)
res 3, a // port D3
ioi ld (PDDDR), a
ld (PDDDRShadow), a
#endasm
#asm
OW_ResOut::
ld a, (PDDRShadow) // set output low.
set 3, a // port D3
ioi ld (PDDR), a
ld (PDDRShadow), a
ret
#endasm

#asm
OW_Write1::
call OW_Output
ld b, 15
call OW_Delay
call OW_Input
ld b, 45
call OW_Delay
call OW_Input
#endasm

#asm
OW_Write0::
call OW_Output
ld b, 60
call OW_Delay
ld b, 60
call OW_Delay
call OW_Input
#endasm

//
// Wait for TICK_TIMER change
//
#asm
OW_Tick::
ld ix, TICK_TIMER
ld a, (ix + 0)

// Sync with TICK_TIMER
OW_T10:
cp (ix + 0)
jp z, OW_T10

ret
#endasm

erikcoenders wrote:
Hello everybody!

Has someone used DS18S20 thermometer with rabbit RCM3700 and have you
had any luck?

Is there a working source code available? How will look the 1-wire
interface (schematic)?

Any help would be highly appreciated!

Regards,

Erik

---------------------------------
Looking for last minute shopping deals? Find them fast with Yahoo! Search.

---------------------------------
Never miss a thing. Make Yahoo your homepage.