HCS12x Enhanced capture timer

cancel
Showing results for 
Search instead for 
Did you mean: 

HCS12x Enhanced capture timer

Jump to solution
566 Views
hucklim
Contributor III

Hello,

I have a question regarding the Enhanced capture timer. I am using the ECT as interrupt timer. I set the TC1 to fire the interrupt at a specific compare output. The sequence of the instruction is as below:

 

ECT_TCNT = 0;

asm BSET ECT_TSCR1, #0x80 //timer started

ECT_TC1 = ECT_TCNT + 6400;

asm BSET ECT_TIE, #0x02 //interrupt enable

 

Presumably the interrupt will fire when the timer counted from 0 to 6400. What I noticed is that the first interrupt was triggered right away, which is not what I expected. Thereafter the interrupt triggered at regular interval, which is what I expected.

 

If I change the ECT_TCNT's initial value, for example,

ECT_TCNT = 10000;  //---------changed this initial value

asm BSET ECT_TSCR1, #0x80 //timer started

ECT_TC1 = ECT_TCNT + 6400;

asm BSET ECT_TIE, #0x02 //interrupt enable

 

Then everything works fine. The first interrupt was not triggered right away.

 

Can anybody explain to me why the initial value of ECT_TCNT makes the difference? I think I read about this in the manual somewhere, but I cannot find it anymore.

 

Yours sincerely,

Huck

Labels (1)
Tags (3)
0 Kudos
1 Solution
312 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

or another approach, just do not start timer before you add a first value into the OC register.

For example, see bellow. However, as Edward says and I can confirm it is good approach if you clear interrupt flags before interrupt is enabled to avoid servicing accidental flag.

******************************************************************************

Description: SW-XET256-ECT-OC-CW47

Documentation: MC9S12XEP100RMV1.pdf                                                   

This software is classified as Engineering Sample Software.               

******************************************************************************

- the board includes 16MHz crystal / the MCU's bus frequency 8MHz is used

  - the sample software does:

  . TC0 interrupt is set to be generated with constant period.

==============================================================================*/

//******************************************************************************

#include <hidef.h>     

#include <MC9S12XET256.h>

#pragma LINK_INFO DERIVATIVE "mc9s12xet256"

//******************************************************************************

//==============================================================================

// SETUP DEFINITIONS

//==============================================================================

#define  INTERVAL  50000

//==============================================================================

// COMMON DEFINITIONS

//==============================================================================

#define     UBYTE       unsigned char

#define     UWORD       unsigned  int

//==============================================================================

// FUNCTION PROTOTYPES

//==============================================================================

void ECT_Init(void);

//==============================================================================

// Variables section

//==============================================================================

// NA

//==============================================================================

// CODE section

//==============================================================================

void ECT_Init(void)

{

  ECT_TSCR2 = 0x07;                    //  TOV disable, no reset timer from T7, prescaller=128

  //--- channel 0 setup ---------------

  ECT_TCTL1 = 0x00;                    // timer 7~4 no output compare action

  ECT_TCTL2 = 0x01;                    // timer 3~1  no output compare action, T0 toggle on compare

  ECT_TIOS  = 0x01;                    // channel 0 is output compare

  ECT_OCPD  = 0xFE;                    // enable OC at timer 0 port

  //-----------------------------------

  ECT_TC0 = (UWORD) (INTERVAL + ECT_TCNT); // base setup of the first OC at T0

  //-----------------------------------

  ECT_TIE   = 0x01;                    // enable interrupt from channel 0

  //---------------------------------

  ECT_TSCR1 = 0xE0;                    // enable timer,stop in wait,stop in freeze, no fast flag clear, legacy timer

}

//******************************************************************************

#pragma CODE_SEG NON_BANKED

//-------------------------------------

interrupt  8 void TC0_Isr(void)

{                             

ECT_TC0        =  INTERVAL + ECT_TCNT;  // set new period end

ECT_TFLG1   = 0x01;                                      // clear interrupt flag

}

//-------------------------------------

#pragma CODE_SEG DEFAULT

//******************************************************************************

// void main(void)

//******************************************************************************

void main(void)

{

  //----------------------------------------

  ECT_Init();

  //----------------------------------------

  EnableInterrupts;

  //----------------------------------------

  for(;;)

    {

    }

}

//******************************************************************************

Best regards,

Ladislav

View solution in original post

0 Kudos
6 Replies
313 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

or another approach, just do not start timer before you add a first value into the OC register.

For example, see bellow. However, as Edward says and I can confirm it is good approach if you clear interrupt flags before interrupt is enabled to avoid servicing accidental flag.

******************************************************************************

Description: SW-XET256-ECT-OC-CW47

Documentation: MC9S12XEP100RMV1.pdf                                                   

This software is classified as Engineering Sample Software.               

******************************************************************************

- the board includes 16MHz crystal / the MCU's bus frequency 8MHz is used

  - the sample software does:

  . TC0 interrupt is set to be generated with constant period.

==============================================================================*/

//******************************************************************************

#include <hidef.h>     

#include <MC9S12XET256.h>

#pragma LINK_INFO DERIVATIVE "mc9s12xet256"

//******************************************************************************

//==============================================================================

// SETUP DEFINITIONS

//==============================================================================

#define  INTERVAL  50000

//==============================================================================

// COMMON DEFINITIONS

//==============================================================================

#define     UBYTE       unsigned char

#define     UWORD       unsigned  int

//==============================================================================

// FUNCTION PROTOTYPES

//==============================================================================

void ECT_Init(void);

//==============================================================================

// Variables section

//==============================================================================

// NA

//==============================================================================

// CODE section

//==============================================================================

void ECT_Init(void)

{

  ECT_TSCR2 = 0x07;                    //  TOV disable, no reset timer from T7, prescaller=128

  //--- channel 0 setup ---------------

  ECT_TCTL1 = 0x00;                    // timer 7~4 no output compare action

  ECT_TCTL2 = 0x01;                    // timer 3~1  no output compare action, T0 toggle on compare

  ECT_TIOS  = 0x01;                    // channel 0 is output compare

  ECT_OCPD  = 0xFE;                    // enable OC at timer 0 port

  //-----------------------------------

  ECT_TC0 = (UWORD) (INTERVAL + ECT_TCNT); // base setup of the first OC at T0

  //-----------------------------------

  ECT_TIE   = 0x01;                    // enable interrupt from channel 0

  //---------------------------------

  ECT_TSCR1 = 0xE0;                    // enable timer,stop in wait,stop in freeze, no fast flag clear, legacy timer

}

//******************************************************************************

#pragma CODE_SEG NON_BANKED

//-------------------------------------

interrupt  8 void TC0_Isr(void)

{                             

ECT_TC0        =  INTERVAL + ECT_TCNT;  // set new period end

ECT_TFLG1   = 0x01;                                      // clear interrupt flag

}

//-------------------------------------

#pragma CODE_SEG DEFAULT

//******************************************************************************

// void main(void)

//******************************************************************************

void main(void)

{

  //----------------------------------------

  ECT_Init();

  //----------------------------------------

  EnableInterrupts;

  //----------------------------------------

  for(;;)

    {

    }

}

//******************************************************************************

Best regards,

Ladislav

0 Kudos
312 Views
hucklim
Contributor III

Hello Ladislav,

thanks for the tips. I will switch my sequence to enable the timer after setting the OC register.

Yours sincerely,

Huck

0 Kudos
312 Views
kef2
Senior Contributor IV

TCNT is free running counter, which you can't alter in normal operating modes. In special operating modes write to TCNT resets TCNT to 0. (BDM debugger usually uses special single chip mode).

I think you need to clear TFLG1 flag before unmasking TIE interrupt:

TFLG1 = (1<<1); // clear n=1 channel interrupt flag, mask = 1<< n

TIE |= (1<<1); // unmask interrupt

Since it seems you are new to S12, please note that following would clear ALL TFLG1 flags, not just channel 1 flag:

TFLG1 |= (1<<1);

BSET  TFLG1, #1<<1

312 Views
hucklim
Contributor III

Hello Edward,

thanks for the useful information. I will make sure I do not make the mistake when using the ECT.

I do clear the interrupt flag immediately in the ISR.

Do you have any information as far as why the interrupt gets trigger right away when the TCNT was set to 0?

Yours sincerely,

Huck 

0 Kudos
312 Views
kef2
Senior Contributor IV

Interrupt is fired when both TIE and TFLG1 are set. So it must be set flag in TFLG1. Though documentation states TFLG1 is all 0 out of reset, I always clear TFLG1 before enabling TIE interrupts. No problems so far.

312 Views
hucklim
Contributor III

Hello Edward,

ok, thanks for the tips. I will check my code to see if I am missing something.

Yours sincerely,

Huck

0 Kudos