About PIC Timer And Interrupt

Discussion in 'Embedded Systems and Microcontrollers' started by ali1980, Nov 17, 2015.

  1. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    Hello guys , the long_click function could not executed even I press the push button for long time ., always short_click function works
    anybody advice ?



    // ************************************************************//
    /* PIC16F88 */


    unsigned int volatile counter = 0 ;
    bit flag ;

    void Interrupt()
    {
    while (PORTB.F0==0 && INTCON.TMR0IF == 1) {
    counter++ ;
    INTCON.TMR0IF=0;
    INTCON.GIE = 1 ;
    if ( counter >6500) { // reset counter value
    counter = 0 ;
    }

    }

    void main() {


    unsigned int Interval ;
    OSCCON = 0b01111110 ; // Internal OSC 8 MHz
    TRISA.F0 = 0 ; // RA0 as output
    TRISB.F0 = 1 ; // RB0 as Input
    PORTA.F0= 0 ; // ( Led connected )
    PORTB.F0= 1 ; // push button
    INTCON = 0b10000000 ;
    OPTION_REG = 0b11000010 ; // interrupt on RB0 rising edge (push button) , prescaler 32 , Timer0 overflow interrupt every 1ms
    ANSEL = 0 ; // All ports as digital I/O



    while(1){ // infinite loop

    Interval = counter ; // assign counter to Interval
    if(PORTB.F0 == 0 ) { //if button pressed
    delay_ms(10); // delay
    INTCON.TMR0IE = 1 ; // enable timer0 Interrupt
    INTCON.INT0IE = 1; // enable RB0 interrupt
    INTCON.GIE = 0 ; // enable global interupt
    flag = 1 ; // set flag
    }

    if (flag && PORTB.F0== 1 && INTCON.INT0IF == 1) // if flag and button released and INT flag do
    {

    if(Interval<=500){ // if Interval below 500ms do
    Run_Short_Click();
    Interval = 0;
    counter = 0 ;
    }
    if(Interval>500){ // if Interval greater 500ms do // Note this not executed even long hold of button
    Run_Long_Click();
    Interval = 0;
    counter =0 ;
    }
    INTCON.INT0IE = 0; // disable RB0 interrupt
    flag=0 ; // clear flag
    }

    }

    }


    void Run_Short_Click() short click
    {
    unsigned char j ,x ;
    for( j=0;j<2 ;j++ )
    {
    PORTA.F0 = 1 ;
    delay_ms( 100);
    PORTA.F0 = 0 ;
    delay_ms( 100);

    }

    void Run_Long_Click()
    {
    unsigned char j ,x ;
    for( j=0;j<4 ;j++ ) {
    PORTA.F0 = 1 ;
    delay_ms( 125);
    PORTA.F0 = 0 ;
    delay_ms( 125);

    }
     
  2. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    What have you done to troubleshoot the issue? Have you debugged your code to see if the input is changing state?
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,387
    1,605
    It is almost missile to read your code as formatted. Perhaps using code tags would help (they keep your formatting intact unlike other test areas).

    I did notice you enable the global interrupts inside the interrupt routine. DO NOT DO THAT. Ever. When you return from the interrupt C is smart enough to do that for you.

    If you do it yourself you can retrigger interrupts while inside the routine. That can blow the return stack and make bad things happen.
     
  4. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    MikroC IDE simulator does not support simulation of peripherals or interrupts
     
  5. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    Thanks for your reply and advice
     
  6. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    The problem is not with GIE ...
     
  7. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    I didn't say anything about interrupts or a simumulator. Read my post again. You don't have a button wired to a simulator do you?
     
  8. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    Where is your interrupt handler?
     
  9. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0

    At the top void Interrupt()
     
  10. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    You don't need to tell MikroC that is your interrupt function? Just call it interrupt?

    This is really bad in an interrupt routine
    while (PORTB.F0==0 && INTCON.TMR0IF == 1)

    PORTB.F0 might always be 0 and TMR0IF might always be 1.

    In fact TMR0IF will always be 1 at that point of your interrupt.

    You don't need to use interrupts for a button push anyway. Polling with software debouncing will do. Unless you have some sort of hardware debouncing most humans will cause your interrupt routine to trigger several times with one press.


    What where the results of your debugging? Have you monitored the SFR in a test loop?
     
  11. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    No, I think it's OK, because TMR0IF does get cleared. But I don't see the need for a WHILE there instead of IF.

    And look, formatting and code tags!

    Code (Text):
    1.  
    2.   while (PORTB.F0==0 && INTCON.TMR0IF == 1)
    3.   {
    4.     counter++ ;
    5.     INTCON.TMR0IF=0;
    6. ...
    7.  
     
  12. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    Thank you Spinnaker and thank you John , I fixed my code it works with MPLAB but not works MikroC.
    The code is attached
     
  13. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    Sorry but I know nothing about Mikro C. If it works with whatever microchip compiler you are using then why not just use it? And MPLab is a development environment and not a compiler.
     
  14. JohnInTX

    Moderator

    Jun 26, 2012
    2,345
    1,028
    What @spinnaker said - just use X.
    If you must use MikroC, realize that its syntax is different than XC8 in several areas.
    Delete the #include <xc.h>, that's XC8-specific. MikroC includes the libraries you select when you create the project.
    Bit-addressable SFRs (PORTS, INTCON etc), have different syntax. From the chapter 4 of the MikroC manual:
    You'll have to visit all of the lines causing syntax errors and fix them up to what MikroC wants.

    As always, the answers are in the MikroC manual.

    Good luck.
     
  15. ali1980

    Thread Starter New Member

    Nov 12, 2011
    7
    0
    Yup JohnInTX , I know what you mentioned about ,but what I mean was , the same code compilation was successfully rununder mikroC (of course as you said according to mikroC syntax ) , but after I tested the HEX file on Proteus it did not give me results.
    Any way I will use MPLAB I think its better . By the way thank you for everybody.
     
  16. JohnInTX

    Moderator

    Jun 26, 2012
    2,345
    1,028
    A big difference between MikroC and XC8 that I recently found is that MikroC, by default, does not initialize static and global variables to 0. It looks like @ali1980 has that covered but something to know. Even though they are both 'C' compilers, there are lots of differences in the details.

    MikroC has a warm fuzzy feel to it but I prefer XC8 myself.
     
    Last edited: Nov 19, 2015
  17. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,884
    1,005
    Always best practice to initialize your variables no mater the compiler.
     
Loading...