⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thermo21.c

📁 Small Device C Compiler 面向Inter8051
💻 C
📖 第 1 页 / 共 3 页
字号:
         {
            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 + -