/* kodlock.c version:slutlig C-kompilator: CC5X Programmerare: Lars Viebke: l.viebke@telia.com 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 */ { int m; int n0; char i; OPTION = 7; for (m = 0; m < 10; m++) { n0 = n; do { i = TMR0 + 39; /* 256 us * 39 = 10ms */ while (i != TMR0); } while (--n0 > 0); } } bit delay_knapp (char n) /* Delays en multippel av 0.1 sekund hoppar ur med knappflagga om knapp trycks in */ { int m; int n0; char i; bit knapp = OFF; /* knappflagga nollstalls */ OPTION = 7; for (m = 0; m < 10; m++) { n0 = n; do { i = TMR0 + 39; /* 256 us * 39 = 10ms */ while (i != TMR0); if (datatang == ON) /* om nagon knapp trycks in avbryts delayfunktionen */ { knapp = ON; /* satter knappflagga hog */ n0 = 0; m = 10; } } while (--n0 > 0); } return knapp; /* knappflaggan skickas med */ } void main( void) { TRISB = 0b00011111; /* RB0,RB1,RB2,RB3,RB4 in, RB5,RB6 ut */ 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 */ 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 */ kod[1] = 4; /* kod: 5 4 3 2 */ kod[2] = 3; kod[3] = 2; summer = SUMMEROFF; dorrdiod = ON; /* Funktionstest: Lysdioderna lyser i 2 sekund */ START: /* hoppar hit om processen avbryts (C-knapp intryckt, 5 sek inaktivitet) */ lysdiod = ON; /* indikerar med 2 sek lysdiod */ delay_100ms(20); /* delay 2 sek */ dorrdiod = OFF; lysdiod = OFF; while (1) /* Overgripande evighetsloop! */ { siffra = 1; /* siffra=1 for att undvika negativt varde vid minskning */ korrekt = 0; /* nollstaller korrektraknare */ byt_kod = OFF; /* nollstaller flagga for kodbyte */ /* SIFFERRAKNARE */ while (datatang == OFF); /* Vantar pa knapptryckning */ do { if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ { goto START; /* hoppar ur till START */ } tangbord = PORTB & 0b00001111; /* laser tangentbord (RB0-RB3) */ if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ { goto START; /* hoppar ur till START */ } if (tangbord == 11 && siffra == 1) /* 11 = B-knapp - byte av kod */ { byt_kod = ON; siffra --; /* minska sifferraknare med 1 (B-knapp ingar ej i koden) */ } kodtemp = kod[siffra-1]; if (tangbord == kodtemp) /* korrekt kodsiffra pa ratt position */ { korrekt++; /* raknar upp korrektraknare */ } while (datatang == ON); /* vantar medan knapptryck kvar */ siffra ++; /* raknar upp sifferraknaren */ } while (siffra < 5); /* 4 knapptryckningar */ /* FEL KOD! */ if (korrekt != 4) /* antal ratt ej 4 */ { lysdiod = ON; /* tand lysdiod */ antal_fel ++; /* raknar upp felraknaren */ if (antal_fel > 2) /* vid 3 fel */ { summer = SUMMERON; /* larm i 6 sek (4+2) vid 3 fel */ delay_100ms(40); /* delay 4 sek */ antal_fel = 0; /* nollstallning av felraknare */ } delay_100ms(20); /* delay 2 sek */ summer = SUMMEROFF; lysdiod = OFF; } /* OPPNAR DORREN! */ else if (byt_kod == OFF) /* antal ratt 4 */ { dorrdiod = ON; /* korrekt knapp inslagen, oppna dorren */ lysdiod = OFF; antal_fel = 0; /* nollstallning av felraknare */ delay_100ms(50); /* oppnar dorr i 5 sekunder */ dorrdiod = OFF; } /* B-KNAPPSKONTROLL! */ else /* byt_kod == ON */ { if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ { goto START; /* hoppar ur till START */ } tangbord = PORTB & 0b00001111; /* laser tangentbord */ while (datatang == ON); /* vantar medan knapp nedtryckt */ if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ { goto START; /* hoppar ur till START */ } /* MISSLYCKAT KODBYTE */ if (tangbord != 11) /* annan an B-knapp intryckt */ { byt_kod = OFF; loop = 0; /* nollstaller loop-raknare */ while (loop < 10) /* blinkar lysdiod, med 1,25Hz i 8 sek */ { lysdiod = ON; delay_100ms(4); /* delay 0,4 sek */ lysdiod = OFF; delay_100ms(4); /* delay 0,4 sek */ loop ++; } } else /* B-knapp intryckt */ { /* SIFFERRAKNARE (ny kod) */ siffra = 0; /* nollstaller sifferraknare */ do { if (delay_knapp(50) == 0) /* Atergar till grundlage vid 5 sek inaktivitet */ { goto START; /* hoppar ur till START */ } tangbord = PORTB & 0b00001111; /* laser tangentbord (RB0-RB3) */ if (tangbord == 12) /* 12 = C-knapp - angra knapptryck */ { goto START; /* hoppar ur till START */ } if (tangbord < 10) /* endast siffertangenter */ { ny_kod[siffra] = tangbord; /* matar in siffra i ny kod i ratt position */ siffra ++; /* raknar upp sifferraknaren/kodpositionen */ } while (datatang == ON); /* vantar medan knapp nedtryckt */ } while (siffra < 4); /* 4 knapptryckningar */ kod[0] = ny_kod[0]; /* kod uppdateras, en cell i taget */ kod[1] = ny_kod[1]; kod[2] = ny_kod[2]; kod[3] = ny_kod[3]; /* LYCKAT KODBYTE */ loop = 0; /* nollstaller loop-raknare */ while (loop < 20) /* blinkar dorrdiod, med 5Hz i 4 sek */ { lysdiod = ON; delay_100ms(1); /* delay 0,1 sek */ lysdiod = OFF; delay_100ms(1); /* delay 0,1 sek */ loop ++; } } } } }