PIC18 & interupt

Discussion in 'Embedded Systems and Microcontrollers' started by ect_09, Jul 19, 2012.

  1. ect_09

    Thread Starter Member

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

    Code ( (Unknown Language)):
    2. #include <P18f458.h>
    3. //#include <delay.h>
    5. #pragma config PWRT =OFF
    6. #pragma config BOR =OFF
    7. #pragma config DEBUG =OFF
    8. #pragma config OSC      =HS // 4MHz Crystal, (HS oscillator)
    9. #pragma config WDT      =OFF   // watch dog timer off
    10. #pragma config LVP     =OFF   // Low voltage program off
    12. void chk_isr(void);
    13. void chk_data(void);
    16. #pragma interrupt chk_isr
    17. void chk_isr(void)
    18. {if(INTCONbits.INT0IF==0)
    19. chk_data();
    21. }
    22. #pragma code my_HiPrio_int=0x08
    23. void my_HiPrio_int(void)
    24. {_asm
    25. GOTO chk_isr
    26. _endasm
    28. }
    30. #pragma code
    31. void main()
    32. {
    33. TRISBbits.TRISB6=1;
    34. TRISBbits.TRISB0=0;
    35. INTCONbits.INT0IF=0;
    36. INTCONbits.INT0IE=1;
    37. INTCONbits.GIE=1;
    38. }
    39. void chk_data(void)
    40. {TRISBbits.TRISB6=1;
    41. INTCONbits.INT0IF=0;
    43. }
    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.
  2. takao21203

    Distinguished Member

    Apr 28, 2012
    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.
  3. ect_09

    Thread Starter Member

    May 6, 2012
    i write this code by following mazidi book..
    so am trying for it.
  4. takao21203

    Distinguished Member

    Apr 28, 2012
    let the forum know how it works out further, and if you can put it to working condition.
  5. JohnInTX


    Jun 26, 2012
    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:

    Code ( (Unknown Language)):
    1. #include <P18f458.h>
    2. //#include <delay.h>
    4. #pragma config PWRT =OFF
    5. #pragma config BOR =OFF
    6. #pragma config DEBUG =OFF
    7. #pragma config OSC      =XT // 4MHz Crystal - Table 2-1 in databook
    8. #pragma config WDT      =OFF   // watch dog timer off
    9. #pragma config LVP     =OFF   // Low voltage program off
    11. void chk_isr(void);
    12. void chk_data(void);
    15. #pragma interrupt chk_isr
    16. void chk_isr(void)
    17. {
    18. if((INTCONbits.INT0IF) && (INTCONbits.INT0IE))  // only sample INT0IF if irq is enabled
    19.     {
    20.     chk_data();             // simple service routines can be inline instead of calls
    21.     INTCONbits.INT0IF=0;    // clear flag here where you can see it
    22.     }
    23. }
    24. #pragma code my_HiPrio_int=0x08
    25. void my_HiPrio_int(void)    // what the heck is this? GOTO??  see compiler templates for interrupts..
    26. {_asm
    27. GOTO chk_isr
    28. _endasm
    30. }
    32. #pragma code
    33. void main()
    34. {
    35.     LATBbits.LATB6 = 0;     // init port bit before TRIS
    36.     TRISBbits.TRISB6=0;     // RB6 is OUTPUT
    37.     TRISBbits.TRISB0=1;     // INT0 is INPUT
    38.     INTCONbits.INT0IF=0;    // Good! clear IRQ flag before enabling it
    39.     INTCONbits.INT0IE=1;
    40.     INTCONbits.GIE=1;
    42.     while(1);               // something for the processor to do while waiting for IRQ
    43. }
    45. void chk_data(void)
    46. {
    47.     LATBbits.LATB6 ^= 1; // Toggle RB6 output each IRQ service
    48. }
    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 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: Jul 21, 2012