/***************************************************************************************** ** Nano Access Control with DS1990 iButton ** ***************************************************************************************** * This program allow the implementation of a very simple acces control with a DS1990 * * iButton as key. * * This program implements all the necessary routines for the handling of the “one wire” * * protocol. * * The read serial number is compared with the five stored in the memory, if there is * * some coincidence a relay is activated. * * The serial number readed is compared whit five serial number stored in internal * * EEPROM of the the microcontoller. If the serial number readed match with any of the * * serial numbers stored in the memory a relay is actived. * * ***************************************************************************************** * Microcontroller : PIC16F818 * * Author : Armando Novello * * * * (C) Vertrics microSistemas - www.vertrics.com * *****************************************************************************************/ #include <system.h> /// General definitions ////////////////////////////////////////////////////////////////// /// #define AS_OUT 0 #define AS_IN 1 #define LED_ON 0 #define LED_OFF 1 #define RELAY_ON 1 #define RELAY_OFF 0 #define SM_READY 0x02 #define SM_OPEN 0x03 #define EEAD_SMSTA 0 #define EEAD_CNUSR 1 #define EEAD_RECMST 0x50 #define CNT_TMR0 0x63 #define CN_USR 0x05 #pragma CLOCK_FREQ 4000000 //// FSR bits //////////////////////////////////////////////////////////////////////////// // volatile bit T1CON_TMR1ON@T1CON.TMR1ON; volatile bit INTCON_GIE@INTCON.GIE; volatile bit INTCON_PEIE@INTCON.PEIE; volatile bit INTCON_TMR0IE@INTCON.TMR0IE; volatile bit INTCON_TMR0IF@INTCON.TMR0IF; volatile bit PIR1_TMR1IF@PIR1.TMR1IF; volatile bit PIE1_TMR1IE@PIE1.TMR1IE; volatile bit OSCCON_IOFS@OSCCON.IOFS; volatile bit EECON1_WR@EECON1.WR; volatile bit EECON1_RD@EECON1.RD; volatile bit EECON1_EEPGD@EECON1.EEPGD; volatile bit EECON1_WREN@EECON1.WREN; //// variables globales /////////////////////////////////////////////////////////////// // #define A_FLAGS 0x20 // flags in address 0x20 char flags@A_FLAGS; bit fST1En@A_FLAGS.0; // software timer 1 enaable bit fST1Ex@A_FLAGS.1; // software timer 1 expired volatile bit fIBDet@A_FLAGS.2; // iButton detected char dataIB[8]; // buffer iButton data char crc; // crc of readed data char cnUsr; // quntity of user loaded char cntST1; // software timer 1, used for led char foOnTime; char foOffTime; char foNOR; char smSta; /// pins definitions /////////////////////////////////////////////////////////////////// /// volatile bit pinIB@PORTB.0; // iButton reader pin volatile bit trisIB@TRISB.0; volatile bit pinLed@PORTB.3; // led pin volatile bit trisLed@TRISB.3; volatile bit pinRelay@PORTB.4; // relay pin volatile bit trisRelay@TRISB.4; //// prototypes //////////////////////////////////////////////////////////////////////// // void Delay(char t); void InitHard(void); // hardware initialization void InitSoft(void); // software initialization char IsDetecIB(void); // true if iButton is detected void WrByteIB(char b); // write iButton char RdByteIB(void); // read a byte from iButton char ReadIB(void); // read a frame from iButton char ChekIBCrc(void); // check CRC void WrIEEPROM(const char d, const char a); // write internal EEPROM char RdIEEPROM(const char a); // read internal EEPROM void StoUsrRec(const char nr); char CmpUsrRec(const char nr); // match user 'nr' char IsMatchUsr(void); // return true if match any user void InitFlash(char on, char off, char nr); // flash led /// ISR //////////////////////////////////////////////////////////////////////////////// /// void interrupt(void) { if (INTCON_TMR0IF) { tmr0 = CNT_TMR0; INTCON_TMR0IF = 0; if (fST1En) { if (cntST1 == 0) { if (foNOR > 0) { if (pinLed == LED_OFF) { cntST1 = foOnTime; pinLed = LED_ON; } else { pinLed = LED_OFF; cntST1 = foOffTime; foNOR--; } } else fST1En = 0; } --cntST1; } } } /// main function ///////////////////////////////////////////////////////////////////// /// void main(void) { InitHard(); InitSoft(); INTCON_GIE = 1; INTCON_PEIE = 1; do { if (IsDetecIB()) { delay_ms(100); // for debounce if (IsDetecIB()) { if (ReadIB()) { if (IsMatchUsr()) { InitFlash(40, 5, 1); pinRelay = RELAY_ON; delay_s(5); // relay on for 5 sec. pinRelay = RELAY_OFF; } else InitFlash(10, 5, 3); } } } } while (1); } /// functions ///////////////////////////////////////////////////////////////////////// /// /************************************************************************************* ** Delay(chart t) * ************************************************************************************* ** Delay t*5 microsec (t=2 => delay = 10us) * *************************************************************************************/ void Delay(char t) { asm { dlyLoop: nop nop decfsz _t, F goto dlyLoop } } /************************************************************************************* ** InitHard(void) * ************************************************************************************* ** Hardware initialization * *************************************************************************************/ void InitHard(void) { adcon0 = 0; // CAD disabled adcon1 = 0x06; // all output as digitas osccon = 0x60; // internal clock 4MHz while (OSCCON_IOFS == 0); option_reg = 10000101b; // R pullup disable, prescaler trm0 64 tmr0 = CNT_TMR0; // interrup ~10ms intcon = 0; INTCON_TMR0IE = 1; portb = 0xFF; trisb = 10000000b; t1con = 00110000b; } /************************************************************************************* ** InitSoft(void) * ************************************************************************************* ** Software initialization * *************************************************************************************/ void InitSoft(void) { flags = 0; cntST1 = 0; smSta = RdIEEPROM(EEAD_SMSTA); cnUsr = RdIEEPROM(EEAD_CNUSR); if (cnUsr == 0xFF) cnUsr = 0; } /************************************************************************************* ** void WrIEEPROM(BYTE d, BYTE a) ** ************************************************************************************* * write the byte 'd' in de address 'a' of the internal EEPROM * *************************************************************************************/ void WrIEEPROM(const char d, const char a) { eeadr = a; eedata = d; EECON1_EEPGD = 0; EECON1_WREN = 1; INTCON_GIE = 0; eecon2 = 0x55; eecon2 = 0xAA; EECON1_WR = 1; INTCON_GIE = 1; while (EECON1_WR); EECON1_WREN = 0; } /************************************************************************************* ** BYTE RdIEEPROM(BYTE a) ** ************************************************************************************* * Read a byte from address 'a' of the internal EEPROM * *************************************************************************************/ char RdIEEPROM(const char a) { eeadr = a; EECON1_EEPGD = 0; EECON1_RD = 1; return eedata; } /************************************************************************************* ** char IsDetecIB(void) ** ************************************************************************************* * Return 'true' if a iButton are present in the reader * *************************************************************************************/ char IsDetecIB(void) { char detect; detect = 0; pinIB = 0; trisIB = AS_OUT; Delay(500/5); trisIB = AS_IN; Delay(70/5); if (pinIB == 0) detect++; Delay(250/5); if (pinIB == 1) detect++; Delay(180/5); if (detect == 2) return 1; return 0; } /************************************************************************************* ** void WrByteIB(char b) ** ************************************************************************************* * Write byte 'b' in the iButton * *************************************************************************************/ void WrByteIB(char b) { char n; for (n = 0; n < 8; n++) { pinIB = 0; trisIB = AS_OUT; if (b & 0x01) trisIB = AS_IN; Delay(60/5); trisIB = AS_IN; b >>= 1; } } /************************************************************************************* ** char RdByteIB(void) ** ************************************************************************************* * Read one byte from the iButton * *************************************************************************************/ char RdByteIB(void) { char n; char b; b = 0; for (n = 0; n < 8; n++) { pinIB = 0; trisIB = AS_OUT; nop(); nop(); nop(); nop(); nop(); nop(); trisIB = AS_IN; nop(); nop(); nop(); nop(); b >>= 1; if (pinIB) b |= 0x80; Delay(50/5); } return b; } /************************************************************************************* ** char ReadIB(void) ** ************************************************************************************* * Read a frame from the iButton * * Return 'true' if the frame is ok * * 'false'if some error occurs * *************************************************************************************/ char ReadIB(void) { char n; WrByteIB(0x33); dataIB[0] = RdByteIB(); if (dataIB[0] != 0x01) return 0; for (n = 1; n < 8; n++) { dataIB[n] = RdByteIB(); } if (ChekIBCrc() == 0) return 1; return 0; } /************************************************************************************* ** char ChekIBCrc(void) ** ************************************************************************************* * verifies the crc of the read frame. Return the crc calculated * *************************************************************************************/ char ChekIBCrc(void) { char n, i, d, f; crc = 0; for (n = 0; n < 8; n++) { d = dataIB[n]; for (i = 0; i < 8; i++) { f = (d ^ crc) & 1; crc >>= 1; d >>= 1; if (f) crc ^= 0x8C; } } return crc; } /************************************************************************************* ** void InitFlash(char onT, char offT, char nr) ** ************************************************************************************* * flash led * *************************************************************************************/ void InitFlash(char onT, char offT, char nr) { foOnTime = onT; cntST1 = onT; foOffTime = offT; foNOR = nr; pinLed = LED_ON; fST1En = 1; } /************************************************************************************* ** void CmpUsrRec(char nr) ** ************************************************************************************* * compares buffer with record user 'nr'. * * return 0x00 is are equal, 0x01 if not * *************************************************************************************/ char CmpUsrRec(const char nr) { char i; if (RdIEEPROM(nr*8+EEAD_RECMST) == 0xFF) return 0x01; for (i = 1; i < 7; i++) if (RdIEEPROM(nr*8+EEAD_RECMST+i) != dataIB[i]) return 1; return 0; } /************************************************************************************* ** char IsMatchUsr(void) ** ************************************************************************************* * search user in the user table. * * return 'true' if exists * *************************************************************************************/ char IsMatchUsr(void) { char i; for (i = 0; i < CN_USR; i++) if (CmpUsrRec(i+1) == 0x00) return 1; return 0; }
Copyright © 2006 SourceBoost Technologies