PIC18 & interupt

Thread Starter

ect_09

Joined May 6, 2012
180
Am working with interupts.
i write my code as it is given below.

Rich (BB code):
#include <P18f458.h>
//#include <delay.h>

#pragma config PWRT =OFF
#pragma config BOR =OFF
#pragma config DEBUG =OFF
#pragma config OSC      =HS // 4MHz Crystal, (HS oscillator)
#pragma config WDT      =OFF   // watch dog timer off
#pragma config LVP     =OFF   // Low voltage program off

void chk_isr(void);
void chk_data(void);


#pragma interrupt chk_isr
void chk_isr(void)
{if(INTCONbits.INT0IF==0)
chk_data();

}
#pragma code my_HiPrio_int=0x08
void my_HiPrio_int(void)
{_asm
GOTO chk_isr
_endasm

}

#pragma code
void main()
{
TRISBbits.TRISB6=1;
TRISBbits.TRISB0=0;
INTCONbits.INT0IF=0;
INTCONbits.INT0IE=1;
INTCONbits.GIE=1;
}
void chk_data(void)
{TRISBbits.TRISB6=1;
INTCONbits.INT0IF=0;

}
when i apply the 5v on RB0/INT0 in proteous then no interupt come on RB6.
what is the reason?
is there any problem in code.
 

takao21203

Joined Apr 28, 2012
3,702
You are mixing up some things here.

1. the main routine will run only once, what happens after that is undefined.

2. You set the TRIS bit again from the isr. No need for this.

3. You test for INT0IF==0, but that's incorrect.

You need to test for INT0IE&&INT0IF.

Or is it you want to float RB6 by setting the TRIS bit?

Your code is majorly incorrect, I suggest to read my explanation, and I hope it's correct.

You could use MPLABX, and you get a project template, and you would see for yourself. It is helpful actually. And always test for INT0IE&&INT0IF.

You could also test for INT0IF==1 but not needed. Why you test for INT0IF==0 is a riddle to me.

The INTCONbits can be omitted by the way.

RB6 is deprecated! So if you want to set/reset it, use LB6.
 

JohnInTX

Joined Jun 26, 2012
4,787
Review what takao21203 has said and do it. 'majorly incorrect' is being kind.

You didn't say what compiler you were using so I built your code on HiTech PICC18 - it didn't build (PICC18 uses different methods for defining SFRs)
Then I tried C18 under MPLAB 8.63. It built but hung up in the C init code (before main - WTF??)
I built it under MPLAB X using XC8 - it did not build (different pragma syntax).
Boy, so much for C being portable eh?

Finally, I built it under MPLAB X using C18 Ver 3.40. That worked but of course, your code did not. I haven't used MPLAB X with C too much so thought I'd debug your code a bit as an exercise for me. Here it is:

Rich (BB code):
#include <P18f458.h>
//#include <delay.h>

#pragma config PWRT =OFF
#pragma config BOR =OFF
#pragma config DEBUG =OFF
#pragma config OSC      =XT // 4MHz Crystal - Table 2-1 in databook
#pragma config WDT      =OFF   // watch dog timer off
#pragma config LVP     =OFF   // Low voltage program off

void chk_isr(void);
void chk_data(void);


#pragma interrupt chk_isr
void chk_isr(void)
{
if((INTCONbits.INT0IF) && (INTCONbits.INT0IE))  // only sample INT0IF if irq is enabled
    {
    chk_data();             // simple service routines can be inline instead of calls
    INTCONbits.INT0IF=0;    // clear flag here where you can see it
    }
}
#pragma code my_HiPrio_int=0x08
void my_HiPrio_int(void)    // what the heck is this? GOTO??  see compiler templates for interrupts..
{_asm
GOTO chk_isr
_endasm

}

#pragma code
void main()
{
    LATBbits.LATB6 = 0;     // init port bit before TRIS
    TRISBbits.TRISB6=0;     // RB6 is OUTPUT
    TRISBbits.TRISB0=1;     // INT0 is INPUT
    INTCONbits.INT0IF=0;    // Good! clear IRQ flag before enabling it
    INTCONbits.INT0IE=1;
    INTCONbits.GIE=1;

    while(1);               // something for the processor to do while waiting for IRQ
}

void chk_data(void)
{
    LATBbits.LATB6 ^= 1; // Toggle RB6 output each IRQ service
}
takao21203's suggestions are valid and are in the modified code. There were other problems as well:
XT is the correct OSC setting for a 4MHz XTAL (databook). HS will work but it bangs the crystal harder than it might like.
RB0 was an output (so it could not see your interrupt). Now its an input.
RB6 was an input .. no help there. I made it an output.
I don't get the _asm GOTO stuff It works but its not a good construct.
You should always perform a FULL initialization of the I/O, not just the bits you are going to use.
The while(1) at the end of main allows the processor to run after init while waiting for an interrupt.
I added a bit toggle to the output to change it every IRQ.

BTW: examining the assembler output of the compiler what happens if you run off the end of main is it RETURNS to the C startup code, does some housekeeping and calls main again. That's pretty typical but NOT recommended.

You can build and run this using the simulator. Open a watch window and load TRISB, LATB and INTCON. Using MPSIM, step the code from main until you hit the while(1). Inspect the I/O and IRQ setup.

Then in the watch window, write a 1 to INTCON bit 0 (INT0IF). Step again and you should enter the interrupt routine. Step through chk_data and watch LATB:6 toggle each time. When the IRQ completes, you'll be back at the watch(1).

There is still lots wrong here as far as organization, constructs, programming discipline etc. but this should get you started.

i write this code by following mazidi book
I see on another post that you are looking for additional sources. I think that would be a good idea. A good book on structured programming using C should be first. You can get most of the PIC stuff from the databook, Microchip's website, appnotes, MPLAB templates and right here.
 
Last edited:
Top