📄 thermo21.c
字号:
{
sprintf(msg,"Thermochron not on 1-Wire Net");
*Status = STATUS_INPROGRESS;
}
default:
break;
}
return *Status;
}
//----------------------------------------------------------------------
// Read a specified number of pages in overdrive
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
int ReadPages(int portnum, int start_pg, int num_pgs, int *last_pg, uchar *finalbuf)
{
int skip_overaccess = 0, skip_access = 0;
uchar pkt[60];
int len,i;
uchar SerialNumber[8];
ushort lastcrc16;
// read the rom number
owSerialNum(portnum,SerialNumber,TRUE);
// verify device is in overdrive
if (current_speed[portnum] == MODE_OVERDRIVE)
{
if (owVerify(portnum,FALSE))
skip_overaccess = 1;
}
if (!skip_overaccess)
{
if (owOverdriveAccess(portnum))
current_speed[portnum] = MODE_OVERDRIVE;
else
current_speed[portnum] = MODE_NORMAL;
}
// loop while there is pages to read
do
{
// create a packet to read a page
len = 0;
setcrc16(portnum,0);
// optional skip access on subsequent pages
if (!skip_access)
{
// match
pkt[len++] = 0x55;
// rom number
for (i = 0; i < 8; i++)
pkt[len++] = SerialNumber[i];
// read memory with crc command
pkt[len] = 0xA5;
docrc16(portnum,pkt[len++]);
// address
pkt[len] = (uchar)((*last_pg << 5) & 0xFF);
docrc16(portnum,pkt[len++]);
pkt[len] = (uchar)(*last_pg >> 3);
docrc16(portnum,pkt[len++]);
}
// set 32 reads for data and 2 for crc
for (i = 0; i < 34; i++)
pkt[len++] = 0xFF;
// send the bytes
if (owBlock(portnum,!skip_access,pkt,len))
{
// calucate the CRC over the last 34 bytes
for (i = 0; i < 34; i++)
lastcrc16 = docrc16(portnum,pkt[len - 34 + i]);
// check crc
if (lastcrc16 == 0xB001)
{
// copy the data into the buffer
#ifdef LetsCrashTheCompiler
for (i = 0; i < 32; i++)
finalbuf[i + (*last_pg - start_pg) * 32] = pkt[len - 34 + i];
#endif
{
ushort k;
for (i = 0; i < 32; i++) {
k=i + (*last_pg - start_pg) * 32;
finalbuf[k] = pkt[len - 34 + i];
}
}
// change number of pages
*last_pg = *last_pg + 1;
// now skip access
skip_access = TRUE;
}
else
return FALSE;
}
else
return FALSE;
}
while ((*last_pg - start_pg) < num_pgs);
return TRUE;
}
//----------------------------------------------------------------------------}
// Write a memory location. Data must all be on the same page
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
int WriteMemory(int portnum, uchar *Buf, int ln, int adr)
{
// write to scratch and then copy
if (WriteScratch(portnum,Buf,ln,adr))
return CopyScratch(portnum,ln,adr);
return FALSE;
}
//----------------------------------------------------------------------------}
// Write the scratch pad
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
int WriteScratch(int portnum, uchar *Buf, int ln, int adr)
{
int i;
uchar pbuf[80];
// check for alarm indicator
if (owAccess(portnum))
{
// construct a packet to send
pbuf[0] = 0x0F; // write scratch command
pbuf[1] = (adr & 0xFF); // address 1
pbuf[2] = ((adr >> 8) & 0xFF); // address 2
// the write bytes
for (i = 0; i < ln; i++)
pbuf[3 + i] = (uchar)(Buf[i]); // data
// perform the block
if (!owBlock(portnum,FALSE,pbuf,ln+3))
return FALSE;
// Now read back the scratch
if (owAccess(portnum))
{
// construct a packet to send
pbuf[0] = 0xAA; // read scratch command
pbuf[1] = 0xFF; // address 1
pbuf[2] = 0xFF; // address 2
pbuf[3] = 0xFF; // offset
// the write bytes
for (i = 0; i < ln; i++)
pbuf[4 + i] = 0xFF; // data
// perform the block
if (!owBlock(portnum,FALSE,pbuf,ln+4))
return FALSE;
// read address 1
if (pbuf[1] != (adr & 0xFF))
return FALSE;
// read address 2
if (pbuf[2] != ((adr >> 8) & 0xFF))
return FALSE;
// read the offset
if (pbuf[3] != ((adr + ln - 1) & 0x1F))
return FALSE;
// read and compare the contents
for (i = 0; i < ln; i++)
{
if (pbuf[4 + i] != Buf[i])
return FALSE;
}
// success
return TRUE;
}
}
return FALSE;
}
//----------------------------------------------------------------------------}
// Copy the scratch pad
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
int CopyScratch(int portnum, int ln, int adr)
{
int i;
uchar pbuf[50];
// check for alarm indicator
if (owAccess(portnum))
{
// construct a packet to send
pbuf[0] = 0x55; // copy scratch command
pbuf[1] = (adr & 0xFF); // address 1
pbuf[2] = ((adr >> 8) & 0xFF); // address 2
pbuf[3] = (adr + ln - 1) & 0x1F; // offset
for (i = 0; i <= 9; i++)
pbuf[4 + i] = 0xFF; // result of copy
// perform the block
if (owBlock(portnum,FALSE,pbuf,14))
{
if ((pbuf[13] == 0x55) ||
(pbuf[13] == 0xAA))
return TRUE;
}
}
return FALSE;
}
//----------------------------------------------------------------------
// Interpret the Status by looking at the 'raw' portion of the
// mission status structure.
//
void InterpretStatus(MissionStatus *mstatus)
{
timedate td,tdtmp;
int offset;
ulong tmtmp;
time_t tlong;
struct tm *tstruct;
// mission in progress flag
mstatus->mission_in_progress = (0x20 & mstatus->status_raw[0x14]) >> 5;
// sample rate
mstatus->sample_rate = mstatus->status_raw[0x0D];
// rollover enabled
mstatus->rollover_enable = (0x08 & mstatus->status_raw[0x0E]) >> 3;
// startdelay
mstatus->start_delay = ((int)mstatus->status_raw[0x13] << 8) |
mstatus->status_raw[0x12];
// number of samples in this mission
mstatus->mission_samples = ((long)mstatus->status_raw[0x1C] << 16) |
((int)mstatus->status_raw[0x1B] << 8) |
mstatus->status_raw[0x1A];
// total number of samples
mstatus->samples_total = ((long)mstatus->status_raw[0x1F] << 16) |
((int)mstatus->status_raw[0x1E] << 8) |
mstatus->status_raw[0x1D];
// temperature thresholds
mstatus->high_threshold = mstatus->status_raw[0x0C];
mstatus->low_threshold = mstatus->status_raw[0x0B];
// rollover occurred
if ((mstatus->mission_samples > 2048) && mstatus->rollover_enable)
mstatus->rollover_occurred = 1;
else
mstatus->rollover_occurred = 0;
// current real-time clock value
offset = 0x00;
td.second = BCDToBin((uchar)(mstatus->status_raw[offset] & 0x7F));
td.minute = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x7F));
// check for 12 hour mode
if (mstatus->status_raw[offset + 2] & 0x40)
{
td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x1F));
// check for PM
if (mstatus->status_raw[offset + 2] & 0x20)
td.hour += 12;
}
else
td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x3F));
td.day = BCDToBin((uchar)(mstatus->status_raw[offset + 4] & 0x3F));
td.month = BCDToBin((uchar)(mstatus->status_raw[offset + 5] & 0x1F));
td.year = BCDToBin(mstatus->status_raw[offset + 6]) + 1900;
// check for century bit
if (mstatus->status_raw[offset + 5] & 0x80)
td.year = BCDToBin(mstatus->status_raw[offset + 6]) + 2000; // (2.00)
// convert to seconds since 1970
mstatus->current_time = DateToSeconds(&td);
// date/time when mission started
offset = 0x15;
td.second = (uchar)0;
td.minute = BCDToBin((uchar)(mstatus->status_raw[offset] & 0x7F));
// check for 12 hour mode
if (mstatus->status_raw[offset + 1] & 0x40)
{
td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x1F));
// check for PM
if (mstatus->status_raw[offset + 1] & 0x20)
td.hour += 12;
}
else
td.hour = BCDToBin((uchar)(mstatus->status_raw[offset + 1] & 0x3F));
td.day = BCDToBin((uchar)(mstatus->status_raw[offset + 2] & 0x3F));
td.month = BCDToBin((uchar)(mstatus->status_raw[offset + 3] & 0x1F));
td.year = BCDToBin((uchar)(mstatus->status_raw[offset + 4])); // (2.00)
// (2.00) logic to decide on century of mission stamp
// check if century bit set in mission stamp
if (mstatus->status_raw[offset + 3] & 0x80)
td.year += 2000;
// check in mission in progress
else if (mstatus->mission_in_progress)
{
// calculate the mission start year back from real time clock
tmtmp = mstatus->current_time -
(mstatus->sample_rate * mstatus->mission_samples * 60);
SecondsToDate(&tdtmp,tmtmp);
td.year = tdtmp.year;
}
else
{
// mission stopped so get century by year window
if (td.year <= 70)
td.year += 2000;
else
td.year += 1900;
}
// convert to seconds since 1970
if ((td.month == 0) || (td.day == 0))
mstatus->mission_start_time = 0;
else
mstatus->mission_start_time = DateToSeconds(&td);
// download stations time of reading
time(&tlong);
tstruct = localtime(&tlong);
td.day = tstruct->tm_mday;
td.month = tstruct->tm_mon + 1; // (1.01)
td.year = tstruct->tm_year + 1900;
td.hour = tstruct->tm_hour;
td.minute = tstruct->tm_min;
td.second = tstruct->tm_sec;
mstatus->download_time = DateToSeconds(&td);
// skip alarm modes and status for now
}
//--------------------------------------------------------------------------
// Take the Mission Status structure and create new raw data to start
// a new mission.
//
void FormatMission(MissionStatus *mstatus)
{
int i;
time_t tlong;
struct tm *tstruct;
// clear the buffer
for (i = 0; i < 32; i++)
mstatus->status_raw[i] = 0;
// Real Time Clock
time(&tlong);
tlong++; // add 1 second
tstruct = localtime(&tlong);
// convert to BCD
mstatus->status_raw[0x00] = ToBCD((short)tstruct->tm_sec);
mstatus->status_raw[0x01] = ToBCD((short)tstruct->tm_min);
mstatus->status_raw[0x02] = ToBCD((short)tstruct->tm_hour);
mstatus->status_raw[0x03] = ToBCD((short)(tstruct->tm_wday + 1));
mstatus->status_raw[0x04] = ToBCD((short)tstruct->tm_mday);
mstatus->status_raw[0x05] = ToBCD((short)(tstruct->tm_mon + 1));
if (tstruct->tm_year >= 100)
mstatus->status_raw[0x05] |= 0x80;
mstatus->status_raw[0x06] = ToBCD((short)(tstruct->tm_year % 100));
// Real Time clock Alarm (leave 0's)
// Low temp alarm
mstatus->status_raw[0x0B] = mstatus->low_threshold;
// High temp alarm
mstatus->status_raw[0x0C] = mstatus->high_threshold;
// sample rate
mstatus->status_raw[0x0D] = mstatus->sample_rate;
// control
mstatus->status_raw[0x0E] = 0x40;
if (mstatus->rollover_enable)
mstatus->status_raw[0x0E] |= 0x08;
// mission start delay
mstatus->status_raw[0x12] = mstatus->start_delay & 0xFF;
mstatus->status_raw[0x13] = (mstatus->start_delay >> 8) & 0xFF;
}
//--------------------------------------------------------------------------
// Convert an integer to a 1 Byte BCD number (99 max)
//
uchar ToBCD(short num)
{
uchar rtbyte;
rtbyte = (num - ((num / 10) * 10)) & 0x0F;
rtbyte = rtbyte | ((num / 10) << 4);
return rtbyte;
}
//--------------------------------------------------------------------------
// Take the Mission Status structure and convert to string format
//
void MissionStatusToString(MissionStatus *mstatus, int ConvertToF, char *str)
{
int cnt=0,i;
timedate td;
time_t tlong;
struct tm *tstruct;
// title
cnt += sprintf(&str[cnt],"Mission State\n-------------\n");
// serial number
cnt += sprintf(&str[cnt],"Serial Number of DS1921: ");
for (i = 7; i >= 0; i--)
cnt += sprintf(&str[cnt],"%02X",mstatus->serial_num[i]);
// mission state
if (mstatus->mission_in_progress)
cnt += sprintf(&str[cnt],"\nMission is in progress\n");
else
cnt += sprintf(&str[cnt],"\nMission is ended\n");
// sample rate
cnt += sprintf(&str[cnt],"Sample rate: %d minute(s)\n",mstatus->sample_rate);
// rollover
cnt += sprintf(&str[cnt],"Roll-Over Enabled: ");
if (mstatus->rollover_enable)
cnt += sprintf(&str[cnt],"yes\n");
else
cnt += sprintf(&str[cnt],"no\n");
cnt += sprintf(&str[cnt],"Roll-Over Occurred: ");
if (mstatus->rollover_occurred)
cnt += sprintf(&str[cnt],"yes\n");
else
cnt += sprintf(&str[cnt],"no\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -