CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Emulating a DS2401 on 16F88

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
dorinm



Joined: 07 Jan 2006
Posts: 38

View user's profile Send private message

Emulating a DS2401 on 16F88
PostPosted: Mon Feb 21, 2011 7:36 am     Reply with quote

this is the whole code needed to emulate a DS2401 8byte serial number;
it is based on some code found on web written for hitech compiler (as far as I remember), the code didn't mention the author so I can't do that either;
...the original code has some bugs in it (mainly bad timming and "corner-cuts"; also the reset procedure in the interrupt routine was not ok), I have just adapted it for CCS and corrected where it was necessary;
... I do not take any responsability on how it's used

Code:

#include <16f88.h>
#device *=16

#fuses HS, WDT, PUT, MCLR, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOIESO, NOFCMEN

//i've tried also with lower frequencies, there are problems with precise timmings
//so I recomend using 20MHZ; do not even think about internal RC ;)
#use delay(clock=20000000)
#use fast_io(B)

//some arbitrary serial data
#rom 0x2100={0x01,0x11,0x22,0x33,0x44,0x55,0x69,0x00}

// comment it out if you're not using leds for debugging
#define  MOD_TEST

#define  LED_PWR   PIN_B1
#define  LED_RST   PIN_B2
#define  LED_RX    PIN_B3
#define  LED_TX    PIN_B4

//the pin used for interfacing with DS2401
//do not forget that sometimes you should use a pullup resistor on this line, 50k>(100k) should be fine
//be aware about the fact that in some cicumstances the DS's are powered up using parasite mode (by DQ line),
//this is not the case so you should power up your schematics from your 5V line
#define  DS_DQ       PIN_B0

#define  PLIN        1
#define  GOL         0
#define  BUFFER_MAX  7

#define  INIT_SEQ    (flag_Rx=FALSE, flag_BUF_Rx=GOL, bit_curent=0)


int1  flag_Rx;
int1  flag_BUF_Rx;

int8  BUF_Rx;
int1  bRx;
int8  BUF_Tx[8];
int8  SN[8];

int8  bit_curent, buffer_index, del_count;






#INT_EXT
void interrupt(void)
{
 
   if (flag_Rx)
   {
   
       #ifdef MOD_TEST
       output_high(LED_RX);
       #endif
     
      delay_us(15);
      bRx = input(DS_DQ);
      flag_BUF_Rx = GOL;
      bit_curent++;
     
      if (bit_curent == 8)
      {
               #ifdef MOD_TEST
               output_low(LED_RX);
               #endif

         flag_BUF_Rx = PLIN;
         bit_curent = 0;

      }
     
      BUF_Rx >>= 1;
      if (bRx)
         BUF_Rx |= 0x80;
      delay_us(5);


      if(input(DS_DQ))
      {
               #ifdef MOD_TEST
               output_low(LED_RX);
               #endif
         clear_interrupt(INT_EXT);
         return;
      }
     
      else
      {
         del_count = 45;
         while (del_count--)
         {
         if (input(DS_DQ))
            {
               #ifdef MOD_TEST
               output_low(LED_RX);
               #endif
               clear_interrupt(INT_EXT);
               return;
            }
         }
      }
   }





   RST:

      set_tris_b(0b00000001);

      #ifdef MOD_TEST
      output_high(LED_RST);
      #endif
     
      delay_us(200);
   
      while(!input(DS_DQ));
         
      delay_us(30);
      output_low(DS_DQ);
      set_tris_b(0b00000000);
      delay_us(480);
     
      INIT_SEQ;
      flag_Rx = TRUE;
      set_tris_b(0b00000001);

   
      #ifdef MOD_TEST
      output_low(LED_RST);
      #endif
   
      clear_interrupt(INT_EXT);
      return;
     
   
}


void C_CRC(byte *CRCVal, int8 value)
{
     int8 odd, bcnt;

     for (bcnt=0; bcnt<8; bcnt++)
   {
      odd = (value ^ *CRCVal) & 0x01;
       *CRCVal >>= 1;
       value >>= 1;
       if (odd != 0)
         *CRCVal ^= 0x8C;
     }
}


int8 CalcCRC(byte code_len, int8 *code)
{
   int8 i, CRCVal=0;

     for ( i=0; i<code_len; i++ )
       C_CRC( &CRCVal, code[i] );

     return CRCVal;
}


void Read_SN(void)
{
   int8 adresa;

   for ( adresa=0; adresa<BUFFER_MAX; adresa++ )
      SN[adresa] = read_eeprom (adresa);

   
   SN[adresa] = CalcCRC(7, SN);
}




/******************* MAIN *****************/

void main() {

   int8 i,mask;


   setup_wdt(WDT_2304MS);
 
   INIT_SEQ;

   Read_SN();
   
   BUF_Rx = 0;

   setup_adc(ADC_OFF);
   setup_adc_ports(NO_ANALOGS);
   set_tris_a(0b11111111);
   set_tris_b(0b00000001);
   output_float(DS_DQ);
   ext_int_edge( H_TO_L );
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   #ifdef MOD_TEST
   output_high(LED_PWR);
   #endif


  for(i=0; i<8; i++)
  BUF_Tx[i] = SN[i];


   while(TRUE)
   {
         
      if (flag_BUF_Rx == PLIN)
      {

            if (BUF_Rx == 0x33)
            {
               #ifdef MOD_TEST
               output_high(LED_TX);
               #endif
           

               disable_interrupts(INT_EXT);
               set_tris_b(0b00000001);
               
               for (buffer_index=0; buffer_index<8; buffer_index++)
               {
                  for (bit_curent=0; bit_curent<8; bit_curent++)
                  {
                     set_tris_b(0b00000001);
                     while(input(DS_DQ));
                     output_low(DS_DQ);
                     mask=0x01 & BUF_Tx[buffer_index];
                     set_tris_b(mask);
                     
                    delay_us(35);
                    set_tris_b(0b00000001);
                       
                    BUF_Tx[buffer_index] >>= 1;
                     
                  }
               }                   
     
             
               #ifdef MOD_TEST
               output_low(LED_TX);
               #endif
                   
               for(i=0; i<8; i++)
               BUF_Tx[i] = SN[i];
               INIT_SEQ;
               restart_wdt();
               clear_interrupt(INT_EXT);
               enable_interrupts(INT_EXT);
            }
         restart_wdt();
      }
   }
}


feel free to ask questions if you need

Dorin M
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group