Author Topic: Timer1 Interrupt Not Working?  (Read 2941 times)

0 Members and 1 Guest are viewing this topic.

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Timer1 Interrupt Not Working?
« on: June 16, 2017, 07:32:45 am »
Hi all,

Firstly this is only sandbox code so it's a bit spaghetti like,  the idea here is that when INT3 is high the timer is started which will be a long debounce (this is due to the fact this is going to be a) A very deliberate action with consequences if it 'fires in error' and B) It's going to have to be done by physically bridging INT3 high with a wire!

Now Ed thought I could start Timer1,  count the flags a few times then compare, however in the simulator:

INT3 interrupts MAIN and starts timer.
Timer1 is 'doing it's thing'
The interrupt flag never changes, just remains at zero.

As INT3 works correctly I am happy that the interrupt vector is working, I know the INT3 doesn't do anything at the moment but I was building in stages and that can come later once I've got this flag working.  I thought it would be quite trivial but I guess I'm missing something.  As far as I can see internal interrupts are set.

Code: [Select]
#define PULSE LATAbits.LATA0  //define pin RA0 as PULSE pin
#define DIR LATAbits.LATA1    //define pin RA1 as DIRECTION pin
#define SPEED PORTBbits.RB0 //Define SPEED H/L Pin
int BCOUNT;
   


void interrupt high_isr (void){  //High priority interrupt
   
      //set up TIMER1 Count
    if (PIR1bits.TMR1IF == 1){
       
        PIR1bits.TMR1IF = 0;
        BCOUNT++;
    }

    if(INTCON3bits.INT3IF  == 1){
         INTCON3bits.INT3IF = 0;
         PIE1bits.TMR1IE = 1; //Enable Timer1 Interrupt
       
            //Start Timer 1 for LONG bounce delay
         T1CONbits.RD16 = 0; //Operate in 2x8bit mode
         T1CONbits.T1RUN = 0; //Do not use T1CON clock
         T1CONbits.T1CKPS = 11; //Prescale 1:8
         T1CONbits.T1OSCEN = 0; //Shut down T1 Oscillator
         T1CONbits.TMR1CS = 0; //Use FOSC/4
         T1CONbits.TMR1ON = 1;  //Start timer
                 
       
         DIR= ~DIR;
       
         
       
    }

 
   

 

void delayfive (int loop) // Prototype for pulse timing,  wasteful routine.
{
    int i;
    for (i=0; i<loop; i++)
    {
        ; //do nothing,  this is correct, please do not adjust! - This is just a routine to waste instruction cycles.
}
   
}



int main () {
//Set device clock - 4MHz operation//
    OSCCONbits.IRCF2 = 1;  //Make the
    OSCCONbits.IRCF1 = 1;  //internal clock
    OSCCONbits.IRCF0 = 1; //8MHz


    TRISAbits.RA0 = 0; //define A0 as OUTPUT
    TRISAbits.RA1 = 0; //Define RA1 as OUTPUT
    TRISBbits.RB0 = 1; //define RB0 as INPUT
    CMCON = 0xFF; //switch OFF comparitors
    PWMEN1 = 0xFF; //switch OFF PWM module
    ADCON1 = 0xFF; //switch OFF Port-A ADC
     
     //Interrupt Settings//
    RCONbits.IPEN = 1; //enable interrupt priority

    INTCONbits.GIE = 1; //enable all interrupts
    INTCONbits.PEIE =1; //enable internal interrupts
    INTCON3bits.INT3IE =1; //enable INT3 external interrupt
    INTCON2bits.INTEDG3 =1; //INT3 RISING EDGE interrupt

   
     
     DIR = 0;
     
     if (SPEED == 1) {
     delayfive(100);
     PULSE= 1;
     delayfive(2);
     PULSE= 0;
    }
     else{
         delayfive(10);
         PULSE= 1;
         delayfive(2);
         PULSE= 0;
     }
}

The timing isn't critical (and indeed isn't really set up yet) but I expected at least to be able to see BCOUNT merrily count up once INT3 is fired?

What am I doing wrong here?

Cheers,
Ed

 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Timer1 Interrupt Not Working?
« Reply #1 on: June 16, 2017, 07:37:34 am »
Of course I should add  |O

PIC18F1330
Plain boring free XC8 compiler in MPLAB.
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4102
  • Country: us
Re: Timer1 Interrupt Not Working?
« Reply #2 on: June 16, 2017, 09:41:31 am »
I see you enabled interrupt priority.

It has been along while since I used an 18F. As I recall, when I used high/low priority interrupts, I found I had to set some bits opposite to my interpretation of the datasheet. I can't remember the specifics, but I attribute several grey hairs to this problem. It took a lot of mucking around, and at the time I was fairly convinced the datasheet was wrong. I'll check my datasheet and see if I can find my hand written notes.

* sorry no luck   
« Last Edit: June 16, 2017, 09:53:07 am by KL27x »
 

Offline leeatljs

  • Contributor
  • Posts: 31
  • Country: gb
Re: Timer1 Interrupt Not Working?
« Reply #3 on: June 16, 2017, 09:50:53 am »
also...
declare BCOUNT as volatile like...
volatile int BCOUNT;
since it can change inside the interrupt without the optimizer knowing about it.
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Timer1 Interrupt Not Working?
« Reply #4 on: June 16, 2017, 10:09:54 am »
Always check datasheet AND errata

http://www.microchip.com/wwwproducts/en/PIC18F1330
you find everything at the bottom of the page

you have this document: TIMER1 Module Data Sheet Errata: http://ww1.microchip.com/downloads/en/DeviceDoc/80329B.pdf

maybe there is what you're looking for?

anyway i have a couple of suggersions:
- don't use interrupt priority in pic18, it's more a pain in the butt than what it's worth
- since there is only one interrupt vector, it is called everytime that an xxIF and xxIE pair are both verified.
If you have peripherals that don't have the interrupt enabled at all time, you could service their interrupt also when not needed.. so you should do
Code: [Select]
if (xxIF & xxIE) {
  xxIF = 0;
  ...
}
 

Offline KL27x

  • Super Contributor
  • ***
  • Posts: 4102
  • Country: us
Re: Timer1 Interrupt Not Working?
« Reply #5 on: June 16, 2017, 10:37:46 am »
Quote
    if(INTCON3bits.INT3IF  == 1){
         INTCON3bits.INT3IF = 0;
         PIE1bits.TMR1IE = 1; //Enable Timer1 Interrupt
You might also try turning off INT3 interrupt, completely, rather than just clearing the flag. So you can take it out of the equation.
 
The following users thanked this post: ed_reardon

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Timer1 Interrupt Not Working?
« Reply #6 on: June 18, 2017, 09:53:24 pm »
Hey sorry it's Ed again.

Right this is starting to get frustrating!

Code: [Select]
   
#define PULSE LATAbits.LATA0  //define pin RA0 as PULSE pin
#define DIR LATAbits.LATA1    //define pin RA1 as DIRECTION pin
#define SPEED PORTBbits.RB0 //Define SPEED H/L Pin

   

volatile int  BCOUNT;
void interrupt high_isr (void){  //High priority interrupt
   
      //set up TIMER1 Count
   
    if (PIR1bits.TMR1IF == 1){

        PIR1bits.TMR1IF = 0;
        BCOUNT++;
    }

    if(INTCON3bits.INT3IF  == 1){
         INTCON3bits.INT3IF = 0;
         
       
            //Start Timer 1 for LONG bounce delay
            PIE1bits.TMR1IE = 1; //Enable Timer1 Interrupt
         T1CONbits.RD16 = 1; //Operate in 2x8bit mode
         T1CONbits.T1RUN = 0; //Do not use T1CON clock
         T1CONbits.T1CKPS = 11; //Prescale 1:8
         T1CONbits.T1OSCEN = 0; //Shut down T1 Oscillator
         T1CONbits.TMR1CS = 0; //Use FOSC/4
         T1CONbits.TMR1ON = 1;  //Start timer
                 
       
         DIR= ~DIR;
       
         
       
    }

 
   

 

void delayfive (int loop) // Prototype for pulse timing,  wasteful routine.
{
    int i;
    for (i=0; i<loop; i++)
    {
        ; //do nothing,  this is correct, please do not adjust! - This is just a routine to waste instruction cycles.
}
   
}



int main () {

    //Set device clock - 4MHz operation//
    OSCCONbits.IRCF2 = 1;  //Make the
    OSCCONbits.IRCF1 = 1;  //internal clock
    OSCCONbits.IRCF0 = 1; //8MHz


    TRISAbits.RA0 = 0; //define A0 as OUTPUT
    TRISAbits.RA1 = 0; //Define RA1 as OUTPUT
    TRISBbits.RB0 = 1; //define RB0 as INPUT
    CMCON = 0xFF; //switch OFF comparitors
    PWMEN1 = 0xFF; //switch OFF PWM module
    ADCON1 = 0xFF; //switch OFF Port-A ADC
     
     //Interrupt Settings//
 
    INTCONbits.GIE = 1; //enable all interrupts
    INTCONbits.PEIE =1; //enable internal interrupts
    INTCON3bits.INT3IE =1; //enable INT3 external interrupt
    INTCON2bits.INTEDG3 =1; //INT3 RISING EDGE interrupt
 
   
     
     DIR = 0;
   
     
     if (SPEED == 1) {
     delayfive(100);
     PULSE= 1;
     delayfive(2);
     PULSE= 0;
    }
     else{
         delayfive(10);
         PULSE= 1;
         delayfive(2);
         PULSE= 0;
     }
}

   
           
   
   
         




Now, the plot thickens.  The BCOUNT does increment during the ISR, however as soon as it returns to main it is reset to zero.

I've declared it volatile (and static) and it's made no difference,  if I step through with break-points the counter DOES increment but only for a handful of cycles.

Any suggestions?
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Timer1 Interrupt Not Working?
« Reply #7 on: June 19, 2017, 07:24:23 am »
"however as soon as it returns to main it is reset to zero"

put a data breakpoint, whenever a write to a specific value (0x00)  to this variable is made and let it run
 
The following users thanked this post: ed_reardon

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Timer1 Interrupt Not Working?
« Reply #8 on: June 19, 2017, 10:20:13 am »
You don't have a while(1) loop in main(), so after pulsing RA0 it exits main() and 'reboots' (which reinitializes all the variables). But after being started the timer keeps running, so after a few reboots it triggers the timer interrupt and BCOUNT is incremented. Then on the next reboot BCOUNT is initialized to zero again.
 

Offline ed_reardonTopic starter

  • Regular Contributor
  • *
  • Posts: 131
  • Country: gb
Re: Timer1 Interrupt Not Working?
« Reply #9 on: June 19, 2017, 03:13:31 pm »
You've no idea how much of a numpty I feel right now!

Thank you :)
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf