Timer Compare Interrupt on AW60 after Reset

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Timer Compare Interrupt on AW60 after Reset

4,723件の閲覧回数
PhilG
Contributor I
Hi,
I am setting up the Output Compare interrupt to generate a regular timer tick, say 1ms.
Changing the compare value (Timer value + Ticktime) in the interrupt service routine for the next tick.
I have found that after reset the first tick, takes a longer time as the timer is wrapping round the 16-bit count and only generating the first compare interrupt the next time round.
I have tried increasing the Output Compare value just in case the timer had already passed the compare value and I still experience the same problem as the timer wraps around first.
Has anyone experienced the same behaviour?
I look forward to hearing from your replies.
 
Regards
Phil Green
 
ラベル(1)
0 件の賞賛
返信
10 返答(返信)

2,530件の閲覧回数
thisobj
Contributor III
Hi Phil,

Rocco is correct in pointing out that new timer compare values should be determined by adding to the current value in the timer value register ( TPM1C1V ).  (Mr. Cut & Paste got me in my first reply).  I attempted to edit it, but the edit period expired.  The isr should be:

in the isr:

    TPM1C1SC_CH1F = 0;                          // ACK channel interrupt
    TPM1C1V  =  TPM1C1V + 0x20;           // load for next cycle

However, in the timer initialization code, you may add your value to the current timer value ( TPM1CNT ) as a quick method of establishing an initial TPM1C1V value.  This, of course, depends on your required accuracy.  

Frank
0 件の賞賛
返信

2,530件の閲覧回数
bigmac
Specialist III
Hello all,
 
Actually for an internal tick timer it is possible that there is interest only in the occurrence of the timer interrupt, and not the hardware (toggle) output at the timer pin.  The execution of the ISR code will always be delayed from the hardware event.  The amount of this delay may depend on the completion of execution of other ISRs.
 
The questions in my mind are whether all interrupt flags are cleared prior to globally enabling interrupts, and whether the processing of any other ISR can take in the region of 1ms, or more?
 
Regards,
Mac
 
0 件の賞賛
返信

2,530件の閲覧回数
Mayu
Contributor I

Hello:

 

I have problems with the timer in aw60, i need to use two different time interruption  ,I use ch2 and ch3 of the timer1 , when I use only one channel it works fine ,so I tried this with two channel.

 

//channel 2 init an enable interrupt 

void timer_ch2()   //1mseg
{
  TPM1SC=0x00;
  TPM1C2SC=0x50;             

  TPM1C2V=TPM1MOD=0x9C4;                        
  TPM1SC= 0x0B;               //Preescaler 8  
}


//channel 2 init an enable interrupt
void timer_ch3()       //2mseg

{
  TPM1SC=0x00;
  TPM1C3SC=0x50;           

  TPM1C3V=TPM1MOD=0x1388;                       
  TPM1SC= 0x0B;               //Preescaler 8  
}

 

 

void main(){

 timer_ch2();

timer ch3();

}

 

but with this ch2 change to 2mseg

 

channels can work independently?
how can I solve this?
I'd aprecciate any help 
Regards 

 

 

 

interrupt 7 void timer(void)

    clrReg8(TPM1C2SC,0x80);  
    PTAD_PTAD0 = ~PTAD_PTAD0;   //to verify

 }


interrupt 8 void timer3(void)

    clrReg8(TPM1C3SC,0x80);  
    PTAD_PTAD1 = ~PTAD_PTAD1;
}

0 件の賞賛
返信

2,530件の閲覧回数
kef
Specialist I

//channel 2 init an enable interrupt 

void timer_ch2()   //1mseg
{
  TPM1SC=0x00;
  TPM1C2SC=0x50;             

  TPM1C2V=TPM1MOD=0x9C4;                        
  TPM1SC= 0x0B;               //Preescaler 8  
}


//channel 2 init an enable interrupt
void timer_ch3()       //2mseg

{
  TPM1SC=0x00;
  TPM1C3SC=0x50;           

  TPM1C3V=TPM1MOD=0x1388;                       
  TPM1SC= 0x0B;               //Preescaler 8  
}

 

 

void main(){

 timer_ch2();

timer ch3();

}

 

but with this ch2 change to 2mseg

 

channels can work independently?
Channels can work independently provided required shared settings are the same. Prescaler and modulus should be the same.
0 件の賞賛
返信

2,530件の閲覧回数
Mayu
Contributor I

Thanks for you soon reply, but I'm a litle confused, if channels can work independently and shared settings are the same,(timer1_Init) and I need two interruption of 1mseg and 2mseg  I did this but it doesn't work ,how can i configure this ? can you post some code for do this ?

thanks for you help. 

 

 

void Timer1_Init()
{
  TPM1SC=0x00;
  TPM1SC= 0x0B;           //Preescaler 8
  TPM1MOD=0x9C4;

 

void timer1_ch2()         //1mseg
{
  TPM1C2SC=0x50;             
  TPM1C2V=0x9C4;                                     
}

void timer1_ch3()         //2mseg
{
  TPM1C3SC=0x50;             
  TPM1C3V=0x1388;                                    
}

0 件の賞賛
返信

2,529件の閲覧回数
bigmac
Specialist III

Hello Mayu,

 

Further to Kef's reply, leaving TPM1MOD register set to its default value, for free-running operation, will certainly simplify the coding.  The only requirement is that the TPM overflow period be greater than the longest interrupt period.  This would seem to be the case for a pre-scale division of 8.  The following code might then apply for each ISR.

 

interrupt 7 void timer(void)

   TPM1C2SC_CH2F = 0;      // Clear flag

   TPM1C2V += 2500;        // Next output compare value 1ms

   PTAD_PTAD0 = ~PTAD_PTAD0; //to verify

 }

interrupt 8 void timer3(void)

   TPM1C3SC_CH3F = 0;      // Clear flag

   TPM1C3V += 5000;        // Next output compare value 2ms

   PTAD_PTAD1 = ~PTAD_PTAD1;
}

 

You might also consider the initialisation of the TPM1C2V and TPM1C3V registers, so that the two interrupts never become concurrent, causing additional periodic latency.  Perhaps the following initialisation code - 

 

TPM1SC= 0x0B;             // Preescaler 8

TPM1C2SC=0x50;            // Interrupt only

TPM1C2V = TPM1CNT + 50;

TPM1C2SC=0x50;            // Interrupt only

TPM1C3V = TPM1CNT + 1300;

 

Regards,

Mac

 

0 件の賞賛
返信

2,530件の閲覧回数
kef
Specialist I

You can't use modulus setting to define channel frequency since modulus setting is shared among channels. Instead of changing modulus, on channel interrupt you can calculate and change TPMxCyV setting to match next pulse edge. 

 

For example you want next interrupt to occur 1000 timer ticks past current interrupt. To do so you write in channel interrupt handler:

 

unsigned short t; 

 

   // current output compare 

    t = TPM1C3V;  

 

   // calculate next timer tick

    t = (t + 1000) % MODULUS;   // where MODULUS is current TPM1MOD setting

   

   TPM1C3V = t; // next timer compare

}

 

Please note that it makes sense to leave default modulus setting (0x10000) since

 

  short t % 0x10000 is t  and slow division operation will be optimized out

 

 

Changing channel compare value and maybe ELSnA:ELSnB bits from set output pin on compare to clear and vice versa, it is possible to generate almost any pulse width and pulse frequency.

 

I don't have working example but idea should be clear.

0 件の賞賛
返信

2,530件の閲覧回数
PhilG
Contributor I
Hi all,
Thank you for your quick replies and suggestions.
I have taken your advice about the initialisation order for the timer.
Also, discovered that I was enabling interrupts too late( >1ms) further on in my code this obviously would delay the first compare interrupt causing the timer to wrap around before the next compare.
So all fixed now.
Good forum to get advice for freescale products.
Thanks once again.
Regards
Phil
 
0 件の賞賛
返信

2,530件の閲覧回数
rocco
Senior Contributor II
Hi Phil,

I have two observations which may or may not help, since I don't know how you have programmed the timer.

First, for the sake of the PWM mode, the output-compare can operate in a pipelined mode (I forget the official freescale term). In this mode, the value you write is held in a pipeline until the next timer overflow, and then it is loaded. That sounds somewhat like your symptoms.

Second, if you need an accurate time, I suggest not adding your time offset to the current timer value, but add it to the previous compare value. This way, interrupt latency won't effect your interrupt rate, and you avoid high-byte/low-byte interlock issues that can occur when reading the timer.
0 件の賞賛
返信

2,530件の閲覧回数
thisobj
Contributor III
Hello PhilG,

It's difficult to give specific help without viewing your timer initialization code and the timer isr.   I can only offer the following as an example init for TPM1C1 in Output Compare mode:

    TPM1C1SC = 0x54;                    // set channel 1 for OC toggle on trigger
    TPM1C1V = TPM1CNT + 0x20;  // this is approx .001 ms ( 2 ms period) using 4 MHz bus clock
    TPM1SC   = 0x0f;                        // select clock = bus clock div by 128. NO OVFLOW int.
    TPM1C1SC_CH1F = 0;               // clear pending interrupts
    EnableInterrupts;

The above will cause a toggle to a "1" state after .001 ms.
Further actions are determined in the isr.

In the isr:

    TPM1C1SC_CH1F = 0;               // ACK channel interrupt
    TPM1C1V = TPM1CNT + 0x20;  // load for next cycle

With a more sophisticated isr, you could do away with the auto toggle mode and manually control the compare time and state at the end of the compare time for the next cycle.

Hope this helps.

Frank

0 件の賞賛
返信