First, I must say that I know very few things about programming a microcontroller in C, but I would like to learn.
The following program is not written by me, but I have to write a similiar one (when I press 4 keys from a mini keyboard with 12 keys it activates a cylinder lock who will remain open for a certain amount of time) . In order to do this, I have to understand how this program works (this program is written for a keyboard with 16 keys).
If is somebody among you who knows how to program a microcontroller in C, and has enough patience to explain the program listed(I'm reffering to every line of code ), I would really appreciate it.
Code:
#pragma chip PIC16F84, core 14, code 1024, ram 12 : 0x4F
mapped_into_bank_1
#define INT_min_style
#pragma config_def 0x0111
/* registers from bank 1*/
#pragma char TMR0 @ 0x1
#pragma char PCL0 @ 0x2
#pragma char STATUS0 @ 0x3
#pragma char FSR0 @ 0x4
#pragma char PORTA @ 0x5
#pragma char PORTB @ 0x6
#pragma char EEDATA @ 0x8
#pragma char EEADR @ 0x9
#pragma char PCLAT0 @ 0x0A
/* registers from bank 2*/
#pragma char OPTION @ 0x81
#pragma char PCL1 @ 0x82
#pragma char STATUS1 @ 0x83
#pragma char FSR1 @ 0x84
#pragma char TRISA @ 0x85
#pragma char TRISB @ 0x86
#pragma char EECON1 @ 0x88
#pragma char EECON2 @ 0x89
#pragma char PCLATH1 @ 0x8A
/*define bits port B*/
#pragma bit RB4 @ 6.4
#pragma bit RB5 @ 6.5
#pragma bit RB6 @ 6.6
#pragma bit RB7 @ 6.7
/*define signals for LED-s, buzz, sensor,cylinder lock and selection*/
#pragma bit SUPER_LED @ 5.3
#pragma bit POWER_LED @ 5.4
#pragma bit FULL_LED @ 6.0
#pragma bit OPEN_LED @ 6.1
#pragma bit SOUND_SIG @ 5.0
#pragma bit YALE_SIG @ 5.1
#pragma bit SENZOR_SIG @ 5.2
#pragma bit SEL0 @ 6.2
#pragma bit SEL1 @ 6.3
/*functions definitions for turning ON/OFF LED-S*/
#define SUPER_LED_ON output_low(SUPER_LED)
#define SUPER_LED_OFF output_high(SUPER_LED)
#define POWER_LED_ON output_low(POWER_LED)
#define POWER_LED_OFF output_high(POWER_LED)
#define FULL_LED_ON output_low(FULL_LED)
#define FULL_LED_OFF output_high(FULL_LED)
#define OPEN_LED_ON output_low(OPEN_LED)
#define OPEN_LED_OFF output_high(OPEN_LED)
/*functions definitions for activation/deactivation signal commands)
#define SOUND_SIG_ON output_high(SOUND_SIG)
#define SOUND_SIG_OFF output_low(SOUND_SIG)
#define YALE_SIG_ON output_high(YALE_SIG)
#define YALE_SIG_OFF output_low(YALE_SIG)
/*signals selection for activation of a column*/
#define COL1 (output_low(SEL0);output_low(SEL1);)
#define COL2 (output_low(SEL0);output_high(SEL1);)
#define COL3 (output_high(SEL0);output_low(SEL1);)
#define COL4 (output_high(SEL0);output_high(SEL1);)
/*read signals from the keyboard line*/
#define LINE1 (!input(RB7))
#define LINE2 (!input(RB6))
#define LINE3 (!input(RB5))
#define LINE4 (!input(RB4))
#define SENSOR_READ (input(SENSOR_SIG))
/*sensor: 1- door open; 0- door close */
/*set direction ports PIC: 1 - enter; 0 - exit*/
#define TRISB_VAL 0b00000000
#define TRISA_VAL 0b00000000
/*structure of the control register for interuptions*/
struct (
short int RBIF;
short int INTF;
short int TOIF;
short int RBIE;
short int INTE;
short int TOIE;
short int PEIE;
short int GIE;
) INTCON;
#define byte INTCON = 0x0B
/*******************************yale.c**********************************/
#include "16F84.h"
#fuses HS,NOWDT, NOPROTECT, PUT
#use DELAY(clock=10000000)
#use fast_io(A)
#use fast_io(B)
int StareInt;
int NrCodes;
void SleepInterrupt()
{
int code;
if(!LINE4) StareInt=3;
/*if LINE4 is not active, button # hasn't been pressed and goes into sleep again*/
else
{
INTCON.RBIF=0;
POWER_LED_ON;
COL1;
code=ReadCode();
if(cod==-1) StareInt=3; /*Cancel*/
else
StareInt=VerifyCode(code);
}
return;
}
int ReadCodeMem(int index)
{
int adr=index*2, vall,valh;
valh=read_EEPROM(adr);
vall=read_EEPROM(adr+1);
return valh*256+vall;
}
void WriteCodeMem(int index, int val)
{
int valh, vall, adr;
adr=index * 2;
vall=val / 256;
valh=val % 256;
write_EEPROM(adr, valh);
write_EEPROM(adr+1,vall);
}
int VerifyCode(int code)
{
int i;
if(ReadCodeMem(0)==code || ReadCodeMem(1)==cod) return 1; /*supervisor*/
for(i=2;i<16;i++)
if(ReadCodeMem(i)==code) return 2; /*user*/
return 0;
}
void InitSleep()
{
POWER_LED_OFF;
COL1;
INTCON.RBIF=1; /*keyboard interrupt active*/
StareInt=-1;
Sleep();
}
int ReadKey()
{
/*it activates the columns one by one and tests the lines*/
COL1;
if(LINE1) return 1; /*1*/
if(LINE2) return 2; /*2*/
if(LINE3) return 3; /*3*/
if(LINE4) return 4; /*SUPER*/
COL2;
if(LINE1) return 5; /*4*/
if(LINE2) return 6; /*5*/
if(LINE3) return 7; /*6*/
if(LINE4) return 8; /*NEW*/
COL3;
if(LINE1) return 9; /*7*/
if(LINE2) return 10; /*8*/
if(LINE3) return 11; /*9*/
if(LINE4) return 12; /*DELETE*/
COL4;
if(LINE1) return 13; /*#*/
if(LINE2) return 14; /*0*/
if(LINE3) return 15; /*EXIT*/
if(LINE4) return 16; /*CANCEL*/
return 0;
int IsKey()
{
if(( key >=1 && key <=3) || (key>=5 && key<=7) || (key>=9 && key<=11) || key==14) return 1;
return 0;
}
void Beep(int time)
{
SOUND_SIG_ON;
delay_ms(time);
SOUND_SIG_OFF;
}
int ReadCode()
{
int NrCifre=4;
int key=0;
int t,time;
int Result=0;
/*DIV_64: 25.6 uSec per tic, 6.5536 mSec to roll over setup_counters(RTCC_INTERNAL,RTCC_DIV_64); */
do{
set_rtcc(0); /*start counting*/
key=0;
time=153*3;
do
{
key=ReadKey();
t=get_rtcc();
if(t==0) time--;
}while (key && time)
/*reads until a key is pressed or time expires*/
if(key!=0)
{
if (IsKey(key))
{
Result=Result*10+key;
}
else if(key==16) return -1; /*Cancel*/
else
{
Beep(100);
NrCifre++;
}
NrCifre--;
}
else return -1;
}while (NrCifre);
return Result;
}
void OpenDoor()
{
int t, time;
YALE_SIG_ON; /*door open*/
OPEN_LED_ON; /*LED ON - the door is open*/
Beep(300); /*sound signal*/
set_rtcc(0); /*start counting*/
key=0;
time=153*10; /*door remains unlock for 10 seconds*/
do
{
t=get_rtcc();
if( t==0 ) time--;
}while (SENSOR_READ && time)
/*reads until a person open the door or time expires*/
if(time) /*a person opened the door*/
{
time=153*300; /*after 30 seconds - beeps*/
do
{
t=get_rtcc();
if(t==0) time--;
}while(SENSOR_READ && time);
/*reads until a person close the door or time expires*/
if(!time) /*time expires*/
{
while(!SENSOR_READ)
{
Beep(100);
/*beeps until door is closed*/
}/*door closed*/
}/*door must be closed*/
YALE_SIG_OFF;
OPEN_LED_OFF;
Beep(200);
}
void Edit();
{
int t, key, counter, state;
SUPER_LED_ON;
do
{
set_rtcc(0);
counter=153*10; /*waiting time 10 seconds*/
if(NrCodes==30) FULL_LED_ON;
else FULL_LED_OFF;
do
{
key=ReadKey();
t=get_rtcc();
if(t==0) counter--;
}while(!key && counter);
/*until a key is pressed or time expires*/
if (counter)
{
if(key)
{
switch(key)
{
case 8 : /*NEW*/
if(NrCodes=30) Beep(200);
else
{
key=ReadCode(); /*reads a code*/
if(key != -1)
state=VerifyCode(key);
if(state!=0) Beep(200);
else
{
counter=153*3;
set_rtcc();
do
{
state=ReadKey();
t=get_rtcc(0);
if(t==0) counter--;
}while(!state && counter);
if(state!=4 !counter)
{
NrCodes++;
for (t=2; t<=31 && ReadCodeMem(t) !=0; t++)
if(t!=32) WriteCodeMem(t,key);
}
else if(state==4)
{
if(ReadCodeMem(0)==-1)
WriteCodeMem(0,key);
else if(ReadCodeMem(1)==-1)
WriteCodeMem(1,key);
}
Beep(300);
}
}
break; /*NEW*/
case 12: /*Del*/
if (NrCodes>0)
key=ReadKey(); /*read code*/
if (key!=-1)
state=VerifyCode();
if (state==0) Beep(200); /*code dosn't exist*/
else
{
if(state==2) /*a user is deleted*/
{
for(t=2; t<=31 && ReadCodeMem(t) != key; t++);
WriteCodeMem(t,0); /*user t deleted*/
NrCodes--;
}
else
{
if(ReadCodeMem(0)==key && ReadCodeMem(1)!=-1)
WriteCodeMem(0,0);
else if(ReadCodeMem(1)==key && ReadCodeMem(0)!=-1)
WriteCodeMem(1,0);
}
}
Beep(300);
break;
case 16: Beep(100); break; /*Cancel*/
}
}
}
}while(key!=15 && counter); /*Exit*/
Beep(300);
SUPER_LED_OFF;
FULL_LED_OFF;
}
void main
{
int time,t,key;
set_trisa(TRISA_VAL);
set_trisb(TRISB_VAL);
WriteCodeMem(0,1234); /*initial code for first suprvisor*/
for(t=1; t<=31; t++)
WriteCodeMem(t,0);
NrCodes=0;
InitSleep();
StateInt=-1;
while(1)
{
switch (StateInt)
{
case 3 : Beep(300); /*Cancel*/
case 2 : OpenDoor(); break; /*user*/
case 1 : set_rtcc(0); /*supervisor*/
time=153*3;
do
{
key=ReadKey();
t=get_rtcc();
if(t==0) time--;
}while(key && time);
/*read untile a key is pressed or time expires*/
if (time && key==4) /*SUPER is pressed*/
OpenDoor();
else if(!time) /*goes into EDIT mode*/
Edit();
else Beep(200);
break;
}
InitSleep();
}
}