Source Code File:"nac_r1.c"

/*****************************************************************************************
 ** 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;
}

http://www.sourceboost.com

Copyright © 2006 SourceBoost Technologies