TMR3 Random Count Error (PIC18F, XC8, MPLAB X)

Author
physapp
New Member
  • Total Posts : 10
  • Reward points : 0
  • Joined: 2017/08/28 05:59:31
  • Location: 0
  • Status: offline
2017/11/14 11:44:24 (permalink)
0

TMR3 Random Count Error (PIC18F, XC8, MPLAB X)

Hi guys,
 
I have been working on a project where a Timer (TMR3) is used to measure the time between two external interrupts. Another timer (TMR1) is used to count if any overflows have occurred. The first interrupt starts the timer, the second turns it off and calls a function for some subsequent calculations. Then it is displayed on an LCD.
 
PIC18F26K40 @64MHz Internal Oscillator, TMR3 and TMR1 have no pre- or post-scale. TMR3 is sync'd to FCYC and TMR1 is triggered on the TMR3OUT bit.
 
Currently I am displaying both timer values and the calculated value on the LCD.  I also have the external interrupts set up to an oscilloscope to accurately measure the time between them. In Excel I have taken the time from the scope and multiplied by FCYC (16MIPS).
 
The problem I have at the moment is random count errors in the main timer, TMR3. I am getting an average of 1,783 more (extra) "ticks" in the TMR registers but its all over the place (see attached JPEG). This is causing significant error in the calculation. If it were consistent, I could subtract this average in the calculation.
 
Here are the relevant segments of code:
 
void OSCILLATOR_Initialize(void)
{
    // NOSC HFINTOSC; NDIV 1;
    OSCCON1 = 0x60;
    // CSWHOLD may proceed; SOSCPWR Low power;
    OSCCON3 = 0x00;
    // MFOEN disabled; LFOEN disabled; ADOEN disabled; SOSCEN disabled; EXTOEN disabled; HFOEN disabled;
    OSCEN = 0x00;
    // HFFRQ 64_MHz;
    OSCFRQ = 0x08;
    // TUN 0;
    OSCTUNE = 0x00;
}
 
void TMR3_Initialize(void)
{
    T3CON = 0x00;   //CKPS 1:1; nT3SYNC synchronize; TMR3ON off; T3RD16 enabled;
    T3GCON = 0x00;  //T3GE disabled; T3GTM disabled; T3GPOL low; T3GGO done; T3GSPM disabled;
    T3GATE = 0x00; //GSS T3G_pin;
    T3CLK = 0x01; //CS FOSC/4;
    TMR3H = 0x00;  //TMR3H 0;
    TMR3L = 0x00;  //TMR3L 0;
    timer3ReloadVal=(uint16_t)((TMR3H << 8) | TMR3L);  // Load the TMR value to reload variable
    PIR4bits.TMR3IF = 0;  // Clearing IF flag before enabling the interrupt.
    PIE4bits.TMR3IE = 1;  // Enable TMR3 interrupt.
}
   
    void TMR1_Initialize(void)
{
    T1CON =  0x09;  //CKPS 1:1; nT1SYNC synchronize; TMR1ON off; T1RD16 enabled;
    T1GCON = 0x40; //0xE0;  //T1GE enabled; T1GTM enabled; T1GPOL high; T1GGO done; T1GSPM disabled;
    T1GATE =  0x04; // tmr3 overflow  //GSS TMR0_Overflow;
    T1CLK = 0xA; //tmr 3 overflow  //CS TMR0_Overflow;
    TMR1H = 0x00;   
    TMR1L = 0x00;
    timer1ReloadVal=(uint16_t)((TMR1H << 8) | TMR1L);  // Load the TMR value to reload variable
    PIR4bits.TMR1IF = 0;  // Clearing IF flag before enabling the interrupt.
    PIE4bits.TMR1IE = 1; // Enable TMR1 interrupt.
    TMR1_StartTimer();  // Start TMR1
}
 

void interrupt high_priority ISR_high(void)
{
    if (PIR0bits.INT0IF && PIE0bits.INT0IE == 1)            //Check if the first beam has been broken
    {
        PIR0bits.INT0IF = 0;    //Toggle the Flag
        TMR1H = 0x00;   //RESET all TIMER registers
        TMR1L = 0x00;
        TMR3H = 0x00;
        TMR3L = 0x00;
        
       
        T3CONbits.TMR3ON = 1;   //Turn on the Timer
       //T1CONbits.TMR1ON = 1;   //Turn on the Overflow Counter
        
              LATAbits.LATA5 = 0;  //TURN ON BNC
         
    }
    
     if (PIR0bits.INT1IF && PIE0bits.INT1IE == 1)         
                                   
  {
      PIR0bits.INT1IF = 0;  //Toggle the Flag
      T3CONbits.TMR3ON = 0;  //Turn off the Timer
      //T1CONbits.TMR1ON = 0;  //Turn off Overflow counter
      LATAbits.LATA5 = 1;  //TURN OFF BNC
      Velocity();
  }                        
}
   
   
void interrupt low_priority ISR_low(void)
{  
     if (PIR4bits.TMR3IF == 1)   //TMR3 Interrupt Service Routine
     {        
            PIR4bits.TMR3IF = 0;        
      TMR3H = 0x00;
    TMR3L = 0x00;
    
     }                                
 if (PIR4bits.TMR1IF == 1)   //TMR1 Interrupt Service Routine
     {        
            PIR4bits.TMR1IF = 0;        
      TMR1H = 0x00;
    TMR1L = 0x00;
    
     }   
}
   
   
 
 
 

Attached Image(s)

#1

4 Replies Related Threads

    jtemples
    Super Member
    • Total Posts : 10278
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: TMR3 Random Count Error (PIC18F, XC8, MPLAB X) 2017/11/14 12:40:08 (permalink)
    0
    What is the purpose of these statements?
     
    timer3ReloadVal=(uint16_t)((TMR3H << 8) | TMR3L);
    timer1ReloadVal=(uint16_t)((TMR1H << 8) | TMR1L);
     
    The code you've shown will just load them with 0.  Is that expected?
     
    Do you have the timers in 16-bit mode?
    #2
    physapp
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2017/08/28 05:59:31
    • Location: 0
    • Status: offline
    Re: TMR3 Random Count Error (PIC18F, XC8, MPLAB X) 2017/11/14 12:48:32 (permalink)
    0
    Timers are in 16 bit mode. Those lines are so that I could load them with different initial values for different timer periods
     
    #3
    jack@kksound
    code tags!
    • Total Posts : 2080
    • Reward points : 0
    • Joined: 2014/05/14 10:03:19
    • Location: 0
    • Status: online
    Re: TMR3 Random Count Error (PIC18F, XC8, MPLAB X) 2017/11/14 13:07:30 (permalink)
    0
    Might be simpler using the capture/compare modules? I have done that in the past for pulse measurements. Just a thought...
    #4
    1and0
    Access is Denied
    • Total Posts : 7097
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: TMR3 Random Count Error (PIC18F, XC8, MPLAB X) 2017/11/14 13:39:27 (permalink)
    +1 (1)
    Agree with Jack on using Capture/Compare module.

     I might have missed something, but I don't think you need the interrupts for Timer3 and Timer1.  Clearing TMR3x in the ISR will introduce error.

    Edit: show your velocity() function. Are you reading the timers values in the correct order.
    post edited by 1and0 - 2017/11/14 14:25:32
    #5
    Jump to:
    © 2017 APG vNext Commercial Version 4.5