| dorinm 
 
 
 Joined: 07 Jan 2006
 Posts: 38
 
 
 
			    
 
 | 
			
				| Emulating a DS2401 on 16F88 |  
				|  Posted: Mon Feb 21, 2011 7:36 am |   |  
				| 
 |  
				| 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
 |  |