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