; CC5X Version 3.1D, Copyright (c) B Knudsen Data ; C compiler for the PICmicro family ; ************ 30. Oct 2002 19:56 ************* processor 16F84 radix DEC INDF EQU 0x00 TMR0 EQU 0x01 OPTION_REG EQU 0x81 FSR EQU 0x04 PORTB EQU 0x06 TRISB EQU 0x86 Carry EQU 0 Zero_ EQU 2 RP0 EQU 5 dorrdiod EQU 5 summer EQU 6 lysdiod EQU 7 datatang EQU 4 n EQU 0x1B m EQU 0x1C n0 EQU 0x1D i EQU 0x1E n_2 EQU 0x1B m_2 EQU 0x1C n0_2 EQU 0x1D i_2 EQU 0x1E knapp EQU 0 tangbord EQU 0x0C siffra EQU 0x0D korrekt EQU 0x0E antal_fel EQU 0x0F kodtemp EQU 0x10 loop EQU 0x11 byt_kod EQU 0 kod EQU 0x12 ny_kod EQU 0x16 GOTO main ; FILE kodlock.c ;/* ;kodlock.c ;version:slutlig ;C-kompilator: CC5X ;Programmerare: Lars Viebke ;Datum: 2002-10-29 ; ;Processor: PIC16F84 ;Clock: 4MHz ; ;Circuitprogrammer Configuration: ;WDT=off, CP=off, OSC=XT, /MCLR=off ( Pp875x switch: -xp8 ) ; ; ;Beskrivning: ;Kodlasprogram ; ;PIC16F84 kopplad till ett siffertangentbord med sifferkodare ;knapptryck representeras av en fyrabitarskod (inkopplade pa RB0-RB3) ;Dataeneable kopplad till RB4 hog vid knapptryck ; ;Kod fran borgan: 5 4 3 2 ; ;Om ratt kod matas in oppnas dorr (RB5), oppen i 5 sek ;Om fel kod matas in tands indikerande lysdiod i 2 sek ;Vid tre fel startas larm i 6 sek ;Kod kan korrigeras med C-knappen ; ;Inmatning av ny kod: ;B gammal kod B ny kod ;ex B 5 4 3 2 B 1 2 3 4 => ny kod = 1 2 3 4 ;Rätt kodbyte indikeras med snabbt blinkande lysdiod ;Felaktikt kodbyte indikeras med langsammt blinkande lysdiod ; ;Alla inmatningar maste ske med minst en knapptryckning ;var 5:e sekund annars atergar kodlaset till start ;*/ ; ;#include "16F84.h" ;#define ON 1 /* aktivt hog */ ;#define OFF 0 ;#define SUMMERON 0 /* Summern kopplad aktivt lag */ ;#define SUMMEROFF 1 ;#pragma bit dorrdiod @ RB5 /* dorrlas */ ;#pragma bit summer @ RB6 /* summer/larm */ ;#pragma bit lysdiod @ RB7 /* indikeringslysdiod */ ; ;#pragma bit tangenta @ RB0 /* bit 1 fran tangentbord */ ;#pragma bit tangentb @ RB1 /* bit 2 fran tangentbord */ ;#pragma bit tangentc @ RB2 /* bit 3 fran tangentbord */ ;#pragma bit tangentd @ RB3 /* bit 4 fran tangentbord */ ;#pragma bit datatang @ RB4 /* dataavailable fran tangentbord */ ; ;void delay_100ms (char n) ;/* Delays en multippel av 0.1 sekund */ ;{ delay_100ms MOVWF n ; int m; ; int n0; ; char i; ; OPTION = 7; MOVLW .7 BSF 0x03,RP0 MOVWF OPTION_REG ; for (m = 0; m < 10; m++) CLRF m m001 BTFSC m,7 GOTO m002 MOVLW .10 SUBWF m,W BTFSC 0x03,Carry GOTO m006 ; { ; n0 = n; m002 MOVF n,W MOVWF n0 ; do ; { ; i = TMR0 + 39; /* 256 us * 39 = 10ms */ m003 MOVLW .39 BCF 0x03,RP0 ADDWF TMR0,W MOVWF i ; while (i != TMR0); m004 MOVF i,W BCF 0x03,RP0 XORWF TMR0,W BTFSS 0x03,Zero_ GOTO m004 ; } ; while (--n0 > 0); DECF n0,1 BTFSC n0,7 GOTO m005 MOVF n0,1 BTFSS 0x03,Zero_ GOTO m003 ; } m005 INCF m,1 GOTO m001 ;} m006 RETURN ; ;bit delay_knapp (char n) ;/* Delays en multippel av 0.1 sekund hoppar ur med knappflagga om knapp trycks in */ ;{ delay_knapp MOVWF n_2 ; int m; ; int n0; ; char i; ; bit knapp = OFF; /* knappflagga nollstalls */ BCF 0x1F,knapp ; OPTION = 7; MOVLW .7 BSF 0x03,RP0 MOVWF OPTION_REG ; for (m = 0; m < 10; m++) CLRF m_2 m007 BTFSC m_2,7 GOTO m008 MOVLW .10 SUBWF m_2,W BTFSC 0x03,Carry GOTO m013 ; { ; n0 = n; m008 MOVF n_2,W MOVWF n0_2 ; do ; { ; i = TMR0 + 39; /* 256 us * 39 = 10ms */ m009 MOVLW .39 BCF 0x03,RP0 ADDWF TMR0,W MOVWF i_2 ; while (i != TMR0); m010 MOVF i_2,W BCF 0x03,RP0 XORWF TMR0,W BTFSS 0x03,Zero_ GOTO m010 ; if (datatang == ON) /* om nagon knapp trycks in avbryts delayfunktionen */ BCF 0x03,RP0 BTFSS 0x06,datatang GOTO m011 ; { ; knapp = ON; /* satter knappflagga hog */ BSF 0x1F,knapp ; n0 = 0; CLRF n0_2 ; m = 10; MOVLW .10 MOVWF m_2 ; } ; } ; while (--n0 > 0); m011 DECF n0_2,1 BTFSC n0_2,7 GOTO m012 MOVF n0_2,1 BTFSS 0x03,Zero_ GOTO m009 ; } m012 INCF m_2,1 GOTO m007 ; return knapp; /* knappflaggan skickas med */ m013 BCF 0x03,Carry BTFSC 0x1F,knapp BSF 0x03,Carry RETURN ;} ; ; ; ; ;void main( void) ;{ main ; TRISB = 0b00011111; /* RB0,RB1,RB2,RB3,RB4 in, RB5,RB6 ut */ MOVLW .31 BSF 0x03,RP0 MOVWF TRISB ; char tangbord; /* hog nagon knapp trycks in */ ; char siffra; /* sifferraknare/positionraknare i koden */ ; char korrekt; /* korrektraknare, antal ratt overstammande */ ; char antal_fel = 0; /* nollstallning av felraknare */ CLRF antal_fel ; char kodtemp; ; int loop; /* loopraknare vid lysdiodblink */ ; bit byt_kod; /* indikeringsbit/flagga for byte av kod */ ; ; char kod[4]; /* Aktiv kod, 1-dim matris med 4 celler */ ; char ny_kod[4]; /* Ny kod, 1-dim matris med 4 celler */ ; kod[0] = 5; /* kod initieras, en cell i taget */ MOVLW .5 MOVWF kod ; kod[1] = 4; /* kod: 5 4 3 2 */ MOVLW .4 MOVWF kod+1 ; kod[2] = 3; MOVLW .3 MOVWF kod+2 ; kod[3] = 2; MOVLW .2 MOVWF kod+3 ; ; summer = SUMMEROFF; BCF 0x03,RP0 BSF 0x06,summer ; ; dorrdiod = ON; /* Funktionstest: Lysdioderna lyser i 2 sekund */ BSF 0x06,dorrdiod ; ;START: /* hoppar hit om processen avbryts (C-knapp intryckt, 5 sek inaktivitet) */ ; lysdiod = ON; /* indikerar med 2 sek lysdiod */ m014 BCF 0x03,RP0 BSF 0x06,lysdiod ; delay_100ms(20); /* delay 2 sek */ MOVLW .20 CALL delay_100ms ; dorrdiod = OFF; BCF 0x03,RP0 BCF 0x06,dorrdiod ; lysdiod = OFF; BCF 0x06,lysdiod ; ; while (1) /* Overgripande evighetsloop! */ ; { ; ; siffra = 1; /* siffra=1 for att undvika negativt varde vid minskning */ m015 MOVLW .1 MOVWF siffra ; korrekt = 0; /* nollstaller korrektraknare */ CLRF korrekt ; byt_kod = OFF; /* nollstaller flagga for kodbyte */ BCF 0x1A,byt_kod ; ;/* SIFFERRAKNARE */ ; while (datatang == OFF); /* Vantar pa knapptryckning */ m016 BCF 0x03,RP0 BTFSS 0x06,datatang GOTO m016 ; do ; { ; if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ m017 MOVLW .50 CALL delay_knapp BTFSS 0x03,Carry ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; tangbord = PORTB & 0b00001111; /* laser tangentbord (RB0-RB3) */ MOVLW .15 BCF 0x03,RP0 ANDWF PORTB,W MOVWF tangbord ; if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ MOVF tangbord,W XORLW .12 BTFSC 0x03,Zero_ ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; if (tangbord == 11 && siffra == 1) /* 11 = B-knapp - byte av kod */ MOVF tangbord,W XORLW .11 BTFSS 0x03,Zero_ GOTO m018 DECFSZ siffra,W GOTO m018 ; { ; byt_kod = ON; BSF 0x1A,byt_kod ; siffra --; /* minska sifferraknare med 1 (B-knapp ingar ej i koden) */ DECF siffra,1 ; } ; kodtemp = kod[siffra-1]; m018 MOVLW .17 ADDWF siffra,W MOVWF FSR MOVF INDF,W MOVWF kodtemp ; if (tangbord == kodtemp) /* korrekt kodsiffra pa ratt position */ MOVF tangbord,W XORWF kodtemp,W BTFSC 0x03,Zero_ ; { ; korrekt++; /* raknar upp korrektraknare */ INCF korrekt,1 ; } ; while (datatang == ON); /* vantar medan knapptryck kvar */ m019 BCF 0x03,RP0 BTFSC 0x06,datatang GOTO m019 ; siffra ++; /* raknar upp sifferraknaren */ INCF siffra,1 ; } while (siffra < 5); /* 4 knapptryckningar */ MOVLW .5 SUBWF siffra,W BTFSS 0x03,Carry GOTO m017 ; ;/* FEL KOD! */ ; if (korrekt != 4) /* antal ratt ej 4 */ MOVF korrekt,W XORLW .4 BTFSC 0x03,Zero_ GOTO m021 ; { ; lysdiod = ON; /* tand lysdiod */ BCF 0x03,RP0 BSF 0x06,lysdiod ; antal_fel ++; /* raknar upp felraknaren */ INCF antal_fel,1 ; if (antal_fel > 2) /* vid 3 fel */ MOVLW .3 SUBWF antal_fel,W BTFSS 0x03,Carry GOTO m020 ; { ; summer = SUMMERON; /* larm i 6 sek (4+2) vid 3 fel */ BCF 0x06,summer ; delay_100ms(40); /* delay 4 sek */ MOVLW .40 CALL delay_100ms ; antal_fel = 0; /* nollstallning av felraknare */ CLRF antal_fel ; } ; delay_100ms(20); /* delay 2 sek */ m020 MOVLW .20 CALL delay_100ms ; summer = SUMMEROFF; BCF 0x03,RP0 BSF 0x06,summer ; lysdiod = OFF; BCF 0x06,lysdiod ; } ; ;/* OPPNAR DORREN! */ ; else if (byt_kod == OFF) /* antal ratt 4 */ GOTO m015 m021 BTFSC 0x1A,byt_kod GOTO m022 ; { ; dorrdiod = ON; /* korrekt knapp inslagen, oppna dorren */ BCF 0x03,RP0 BSF 0x06,dorrdiod ; lysdiod = OFF; BCF 0x06,lysdiod ; antal_fel = 0; /* nollstallning av felraknare */ CLRF antal_fel ; delay_100ms(50); /* oppnar dorr i 5 sekunder */ MOVLW .50 CALL delay_100ms ; dorrdiod = OFF; BCF 0x03,RP0 BCF 0x06,dorrdiod ; } ; ;/* B-KNAPPSKONTROLL! */ ; else /* byt_kod == ON */ GOTO m015 ; { ; if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ m022 MOVLW .50 CALL delay_knapp BTFSS 0x03,Carry ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; tangbord = PORTB & 0b00001111; /* laser tangentbord */ MOVLW .15 BCF 0x03,RP0 ANDWF PORTB,W MOVWF tangbord ; while (datatang == ON); /* vantar medan knapp nedtryckt */ m023 BCF 0x03,RP0 BTFSC 0x06,datatang GOTO m023 ; if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ MOVF tangbord,W XORLW .12 BTFSC 0x03,Zero_ ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; ;/* MISSLYCKAT KODBYTE */ ; if (tangbord != 11) /* annan an B-knapp intryckt */ MOVF tangbord,W XORLW .11 BTFSC 0x03,Zero_ GOTO m026 ; { ; byt_kod = OFF; BCF 0x1A,byt_kod ; loop = 0; /* nollstaller loop-raknare */ CLRF loop ; while (loop < 10) /* blinkar lysdiod, med 1,25Hz i 8 sek */ m024 BTFSC loop,7 GOTO m025 MOVLW .10 SUBWF loop,W BTFSC 0x03,Carry GOTO m015 ; { ; lysdiod = ON; m025 BCF 0x03,RP0 BSF 0x06,lysdiod ; delay_100ms(4); /* delay 0,4 sek */ MOVLW .4 CALL delay_100ms ; lysdiod = OFF; BCF 0x03,RP0 BCF 0x06,lysdiod ; delay_100ms(4); /* delay 0,4 sek */ MOVLW .4 CALL delay_100ms ; loop ++; INCF loop,1 ; } GOTO m024 ; } ; else /* B-knapp intryckt */ ; { ; ;/* SIFFERRAKNARE (ny kod) */ ; siffra = 0; /* nollstaller sifferraknare */ m026 CLRF siffra ; do ; { ; if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ m027 MOVLW .50 CALL delay_knapp BTFSS 0x03,Carry ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; tangbord = PORTB & 0b00001111; /* laser tangentbord (RB0-RB3) */ MOVLW .15 BCF 0x03,RP0 ANDWF PORTB,W MOVWF tangbord ; if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ MOVF tangbord,W XORLW .12 BTFSC 0x03,Zero_ ; { ; goto START; /* hoppar ur till START */ GOTO m014 ; } ; if (tangbord < 10) /* endast siffertangenter */ MOVLW .10 SUBWF tangbord,W BTFSC 0x03,Carry GOTO m028 ; { ; ny_kod[siffra] = tangbord; /* matar in siffra i ny kod i ratt position */ MOVLW .22 ADDWF siffra,W MOVWF FSR MOVF tangbord,W MOVWF INDF ; siffra ++; /* raknar upp sifferraknaren/kodpositionen */ INCF siffra,1 ; } ; while (datatang == ON); /* vantar medan knapp nedtryckt */ m028 BCF 0x03,RP0 BTFSC 0x06,datatang GOTO m028 ; } ; while (siffra < 4); /* 4 knapptryckningar */ MOVLW .4 SUBWF siffra,W BTFSS 0x03,Carry GOTO m027 ; ; kod[0] = ny_kod[0]; /* kod uppdateras, en cell i taget */ MOVF ny_kod,W MOVWF kod ; kod[1] = ny_kod[1]; MOVF ny_kod+1,W MOVWF kod+1 ; kod[2] = ny_kod[2]; MOVF ny_kod+2,W MOVWF kod+2 ; kod[3] = ny_kod[3]; MOVF ny_kod+3,W MOVWF kod+3 ; ;/* LYCKAT KODBYTE */ ; loop = 0; /* nollstaller loop-raknare */ CLRF loop ; while (loop < 20) /* blinkar dorrdiod, med 5Hz i 4 sek */ m029 BTFSC loop,7 GOTO m030 MOVLW .20 SUBWF loop,W BTFSC 0x03,Carry GOTO m015 ; { ; lysdiod = ON; m030 BCF 0x03,RP0 BSF 0x06,lysdiod ; delay_100ms(1); /* delay 0,1 sek */ MOVLW .1 CALL delay_100ms ; lysdiod = OFF; BCF 0x03,RP0 BCF 0x06,lysdiod ; delay_100ms(1); /* delay 0,1 sek */ MOVLW .1 CALL delay_100ms ; loop ++; INCF loop,1 ; } GOTO m029 ; } ; } ; } END