18F452 RB port interrupts slow/inconsistent?

Discussion in 'Embedded Systems and Microcontrollers' started by pizzaice, Feb 29, 2008.

  1. pizzaice

    Thread Starter New Member

    Jan 10, 2008
    8
    0
    Hi guys,
    I am currently trying to do a couple of improvements to my solenoid system (thread)and hence used two optical sensor to sense their position and therefore the time delay between the driver signal and the actual movement of the solenoid.

    On my PIC 18f452 I used two interrupt-configured B ports, RB5 and RB6 to sense a high or low status and then calculate the delay in crankshaft degrees. This then feeds back into my main interrupt routine that opens and closes these valves at the actual timing minus the delay.

    For some reason though the delay calculation does not work. When I output the values of the calculated delay onto my display I get values fluctuationg between 30 and 500. It should only really be thirty or max 100.

    Any ideas what could be wrong with my idea?It seems like the RB5 and RB6 ports are too slow for the use with interrupts that fast. But then, as read in other threads in this forum they should take the same time as the external interrupts INT0, INT1 and INT2 (which are all taken by the way;)..).

    The code looks like this (sorry... its long and a bit messy sometimes)
    Code ( (Unknown Language)):
    1. //**************************************************************************************************
    2. //HIGH PRIORITY INTERRUPT HANDLER
    3. //Description: Performs high priority interrupt actions
    4. //**************************************************************************************************
    5. #pragma code
    6. #pragma interrupt InterruptHandlerHigh
    7.  
    8. void InterruptHandlerHigh()
    9. {
    10.     // Handle high priority interrupts.
    11.     //Determine interrupt source
    12.  
    13.  
    14.     //**********************************************************************************************
    15.     //Intake/Exhaust response sensor
    16.     //**********************************************************************************************
    17.     if(INTCONbits.RBIF)
    18.     {
    19.        
    20.     // Intake
    21.    
    22.             if(PORTBbits.RB6 == 0) // Solenoid has moved in ie. valve opened
    23.             {
    24.                 if(IntOpenSensDelay==0)
    25.                 {
    26.                     IntOpenSensDelay==30;
    27.                 }
    28.                 else
    29.                 {
    30.                     IntOpenSensDelay=engineRotationDegs-INTOPENCAD-adjustAdvanceInt;    // example: 370-365=5
    31.                 }
    32.                
    33.             }
    34.             else if(PORTBbits.RB6 == 1)                 // Solenoid has moved out ie. valve closed
    35.             {
    36.                 if(IntCloseSensDelay==0)
    37.                 {
    38.                     IntCloseSensDelay=30;
    39.                 }
    40.                 else
    41.                 {
    42.                     IntCloseSensDelay=engineRotationDegs-INTCLOSECAD-adjustWidthInt;  // example: 550-540=10
    43.                 }
    44.             }
    45.    
    46.     // Exhaust
    47.    
    48.         //If optical switch has been triggered on
    49.             if(PORTBbits.RB5 == 0) //Solenoid has moved out of lightbeam
    50.             {
    51.                 if(ExhOpenSensDelay==0)
    52.                 {
    53.                     ExhOpenSensDelay=30;
    54.                 }
    55.                 else
    56.                 {
    57.                     ExhOpenSensDelay=engineRotationDegs-EXHOPENCAD-adjustAdvanceExh;
    58.                 }
    59.             }
    60.             else if(PORTBbits.RB5 == 1)
    61.             {
    62.                 if(ExhCloseSensDelay==0)
    63.                 {
    64.                     ExhCloseSensDelay=30;
    65.                 }
    66.                 else
    67.                 {
    68.                     ExhCloseSensDelay=engineRotationDegs-EXHCLOSECAD-adjustWidthExh;
    69.                 }
    70.             }
    71.         //Clear interrupt flag
    72.         INTCONbits.RBIF = 0;
    73.     }
    74.    
    75.     //**********************************************************************************************
    76.     //TDC Sensor
    77.     //**********************************************************************************************
    78.     if(INTCON3bits.INT1IF)
    79.     {
    80.         //To synchronise the EVVT system with the engine, the TDC sensor on the shaft encoder is
    81.         //required to be triggered in order to confirm the engine position
    82.         if(systemSyncToEng == 0)
    83.         {
    84.             engineStroke = 1;
    85.             //System is now synchronised
    86.             systemSyncToEng = 1;
    87.         }
    88.  
    89.         if(systemSyncToEng)
    90.         {
    91.             //Reset sync according to TDC sensor after every engine cycle
    92.             if(engineRotationDegs > 700)
    93.             {
    94.                 engineRotationDegs = -1;
    95.                 engineStroke = 1;
    96.             }
    97.         }
    98.    
    99.         //Clear interrupt flag
    100.         INTCON3bits.INT1IF = 0;
    101.     }
    102.    
    103.     //**********************************************************************************************
    104.     //Shaft encoder
    105.     //**********************************************************************************************
    106.     if(INTCONbits.INT0IF)
    107.     {
    108.         //The core interrupt, handling the critical intake and exhaust valve open/ close signals
    109.         if(systemSyncToEng)
    110.         {
    111.             //Encoder increments since last RPM calculation
    112.             encoderRPM++;
    113.  
    114.             //******************************************************************************
    115.             //The EVVT system counts the engine rotation over one engine cycle
    116.             //i.e. 0 to 719 degs
    117.             //******************************************************************************
    118.             engineRotationDegs++;
    119.  
    120.             //************************
    121.             //Intake Valve Open/ Close
    122.             //************************
    123.             //Output signal to trigger intake valve open
    124.             if(engineRotationDegs == (INTOPENCAD-IntOpenSensDelay-adjustAdvanceInt))
    125.             {
    126.                 PORTBbits.RB4 = 1;
    127.             }
    128.  
    129.             //Output signal to trigger intake valve close
    130.             if(engineRotationDegs == (INTCLOSECAD-IntCloseSensDelay-adjustWidthInt))
    131.             {
    132.                 PORTBbits.RB4 = 0;
    133.             }
    134.  
    135.             //*************************
    136.             //Exhaust Valve Open/ Close
    137.             //*************************
    138.             //Output signal to trigger exhaust valve open
    139.             if(engineRotationDegs == (EXHOPENCAD-ExhOpenSensDelay-adjustAdvanceExh))
    140.             {
    141.                 PORTBbits.RB3 = 1;
    142.             }
    143.  
    144.             //Output signal to trigger exhaust valve close
    145.             if(engineRotationDegs == (EXHCLOSECAD-ExhCloseSensDelay-adjustWidthExh))
    146.             {
    147.                 PORTBbits.RB3 = 0;
    148.             }
    149.  
    150.             //******************
    151.             //Display Eng Stroke
    152.             //******************
    153.             //Stroke 1
    154.             if(engineRotationDegs == 0)
    155.             {
    156.                 engineStroke = 1;
    157.             }
    158.             //Stroke 2
    159.             else if(engineRotationDegs == 180)
    160.             {
    161.                 engineStroke = 2;
    162.             }
    163.             //Stroke 3
    164.             else if(engineRotationDegs == 360)
    165.             {
    166.                 engineStroke = 3;
    167.             }
    168.             //Stroke 4
    169.             else if(engineRotationDegs == 540)
    170.             {
    171.                 engineStroke = 4;
    172.             }
    173.  
    174.             //**************
    175.             //Display Update
    176.             //**************
    177.             // if(page == 0x05)
    178.             //          {
    179.             //              //Update display of CAD (Crank Angle Degs)
    180.             //              DisplayLCD(LCD_COM, LCD_POS05);
    181.             //              if(engineRotationDegs > 359)
    182.             //              {
    183.             //                  BinToBCD16Bit(engineRotationDegs - 360);
    184.             //              }
    185.             //              else
    186.             //              {
    187.             //                  BinToBCD16Bit(engineRotationDegs);
    188.             //              }
    189.             //              DisplayLCD(LCD_TXT, hundreds);
    190.             //              DisplayLCD(LCD_TXT, tens);
    191.             //              DisplayLCD(LCD_TXT, ones);
    192.             //
    193.             //              //Update stroke
    194.             //              DisplayLCD(LCD_COM, LCD_POS48);
    195.             //              BinToBCD8Bit(engineStroke);
    196.             //              DisplayLCD(LCD_TXT, ones);
    197.             //          }
    198.         }
    199.  
    200.         //Clear interrupt flag
    201.         INTCONbits.INT0IF = 0;
    202.     }
    203.    
     
  2. nanovate

    Distinguished Member

    May 7, 2007
    665
    1
    Looking at your interrupt handler I see that you have writes to the LCD. This could be the problem. You want your interrupt service routine to be as fast as possible. Can you just have your interrupt set some flags then write to the LCD later?
     
  3. pizzaice

    Thread Starter New Member

    Jan 10, 2008
    8
    0
    thank you for the reply, nanovate

    if you have a look again in the code these LCD writes are commented out. do you have any other idea why the RB port interrupts could be slower than the other external ones?

    cheers,
    chris
     
  4. nanovate

    Distinguished Member

    May 7, 2007
    665
    1
    Could this be the problem?

    Code ( (Unknown Language)):
    1. if(IntOpenSensDelay==0)
    2. {
    3.    [B][COLOR="Blue"]IntOpenSensDelay==30;[/COLOR]
    4. [/B]}
    5. else
    6. {
    7.    IntOpenSensDelay=engineRotationDegs-INTOPENCAD-adjustAdvanceInt;   // example: 370-365=5
    8. }
    You have a "==" instead of a "=".
     
  5. pizzaice

    Thread Starter New Member

    Jan 10, 2008
    8
    0
    Thanks, that could be the problem. I corrected it just now but the interrupts still have really slow response. So you guys think it has to do with my programming rather than a general rule that RB interrupts are slower than external ones?

    Cheers,
    Chris
     
  6. nanovate

    Distinguished Member

    May 7, 2007
    665
    1
    The Pin Change Interrupts on RBn should have a response time very close the other external interrupts. How have you configured the priority bits on your all your interrupts?
     
Loading...