Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to use Interrupt in PIC16F877A in C..??

Status
Not open for further replies.

koolguy

Active Member
Hi,

I am learning pic 877A uC i have done testing with loop and if else condition now i am moving on interrupt please tell how to use interrupt for example at RB0 ...?
i have seen data sheet and i am not getting what to do, ass the stimulus in MP LAB 8.77 is going over my head....
 
Hitech HAS a really good interrupt example..
Code:
#include	<htc.h>

/*
 *	Interrupt test for PIC 
 *
 *	Copyright (C)1997 HI-TECH Software.
 *	Freely distributable.
 */

static volatile long	count;
static volatile bit	bad_intr;

void
main(void)
{
	/* setup stuff */

	T0CS = 0;		// Timer increments on instruction clock
	TRISB = 0xFE;		// Port B bit 0 is output 
	T0IE = 1;		// Enable interrupt on TMR0 overflow
	GIE = 1;		// Global interrupt enable
	for(;;)
		CLRWDT();	// Idly kick the dog
}

static void interrupt
isr(void)			// Here be interrupt function - the name is
				// unimportant.
{
	if(!T0IF)		// Was this a timer overflow?
		bad_intr = 1;	// NO! Shock horror!
	count++;		// Add 1 to count - insert idle comment
	T0IF = 0;		// Clear interrupt flag, ready for next
	PORTB ^= 1;		// toggle bit 0 of Port B, to show we're alive
}

I must admit that the stimulus in MPLAB is a bit of a grind.... I'll make a stimulas file and some code for the RB0 int, so you can see how it works!!
 
Ok..
Code:
#include	<htc.h>

/*
 *	Interrupt test for PIC 
 *
 *	Copyright (C)1997 HI-TECH Software.
 *	Freely distributable.
 */

static volatile long	count;


void
main(void)
{
	/* setup stuff */

	TRISC = 0x0;		// Port C is output 
	INTE = 1;		// Enable interrupt on int0
	GIE = 1;		// Global interrupt enable
	for(;;)
		CLRWDT();	// Idly kick the dog
}

static void interrupt
isr(void)			// Here be interrupt function - the name is
				// unimportant.
{
	if(INTF)		// Was this a interrupt?
		count++;		// Add 1 to count     ///  <<< Place breakpoint here!!!
	INTF = 0;		// Clear interrupt flag, ready for next
	PORTC = count;		// count on port c
}

If you open a stimulus window
Using ASYNC tab, Select RB0 as pin / sfr, set to Toggle... Now every time you click the little ">" button under "Fire" the stimulus will cause an interrupt

If you place a breakpoint where I have said...
 
Last edited:
PORTC is used for reading interrupt but RB0 is shown in data sheet??

Where did you get that from???? I was using port c as a visual aid... ( the code should be "TRISC = 0;" )
 
I am not getting it i have seen RB0 as interrupt...if i want to interrupt the uC externally by switch what changes i have to do???
 
Does the stimulus window open? I was showing how the stimulus window works...

Yes everything was working fine but the code is not clear to me....

here /* setup stuff */
i have written the blinking led but not clear the execution stop at clrwdt why?? i fire two times then it moves, why???


Code:
void
main(void)
{
	/* setup stuff */
 
	TRISC = 0x0;		// Port C is output 
	INTE = 1;		// Enable interrupt on int0
	GIE = 1;		// Global interrupt enable
	for(;;)
		CLRWDT();	// Idly kick the dog
}
 
The forever loop contains the
Code:
CLRWDT();
function...

This is because the watchdog is enabled in the config ( not my code... example code ). The code will NEVER move from here!!

Every time you fir the stimulus... the code enters the interrupt. This is why I told you to put a breakpoint INSIDE the ISR routine...
 
I'm not trying to do anything other than trying to explain the interrupt on pin RB0.... This is what you asked for!!!

There is a section of code "for(;; )"..... Waiting for an interrupt on RB0.... when you fire the stimulus. the interrupt occurs... You can see the count on PORTC.... It doesn't get any easier!!!


To make it easier for you to see what's going on... do not RUN run.png the sim... ANIMATEanimate.png the sim
 
Last edited:
OK, why are you using CLRWDT(); and can't understand this function b'coz where it is called and on changing the name shows error..

You can call it what you want... BUT "void interrupt" are mandatory... So "void interrupt riteshesinterrupt()" will work...

When you use C, the interrupt vector is done for you..... And as I said, This isn't my code I got it from the HTC examples directory... You do not need the "clear watchdog" function if you disable it in the config...
 
Now i am getting you...
for(;; ) why it is here??
CLRWDT(); why bracket are used??

If it was written like this

Code:
   for( ; ; )         /// This is a forever loop... same as goto$-1 in ASM..
      {
       CLRWDT();     /// This is a FUNCTION!! in the HTC libraries somewhere..
      }
 
You mean Timers!!!

The first code posted was for an interrupt on timer0..

Code:
#include	<htc.h>
 
/*
 *	Interrupt test for PIC 
 *
 *	Copyright (C)1997 HI-TECH Software.
 *	Freely distributable.
 */
 __CONFIG(0x3f72);

static volatile long	count;
static volatile bit	bad_intr;
 
void main(void)
   {
	/* setup stuff */
 
	T0CS = 0;		// Timer increments on instruction clock
	TRISB = 0xFE;		// Port B bit 0 is output 
	T0IE = 1;		// Enable interrupt on TMR0 overflow
	GIE = 1;		// Global interrupt enable
	for(;;)
		{}     // REMOVED the WDT function!!!!
   }
 
static void interrupt timerInt(void)			// Here be interrupt function - the name is
				// unimportant.
   {
	if(!T0IF)		// Was this a timer overflow?
		bad_intr = 1;	// NO! Shock horror!
	count++;		// Add 1 to count - insert idle comment
	T0IF = 0;		// Clear interrupt flag, ready for next
	PORTB ^= 1;		// toggle bit 0 of Port B, to show we're alive
   }

Basically:-

Load a pre-scaler. (timer 0 uses option reg )
Set the interrupts. (if needed)
start the timer. (timer 0 is always running )
wait for the interrupt to fire OR check the timers overflow flag.
Or even keep checking against a constant number.

You can always use the timer to count an input signal by re-routing the clock of the timer to input pin RA4 (TOCK1) for timer 0.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top