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.

PIC interrupt handeling basics RB0

Status
Not open for further replies.

LUNAR

New Member
Hello i am using PIC18F4550 and i want to use its interrupts, i have written a simple code to blink an led when interrupt is received on RB0. But its not working please see the code and guide.
thanks
Code:
//************************************************************************************************* 
//test code for int0, blink led on portD on receving interrupt

#include <p18f4450.h>
void main (void);
void InterruptHandlerHigh (void);

void main ()
{
	int i=0;
	INTCON2bits.INTEDG0=1;//m interrupt is rising edge
	INTCONbits.INT0IE=1;//m enable  interrupt
  	INTCONbits.GIEH = 1;          //enable global interrupts
  	TRISB = 1;			//set port b as input
	TRISD=0;			//set port d as output
	while(1);//move in loop, gets out on receving interrupt and then comes back.
}//end main

// High priority interrupt vector
#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
  _asm
    goto InterruptHandlerHigh //jump to interrupt routine
  _endasm
}
//----------------------------------------------------------------------------
// High priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerHigh
void
InterruptHandlerHigh ()
{	int i=0;
	int j=0;
	if (INTCONbits.INT0F)
	{
	INTCONbits.INT0IE=0;//m disable the interrupt

		for(j=0;j<4;j++)//toggle the bit0 or portD on receiving interrupt
		{
			LATDbits.LATD0 = 1;
			for( i=0;i<40000;i++);
			LATDbits.LATD0 = 0;
			for( i=0;i<40000;i++);
		}	 

	INTCONbits.INT0F=0;	//m reset the flag
	}
INTCONbits.INT0IE=1;//m enable the interrupt
}

//----------------------------------------------------------------------------
//*************************************************************************************************
 
Looking at your code I don't see any config data. What are you using as an oscillator? Also, by default interrupts go through the low priority vector at 0x18.

Mike.
 
thanks for quick reply
i am using 20Mhz crystal.
do u mean i have to change
"#pragma code InterruptVectorHigh = 0x08"
to
"#pragma code InterruptVectorHigh = 0x18"
for external hardware interrupts.
 
Here's some code that uses timer 0 to generate an interrupt and complement port C at approx 1Hz. This uses the internal oscillator and so you should be able to see if your hardware is working. Just change the LATC to LATDbits.LATD0 to test your hardware. <edit> and the TRISC to TRISD.</edit>

Code:
#include <p18f4450.h>
#pragma config WDT = OFF, LVP = OFF, FOSC = INTOSC_HS

void main (void);
void InterruptHandlerLow (void);

void main (){
    TRISC=0;                //Port C = output
    T0CON = 0b10000001;     //prescaler = 4 
    INTCONbits.TMR0IE=1;
    INTCONbits.GIE=1;    
    while(1);
}

//Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow
  _endasm
}

// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void
InterruptHandlerLow (){    
    if (INTCONbits.TMR0IF){
        LATC=~LATC;
        INTCONbits.TMR0IF=0;
    }
}
You should then be able to change the above to generate int0 interrupts.

Mike.
 
Last edited:
no luck, please see what is it that i am missing.
Code:
#include <p18f4450.h>
#pragma config WDT = OFF, LVP = OFF, FOSC = INTOSC_HS

void main (void);
void InterruptHandlerLow (void);

void main (){
    TRISC=0;                //Port C = output

/*    T0CON = 0b10000001;     //prescaler = 4 
    INTCONbits.TMR0IE=1; */
    INTCONbits.GIE=1;   //enable global interrupts

INTCON2bits.INTEDG0=1;//m interrupt is rising edge
INTCONbits.INT0IE=1;//m enable  interrupt
PORTBbits.INT0=1;

    while(1);
}

//Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow
  _endasm
}

// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void
InterruptHandlerLow (){    
    /*if (INTCONbits.TMR0IF){

        LATC=~LATC;
        LATB=~LATB;

        INTCONbits.TMR0IF=0;
    }*/

	if (INTCONbits.INT0F)
	{
	    LATC=~LATC;
        //LATB=~LATB;

	INTCONbits.INT0F=0;	//m reset the flag
	}
INTCONbits.INT0IE=1;//m enable the interrupt
}
 
Your code looks like it should work. Did you try the code using the timer interrupt and just changing it to flash your LED. This will tell you if your pic is actually working.

Can you try the following code and confirm your LED flashes,
Code:
#include <p18f4450.h>
#pragma config WDT = OFF, LVP = OFF, FOSC = INTOSC_HS

void main (void);
void InterruptHandlerLow (void);

void main (){
    TRISD=0;                //Port C = output
    T0CON = 0b10000000;     //prescaler = 2
    INTCONbits.TMR0IE=1;
    INTCONbits.GIE=1;    
    while(1);
}

//Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow
  _endasm
}

// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void
InterruptHandlerLow (){    
    if (INTCONbits.TMR0IF){
        LATD^=1;
        INTCONbits.TMR0IF=0;
    }
}
Mike.
 
As the above code works (via PM) we now know your hardware is OK. Having looked at the data sheet I see RB0 can be configured as analogue. I suspect this was your problem all along. With this in mind try,

Code:
#include <p18f4450.h>
#pragma config WDT = OFF, LVP = OFF, FOSC = INTOSC_HS

void main (void);
void InterruptHandlerLow (void);

void main (){
    TRISC=0;                //Port C = output
    ADCON1=0x0e;            //all digital
    INTCON2bits.RBPU=0;     //WPUs on
    T0CON = 0b10000000;     //prescaler = 2
    INTCONbits.TMR0IE=1;    //enable timer interrupts
    INTCONbits.INT0IE=1;    //enable Int0 interrupts
    INTCONbits.GIE=1;       //enable global interrupts
    while(1);
}

//Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow
  _endasm
}

// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void
InterruptHandlerLow (){    
    if (INTCONbits.TMR0IF){
        LATC^=2;
        INTCONbits.TMR0IF=0;
    }
    if (INTCONbits.INT0IF){
        LATC^=2;
        INTCONbits.INT0IF=0;
    }
}

The above should flash the LED and give extra flashes when your key is pressed. To stop it flashing remove the line which sets up TMR0IE.

Let us know if that works?

Mike.
 
NO dear, its not working. I am not getting any blink either on timer nor on interrupt.
THANKS FOR HELPING.
please guide what should i do next.

at some place i read that "fuse" also has something to do with the problem. what do u think?
 
Its Working , Its Working, Yahooooooooooo.
U Rock Man.
Thanks A Lot, I Have Spent 16 Hours To Solve This Problem .
Thanks Man.
U Are Great.
 
So, now it is working what are you going to do with it? Do you need it to run faster, it's running at 1MHz at the moment and not using the external crystal as the oscillator.

Mike.
 
ya now i have to figure out a way to run it with crystal.
i wanted to interface a keypad with controller and use this interrupt pin to interrupt the system that new data is avaiable on the port.

btw for how long have u been working on pics, and what is (via PM)?
 
ya now i have to figure out a way to run it with crystal.
i wanted to interface a keypad with controller and use this interrupt pin to interrupt the system that new data is available on the port.

btw for how long have u been working on pics, and what is (via PM)?
 
To get it to work with the crystal you need to change the config line to,
Code:
#pragma config WDT=OFF,LVP=OFF,FOSC=HSPLL_HS,PLLDIV=5,CPUDIV=OSC2_PLL3
This will make your pic run 32 times faster.

I've been programming for about 30 years and pics for about about 10. PM = personal message.

Mike.
 
It really doesn't matter how you learn to program. If you learn to program microcontrollers to an efficient level then you will be able to program most things with a little more learning (Object orientated excepted).

You actually jumped into the deep end by choosing the 18F4550 as this is complicated by the fact is supports USB.

There are no short cuts but hopefully you have tasted enough to persevere and learn more. I've been doing this (programming) for nearly 30 years and still find it enjoyable.

Mike.
 
Pommie. You obviously have vastly more experience than most (including me ;-) but the notion of "efficient" and "short cut" are surely dependent on requirements.

Interpreted Basic is an efficient short cut to the PIC experience, but very inefficient speed and code wise, horses for courses. I propose that how you learn is critically important. The deep end can be fatally disappointing to start with.
 
Pommie.
Interpreted Basic is an efficient short cut to the PIC experience, but very inefficient speed and code wise, horses for courses. I propose that how you learn is critically important. The deep end can be fatally disappointing to start with.

I agree with you completely. I learn't to program on a Apple II in basic. I then went on to assembler and now see the need for all languages (but not sure about OO). It really doesn't matter on the language as long as you learn how the code flows and how memory becomes variables etc.

I now prefer C as it is pretty much universal but to program pics in C (or basic) you need an understanding of the underlying hardware.

I will add, most of the requests we get on here could be done on a picaxe without too much difficulty and probably without any coaching. Actually, that is probably why not many people ask picaxe questions on here.

Mike.
 
Use PICAXE, Interupts are a no-brainer, software is free, unbelievably short learning curve

PICAXEs are a form of BASIC interpreter and run out of steam quickly compared to a compiled language. If you like BASIC (I do) try Swordfish BASIC for the PIC18F and interrupts are easy on it too. Actually interrupts are pretty easy anyway on the PIC.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top