Timer interrupt

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Timer interrupt

3,083 Views
pierrel
Contributor III

Hello,

 

I'm using a MC9S12XF521 microcontroller.

I want to create a function (timer_1_ms) which configure a timer and enable to counte the timer. After the timer has finished to count-down, an interrupt while set a semaphore in order to go out to the timer_1_ms() function. My problem is about using an IRQ. I don't know my code doesn't work.

 

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

/* Timer 1 ms                                                                                                */

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

void timer_1_ms(void)

{

    /* with Clock_Settings(), the bus' speed is 40MHz */

    blink_led(LED5_MASK);   /* LED5 for indicate that we are in the function */

 

    PITCE_PITCE0 = 0;       /* Le timer0 is disable, so doesn't count  */

   

    timer_1_ms_flag = 0;    /* semaphore used to speak between timer_1_ms() function and the IRQ */

   

    PITCSTP &= ~BIT0_MASK;  /* The timer0 wont wait a bit set of PITFLT register to count again after an overflow */

    PITMTLD0 = 200;                   /* Load of the timer0 8bits at 200 => increment of the 16bits timer0 each 5us */

    PITLD0 = 200;                         /* Load of the timer0 16bits at 200 => flag each 1ms */  

    PITTF_PITTF0 = 1;               /* interrupt flag is clear (just in case) */

    PITINTE_PITINTE0 = 1;        /* Interrup of the  timer0 is enable */

    PITCE_PITCE0 = 1;            /* The timer 0 is enable to count */   

    PITCFLMT_PITE = 1;           /* The PIT module si enable */

    

    while (timer_1_ms_flag != 1){

        LED1 = 0;       /* LED1 ON to show that we are in the loop */

    }

    blink_led(LED2_MASK);           /* LED2 ON to show that we are out of the loop */

}          

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

/* Timer Interrupt Service Routine                                                                */

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

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void interrupt Timer_Isr(void)

{  

    blink_led(LED4_MASK);    /* LED4 ON to show that we are in the timer interrupt routine*/

    if(PITTF_PITTF0 == 1){

      PITCE_PITCE0 = 0;     /* Disable the timer0 */

      PITTF_PITTF0 = 1;     /* Clear the flag */

      blink_led(LED3_MASK);  /* LED3 ON to show that we are in the subroutine*/

      timer_1_ms_flag = 1;  /* semaphore at 1 */

    }

}

#pragma CODE_SEG TIMER_ISR_CODE

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

 

Thank you,

Pierre

Labels (1)
0 Kudos
Reply
6 Replies

2,643 Views
pierrel
Contributor III

Thank you RadekS !

Your last comment will be very usefull for a beginner as me.

The community is quite good !

Have a great day,

Pierre

0 Kudos
Reply

2,643 Views
RadekS
NXP Employee
NXP Employee

Hi Pierre,

I am glad that it works now.

About interrupt vector numbers)

You may look at mc9s12xf512.h file and you will find this definition:

#define VectorNumber_Vpit0              66U

So, you could directly define interrupt routine as:

interrupt VectorNumber_Vpit0 void Timer_Isr(void)

or as

interrupt 66 void Timer_Isr(void)

In such case, you don’t need vector table.

The next option is definition this vector number in prm linker file.

The interrupt number 0 presents POR reset vector, 1 is CM reset, 2 is COP reset, ... , 119 is Spurious Interrupt (63 in the case of S12 core).

Interrupt number = (0xFE-Vector Address)/2. See Table Interrupt Vector Locations at RM.

For Example: Interrupt number of SCI0 = (0xFE-D6)/2 = 0x14 = 20.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

EDIT: fixed Spurious Interrupt vector number.

2,643 Views
pierrel
Contributor III

Hi RadekS,

Thank you for your answere.

Before your comment, I did not know the PIT interrupt. I worked in this way and I found a solution to my problem.

See after (in case it could help someone) my new code :

In Interrupts.c :

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

/* Timer Interrupt Service Routine */

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void interrupt Timer_Isr(void)

{  

    if(PITTF_PITTF0 == 1){

      PITCE_PITCE0 = 0;     /* Disable the timer0 */

      PITTF_PITTF0 = 1;       /* Clear the flag */

     

      timer_1_ms_flag = 1;   /* semaphore at 1 */

    }

}

#pragma CODE_SEG TIMER_ISR_CODE  

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

In Vector.c :

/* Interrupt vectors table */

typedef void (*near tIsrFunc)(void);

const tIsrFunc _InterruptVectorTable[] @0xFF10 = {

  /* ISR name             No.               Address      Pri      XGATE       Name 

Timer_Isr,                  /* 0x3D         0xFF7A         1            no         ivVpit0

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

It was really hard to me to find the good vector in the vectors table. There is any document which talk about the interrupt and their vector ?

Thank you,

Pierre

0 Kudos
Reply

2,643 Views
RadekS
NXP Employee
NXP Employee

Hi Pierre,

The most important question is what do you want to do?

Do you want to have periodic interrupt every 1ms? Or do you want to generate 1ms interval?

In the first case, PIT or RTI is correct choice (PIT is more precise, but RTI could run in pseudo STOP mode). They are designed for generating periodic interrupts.

In the second case, the ECT timer will better choice. You don’t need to take care about divider, disable and enable module again….

The example codes are here:

https://community.freescale.com/docs/DOC-95116

For example: XEP100 - ECT 500us interval - CW47, XEP100 - ECT 500us period - CW47, XS128 - PIT - CW47, ...

And here:

https://community.freescale.com/docs/DOC-329209

Note: Be careful with commands like "PITTF_PITTF0 = 1; /* Clear the flag */". This is read/modify/write command and it will clear all pending flags in PITTF register. Please use rather commands like PITTF=0x01; or PITTF=PITTF_PITTF0_MASK; for clearing specific flag. This is important in all cases where the register contains at least two flags which are cleared by writing log.1 = general rule.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

2,643 Views
pierrel
Contributor III

I found a little trick to solve this problem ( I call an other function in the RTI_isr) but I'm afraid with using this for the future.

If you have a suitable idea, please do not hesitate!

Thank you (again),

Pierre

0 Kudos
Reply

2,643 Views
pierrel
Contributor III

After some investigation, I found the problem's source but not its solution...

The function timer_1_ms() works but when the timer finish to count-down, this is the rti_isr which is called by the interruption.

I use an project example to go faster in my development.

The new question is : How to call the good interrupt routine after an overflow of a timer ?

Thank you

0 Kudos
Reply