Jump to content
Sign in to follow this  
Paolino

Interrupt Handler

Recommended Posts

I have seen that BoostC permits one interrupt handler called "interrupt"; I have not yet explored that land but I think that I have to manage each single interrupt event inside that routine, is that correct? I mean, if I would like to manage T0IF, T1IF, RB0/INT interrupt etc, I have to make a if-else-else if- structure to manage all them, correct?

And what about interrupt for PIC18? They have low and high priority interrupt; how can I distinguish one from the other?

 

Thank you.

 

Paolo.

Share this post


Link to post
Share on other sites
I have seen that BoostC permits one interrupt handler called "interrupt"; I have not yet explored that land but I think that I have to manage each single interrupt event inside that routine, is that correct? I mean, if I would like to manage T0IF, T1IF, RB0/INT interrupt etc, I have to make a if-else-else if- structure to manage all them, correct?

And what about interrupt for PIC18? They have low and high priority interrupt; how can I distinguish one from the other?

 

Thank you.

 

Paolo.

 

If you are looking for an example of multiple interrupts, i can give you an example i am right now working on. Its an frequency/RPM meter. It measures the time interval between two pulses of a optical or proximity sensor. There are two interrupt generating source, they are timer1 over flow flag & ccp capture flag. An LCD is use to display the RPM. I am using PIC16F72.

I have tested it on the SB simulator & it works fine.

code..

#include <system.h>
#include "lcd_driver.h"

// Set clock frequency to 4MHz.

#pragma CLOCK_FREQ 4000000

//set configuration fuse.
#pragma DATA _CONFIG, _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_OFF


#define LCD_ARGS 	2,	/* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \
	0, 				/* Use busy signal: 1 = use busy, 0 = use time delays */\
	PORTC, TRISC, 	/* Data port and data port tris register */ \
	PORTB, TRISB, 	/* Control port and control port tris register */ \
	2,				/* Bit number of control port is connected to RS */ \
	7,				/* Bit number of control port is connected to RW */ \
	3 				/* Bit number of control port is connected to Enable */


unsigned char tick;
unsigned int value1;
bit frequency_update_flag;

/*Interrupt service routine (ISR).On timer1 overflow or  
ccp pulse capture program will jump to this code location.  */	
void interrupt( void )
{
unsigned char capture_count;

  if(pir1.0 == 1)   //tmr1 overflow flag(tmr1if).
{
  tick++;           // count the number of tmr1 interrupts.
  if(tick > 15)    //if frequency is too low
 {
  ccp1con = 0;
  t1con = 0;
  tmr1l = 0;
  tmr1h = 0;
  tick = 0; 
  value1 = 0;
  capture_count = 0;  
  frequency_update_flag = 1;
 }  
  pir1.0 = 0;       //clear tmr1if 
}

  else
  
  if(pir1.2 == 1)   //ccp interrupt flag(ccp1if).
{
  capture_count ++;
  if(capture_count > 1)
 {
  t1con = 0;
  ccp1con = 0;       //switch off capture mode.
  value1 = tmr1l + (tmr1h * 256); 
  
  capture_count = 0;
  frequency_update_flag = 1;
  }
  
  else
//The first ccp interrupt resets tmr1 & starts it.   
 {
  t1con = 0;
  tick = 0;
  tmr1l = 0;
  tmr1h = 0;
  t1con = 1;
 }
  
  pir1.2 = 0;     //clear ccp flag.
}
}  

/* function to display RPM. */

void display (int x)
{
   lcd_clear();   
   lprintf("%d",x);
   delay_s(2);
}

/* The main code configures the intcon, pie1, t1con & ccpcon1 
  registers.*/

void main()
{
trisb = 0;		 //configure port B
portb = 0;		 //clear port B
trisc = 0b00000100; //RC2/ccp1 pin as input.


// enable interrupts: interrupt control register.
intcon.6=1;     //enable peripheral interrupts    
intcon.7=1;     //enable global interrupt

//peripheral interrupt enable register 1.
   pie1.2 = 1;    //enable ccp1 interrupt.
   pie1.0 = 1;    //enables tmr1 overflow interrupt.
   
/*  timer1 control register:

   t1ckps1:t1ckps0: input prescaler
   bit5-4.....select 00= 1:1 prescale
   
   tmr1cs: timer1 clock source select bit.
   bit1...select 0 = internal clock (Fosc/4)
   
   tmr1on: timer1 on bit
   bit0......1 = enable timer1
   bit0......0 = stop timer1         
  	 
we are not concerned about the other bits of t1con. */

//set t1con
   t1con = 0b00000000;  //tmr1 not yet enabled.
   
/*ccpcon1: capture/compare/pwm control register1. 
   
   bit3-0.....ccpxm3:ccpxm0: ccpx mode select bits.
   we will use...
   0100 = capture mode, every falling edge.
   0101 = capture mode, every rising edge.
 we can choose any one of the above mode.
 but we will use 0100 in our project.  
*/

/* print " RPM = " in the first line of LCD */

   lcd_setup();
   lcd_clear();
   lprintf(" RPM = ");
   lcd_gotoxy(0,1);

unsigned long count; 
   while (1)
{    
   frequency_update_flag = 0;
   ccp1con = 0b00000101;  //set capture mode.   
   t1con = 1;  //start timer1.
     
 while (frequency_update_flag == 0);   
 
 count = (tick*65536) + value1;
 if(count == 0)   //if frequency is too low.
 {
 display(count); 
 }
 else
 {
 count = 100000000/count; //to find frequency.
 count *= 60;      //for cycles per minute.
 count /= 100;     //divide by 100 to get actual RPM.
 display(count);
 }	 
}
}

 

see if its useful.

Regards

Raghunathan.

Share this post


Link to post
Share on other sites

PICs have two types of interrupts, priority and non-priority but both share

the same cavet; do the LEAST amount of processing possible in the interrupt.

 

The normal way to handle this is to set/clear a flag and address the usage in

your main code. The reasoning is that your system will very quickly fall out

of sync if you do too much in your interrupt and may wander off doing

unexpected things.

 

An interrupt is an immeadiate exit from the main program to handle an

important process( like a data receive event ) that may happen when

the PIC is doing something else which takes a long time( like writting to

an LCD ).

 

The difference between priority and non-priority is that when using priority

interrupts there are two levels ( commonly called high and low ). The high

level allows critical interrupts to happen while the PIC is in a low level

interrupt state. Concider and ECG that might use a low interrupt for period

counting of heart beats and a high interrupt for a flatline alarm.

 

Without priority, what would happen is that the interrupts enter a stack/queue

and get processed in order as the first on finishes( there is a maximum queue

size which varies from PIC to PIC).

 

Before i forget, if your using a software flag that you need access to in your

program it will need to be a global variable. You cannot access normal program

variables due to the context saving scheme.

 

Hope that helps you to understand roughly how interrupts work.

Share this post


Link to post
Share on other sites

Hi guys.

 

see if its useful.

Regards

Raghunathan.

 

Thank you, Raghunathan. It was like I suspected, but your example is very clear.

 

PICs have two types of interrupts, .....

Hope that helps you to understand roughly how interrupts work.

Thank you, emte. Luckly I know the mechanism of Interrupt (I have been working with PICs CCS PCWH compiler since 2001 and also with other microcontroller). My questions (sure will follow others) come out to understand how BoostC works.

Anyway I appreciate your help and hope it comes again in the next threads I will post. :)

 

Thank you again to both for your suggestions.

 

Best regards,

 

Paolo.

Share this post


Link to post
Share on other sites

Paolino,

I have seen that BoostC permits one interrupt handler called "interrupt"; I have not yet explored that land but I think that I have to manage each single interrupt event inside that routine, is that correct? I mean, if I would like to manage T0IF, T1IF, RB0/INT interrupt etc, I have to make a if-else-else if- structure to manage all them, correct?

And what about interrupt for PIC18? They have low and high priority interrupt; how can I distinguish one from the other?

On pic18 use:

void interrupt()
{
   ....
}

void interrupt_low()
{
   ....
}

for different priority interrupts.

 

Regards

Dave

Share this post


Link to post
Share on other sites

I have been reading that BoostC has one interrupt - is it the same with other PIC compilers? If I were to code in ASM, would I be able to use multiple interrupts? Or is the single interrupt scheme peculiar to the PICs? Thanks.

Share this post


Link to post
Share on other sites
I have been reading that BoostC has one interrupt - is it the same with other PIC compilers? If I were to code in ASM, would I be able to use multiple interrupts? Or is the single interrupt scheme peculiar to the PICs? Thanks.

Hi dersk, yes the single interrupt scheme is peculiar to PICs. See, PICs have one reset vector 0x0000 and one interrupt vector 0x0004. Pics 18FXX and up have two interrupt vector, low priority (0x0004)and a high priority(0x0008, i think) interrupt vectors. On interrupt program flow branches to interrupt vector.Now, for a branching to the interrupt vector to occur three things must happen:

1) That particular interrupt must be eneabled

2) General interrupt bit on intcon register must be set(eneabling general interrupts)

3) The flag of that particular interrupt gets set.

 

Once in interrupt service routine, is up to you to determine(testing the repective interrupt flags) wich one caused the interrupt(that is if you have more that one interrupt enabled, of course). Don´t forget to clear those flags before returning from interrupt.

 

Notice one thing: If you enable one particular interrupt, but do not enable general interrupt, once that interrupt ocurs program flow will continue on the value that program counter had before interrupt + 1.

If you want, I´ll put some example in C and assembler, just ask :)

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...