Jump to content


Photo

Help With Pic16F627 Timer Interrupt

timer interrupts arrays burglarAlarm

3 replies to this topic

#1 ANDYp

ANDYp

    Newbrie

  • Members
  • 1 posts

Posted 15 April 2014 - 01:34 PM

Hi All,

 

I'm pretty new to programming however I have a program that can almost be used as a burglar alarm.

My only problem is that I need some sort of timer interrupt.

 

I need a timer to count up to 20 minutes whilst running the main body of the program (ie keeps checking the zones) but when the timer reaches 20mins it will interrupt the main program and then go into another state.

 

To test/simulate my program I use a button block "2-state" for porta, and an 8 LED block to simulate the alarm, alarm indication, bath, hall, lounge, kitchen and bedroom (portb).

 

Below is my program:

(please bare in mind I'm fairly new)

#include <system.h>
#include <string.h>
#include <stdio.h>
#pragma CLOCK_FREQ 4000000
#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF
//http://forum.sourceboost.com/index.php?showtopic=2399 (how to do an interrupt)
//define all prototypes
void config(void){
intcon = 0x02;
cmcon = 0x07;
trisa = 0xff;
trisb = 0x01; //bit zero is an interrupt.
option_reg = 0x03; //pre-scaler of 16 for the timer register.
}


//define states.
void activation(void);		//START
void indication(void);		//Alarm Indicator for 10secs.
void zoneCheck(void);		//Zone check.
void alarmOn(void);		//Start Alarm timer.
void displayZones(void);	//Silence alarm and Display intruded zones.
void alarmOff(void);

//define global variables
int i, k, a, p, x;
unsigned char inbyte, state, nxtstate, off, off2, sum, sum2, tick, tick1,
	  outbyte, outbyte1, outbyte2, array[10], array2[10], library1[20];
void delay(int, int);
void flashInd(unsigned char, unsigned char);
void zones(unsigned char, unsigned char, unsigned char);

/////////////////////////////////////////////////


int main(void) {
 config();
 nxtstate=0;
 k=0;
 i=0;
 p=0;
 a=0;
 x=0;


do{
  switch(state) {
    case 0: {activation(); state=nxtstate;  break;}
    case 1: {indication(); state=nxtstate;  break;}
    case 2: {zoneCheck(); state=nxtstate;  break;}
    case 3: {alarmOn(); state=nxtstate;  break;}
    case 4: {displayZones(); state=nxtstate;  break;}    
    case 5: {alarmOff(); state=nxtstate; break;}

   }//end of switch.
}while(1);
 return(0);
} //end of main

//////////////////////////////////////////////////////////////////
/////////////////DEFINING THE STATES//////////////////////////////
//////////////////////////////////////////////////////////////////
void activation(void) {
    unsigned char inbyte;
	inbyte = porta;
    portb = 0x00;		//outputs are all zero
    inbyte &= 0xC0;	//Masks inputA so that only the "key switch" and 
			//	"memory" button can be seen.
			//////////////////////////////////////////
if (inbyte==0x40) {nxtstate=4;}	//"memory" button has been activated and 
				// will therefore display,intruded zones.
				//////////////////////////////////////////
if(inbyte==0x80) {nxtstate=1;}	//If the "key switch" is on, move to indicator 
				//stage.	
if(inbyte==0x00) {nxtstate=0;}	//Checks position of "key switch", if in off 
				//position the program will wait in an idle 
				//state until the position is changed.
}//end of state.		///////////////////////////////////////////
///////////////////////////////////////////////


void indication(void){
if (x<1){
 flashInd(0x40, 0x00);
 x++;
 }
 nxtstate=2;
}//end of state.

/////////////////////////////////////////////////////////////////
void zoneCheck(void){
char inbyte;
		
	inbyte = porta;
	
	if (a<1){
	library1[0] = inbyte;
	nxtstate = 3;
	} 
	if (a>=1) {
		library1[p]= inbyte;
	 if (library1[p] == library1[(p-1)]) {
	nxtstate = 2;
	}
	else nxtstate = 3;
	}
}//end of zonecheck.

//////////////////////////////////////////////////////////////

void alarmOn(void){
	unsigned char outbyteOn, outbyteOn2, inbyte1, inbyte2;
	 
//	set_bit( intcon, T0IE ); //enable TMR0 overflow bit    
//	set_bit( intcon, GIE );
	inbyte = porta;
	inbyte &= 0x80;
	
	
	if (i<9) {
	 
				/////
	inbyte1 = porta;	   //
	inbyte1 &= 0x1F;	   // (Indicator + Alarm + Zone) LED's are on.
				   //
	inbyte1 <<= 0x01;	   //
	outbyte1 = inbyte1 | 0xC0; //
	array[10];		   //	
	array[k]= outbyte1;	   //
				   //	
			       //////
	inbyte2 = porta;	   //
	inbyte2 &= 0x1F;	   //
	inbyte2 <<= 0x01;	   //STORES THE HEX VALUE TO TURN OFF, 
				   //THE INDICATOR. 
	outbyte2 = inbyte2 | 0x80; //
	array2[10];		   //
	array2[k]= outbyte2;	   //
	

	sum = (array[0] | array[1] | array[2] | array[3] | array[4] | 
		array[5] | array[6] | array[7] | array[8] | array[9]);
	
	sum2 = (array2[0] | array2[1] | array2[2] | array2[3] | array2[4] | 
		array2[5] | array2[6] | array2[7] | array2[8] | array2[9]);
	
	p++;
	k++;
	i++;
	a++;
	portb = sum;
	portb = sum2;
	nxtstate = 2;	//goes to zoneCheck function to see if 
			//any other zones have been activated.
	}
	if (inbyte == 0x00) {nxtstate = 0;
	} else portb = sum; portb= sum2;
		
	//if memory is full. alarm will stay on until 
	//20mins is up(need a timer interrupt), indicator will flash 
	// until reset. The zones will also stay on.
}

/////////////////////////////////////////////////////////////

void displayZones(void){
 int m;
	 m=0;
 do{
	m++;
	portb = array[m];
   }while (m<10);
nxtstate = 0;
}
////////////////////////////////////////////////////////////////////////////
//NOTE TO SELF. THIS NEEDS CHANGING! DOESNT OUTPUT THE RIGHT LED'S YET////////									
void alarmOff(void){
inbyte = porta;
inbyte &= 0x8F;

if (inbyte =! 0x00){

off = (sum & 0x4F);
portb = off;
off2 = (sum2 & 0x0F);
portb = off2;
}
else
nxtstate=0;
}
///////////////////////////////////////////
////////functions//////////////////////////
///////////////////////////////////////////	
void flashInd(unsigned char on, unsigned char off){
 
 int i;
	 i=0;
 do{
	 i++;
	 portb = on | 0x40;			//alarm indicator turns on.
	 delay_ms(500);				//time delay for 0.5secs.
	 portb = off;				//turns off alarm indicator.
	 delay_ms(500);				//time delay for 0.5secs.
   }while (i!=10);				//repeats the flash for 10secs.
 }//end of function.
 
 
/////////////////////////////////////////////////

//THIS HASN'T BEEN USED IN THE PROGRAM////////

void delay(int value, int count)
{
unsigned char inbyte;
do{
tmr0 = value;
do{inbyte=tmr0;
value--;
}
while (inbyte!=0);
count--;
}while (count!=0);
} //end of delay.
//////////////////////////////////

/////////////////////////////////////////////////////////////////////////
//////////COMMENTED OUT, NOT SURE EAXACLTY HOW TO USE IT.////////////////
//void interrupt(void){

// writing 9 onto tmr0 will generate interrupts at 250us interval.
//   tmr0 += 9;   
//   tick++;       //increment variable tick.
//  if(tick>19)   //if tick equals 20, increment tick1 & reset tick.
//   {
//   tick=0;
//   tick1++;      //if tick1 equals 200,we have counted 4000 ticks
//if(tick1>199)    //in total, which equals 1 second(4000*250us).
//   {
//   nxtstate = 5;
//   tick1=0;        //reset tick1.
//    }
//    }
   // intcon.2=0;  //clear TMR0 overflow flag
//   clear_bit(intcon, TOIF);
//}

Attached Files



#2 joli

joli

    Regular

  • EstablishedMember
  • Pip
  • 81 posts
  • Gender:Male
  • Location:Portugal

Posted 08 August 2016 - 12:37 PM

ANDYp,

 

looking at datasheet, timer 1 section, i can't see how to achieve 20 minutes with timer 1 interrupt... lets see:

 

clock = 4000000 Hz

maximum prescaler = 8

maximum timer 1 count = 65536

 

t1_tick = 1 ( 4000000 / 4 / 8 / 65536 ) = 0.524288 secs

 

But it can be used by polling the timer 1 interrupt flag and count the number of times that the TMR1IF rises.

To achieve 20 mins the number of counts is 20*60/ t1_tick = 2288

Then you can call your function to change state or whatever you want

 

timer 1 interrupt isn't need,  polling pir1.TMR1IF is enough.

 

write a function to do it and call this function from main.

 

If my math is right it should work pretty well

 

br


Edited by joli, 15 August 2016 - 01:12 AM.


#3 Mamed9

Mamed9

    Newbrie

  • Members
  • 1 posts
  • Gender:Male
  • Location:143040
  • Interests:RobertcupDJ

Posted 05 September 2016 - 05:44 PM

you could just enable timer 1 and let it run and read the counter value from the main program. Note that the timer runs downwards and generates interrupt when it hits zero. Also note that some calls to ROM such as InitHardware might enable or disable timers or interrupts, there might be a difference in the operation depending on where in your code you enable the timer and the interrupt. -Panu

#4 JorgeF

JorgeF

    Super Enthusiast

  • EstablishedMember
  • PipPipPip
  • 276 posts
  • Gender:Male
  • Location:ES @ Europe, third rock from the Sun

Posted 18 September 2016 - 01:47 PM

................... the timer runs downwards and generates interrupt when it hits zero....................

 

!!!!!!??????

 

 

 

Best regards

Jorge


Edited by JorgeF, 18 September 2016 - 01:47 PM.




Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users