Thread: Programming a PIC 16F84 microcontroller in C

  1. #1
    Registered User
    Join Date
    Mar 2004
    Posts
    4

    Programming a PIC 16F84 microcontroller in C

    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();
    	}
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well compare how your 16 key keypad is wired up and compare that with the code in int ReadKey()
    Then do the same thing with your 12 key keypad and make the appropriate changes
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 02-18-2009, 06:10 AM
  2. Replies: 27
    Last Post: 10-25-2007, 10:47 AM
  3. Pic 16f84a
    By system_eyes in forum C Programming
    Replies: 2
    Last Post: 08-05-2003, 02:52 AM
  4. PIC Microcontrolers
    By face_master in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 09-28-2002, 11:29 PM
  5. C for microcontroller
    By phernyt in forum C Programming
    Replies: 2
    Last Post: 12-08-2001, 01:01 PM