[Help] MC9S12XS PIT Problem

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

[Help] MC9S12XS PIT Problem

ソリューションへジャンプ
1,843件の閲覧回数
Pogo
Contributor III

Hi all,

I try use PIT to do something on MC9S12XS, but it only can work for PIT0.

The following list is my code.

 

void vfnScheduler_Init(void)

{  

    PITCFLMT_PITFRZ = 1;        /* PIT counter freeze while in Freeze mode */    

   

    PITMTLD0        = PIT_MICROTIMER_DIV0;/* PIT microtimer register = 40, PIT microtimer period = 40MHz/40   = 1Mhz */

    PITMTLD1        = PIT_MICROTIMER_DIV1;/* PIT microtimer register = 200, PIT microtimer period = 40MHz/200 = 200Khz */

 

 

    //Timer for laptimer, drag racing  1ms 

    PITMUX_PMUX0    = 0;        /* 16-bit timer 0 counts with micro time base 0 */

    PITCE_PCE0      = 1;        /* Enables PIT channel 0 */

    PITINTE_PINTE0  = 1;        /* Interrupt of PIT channel 0 is enabled */       

    PITTF_PTF0      = 1;        /* Clear PTI interrupt flag */

    PITLD0          = 999;      /* PIT register = 999, 1MHz/1000 = 1KHz = 1ms period */


    //send data to host 4Hz

    PITMUX_PMUX1    = 1;        /* 16-bit timer 1 counts with micro time base 1 */

    PITCE_PCE1      = 1;

    PITINTE_PINTE1  = 1;        /* Interrupt of PIT channel 1 is enabled */

    PITTF_PTF1      = 1;        /* Clear PTI interrupt flag */

    PITLD1          = 49999;     /* PIT register = 49999, 200KHz/50000 = 4Hz = 250ms period*/

   

    PITMUX_PMUX2    = 0;        /* 16-bit timer 2 counts with micro time base 0 */

    PITCE_PCE2      = 1;        /* Enables PIT channel 2 */

    PITINTE_PINTE2  = 1;        /* Interrupt of PIT channel 2 is enabled */       

    PITTF_PTF2      = 1;        /* Clear PTI interrupt flag */

    PITLD2          = 4999;      /* PIT register = 4999, 1MHz/5000 = 200Hz = 5ms period */

}

void interrupt ISR_PIT0_Timer(void)

{

    /* Verify that Real Time Interrupt caused the interrupt */

         if (PITTF_PTF0)

         {

...    

         }

    /* Clear the real time interrupt flag */

    PITTF_PTF0 = 1;

}

 

void interrupt ISR_PIT1_Timer(void)

{

    if( PITTF_PTF1 )

    {       

    ...

    }

    PITTF_PTF1 = 1;

}

void interrupt ISR_PIT2_Timer(void)

{

    if( PITTF_PTF2)

    {

...

    }

    PITTF_PTF2 = 1;//clear interrupt flag

}

 

 

PIT0 can work well, but PIT1 and PIT2 can't work. Please give me any suggestion. Thanks a lot.

ラベル(1)
1 解決策
1,452件の閲覧回数
kef2
Senior Contributor V
  • PITTF_PTF0 = 1; /* Clear PTI interrupt flag */

Comment is wrong. This ^^ line clears all four PITTF flags.  PITTF_PTF0 is a member of PITTF bitfield struct. There's no way to use bitfields to clear just one PITTF flag.  You need to either use this

  PITTF = (1<<0);

or this

  PITTF &= (1<<0);

If you choose 2nd, then please note the absence of '~' sign on the right, like it would be used to clear bits in variables like a &= ~1;

元の投稿で解決策を見る

8 返答(返信)
1,453件の閲覧回数
kef2
Senior Contributor V
  • PITTF_PTF0 = 1; /* Clear PTI interrupt flag */

Comment is wrong. This ^^ line clears all four PITTF flags.  PITTF_PTF0 is a member of PITTF bitfield struct. There's no way to use bitfields to clear just one PITTF flag.  You need to either use this

  PITTF = (1<<0);

or this

  PITTF &= (1<<0);

If you choose 2nd, then please note the absence of '~' sign on the right, like it would be used to clear bits in variables like a &= ~1;

1,452件の閲覧回数
赵子成
Contributor IV

Very good. Your comment also solve my issue.

Thanks a lot.

0 件の賞賛
返信
1,452件の閲覧回数
Pogo
Contributor III

Hi sir,

I use PORTA_PA0 =1 , it can work. It will only output PA0 as high. Why using bitfield struct can't clear flag of one channel or of one port ??

Thanks a lot!!!!

0 件の賞賛
返信
1,452件の閲覧回数
kef2
Senior Contributor V

PORTA is like regular byte of memory. You write 1 to set bit, and 0 to clear bit. Flags register like PITTF or TFLG1 have more than one bit, which is cleared when you write 1 to it. Writing 0 doesn't change bit. How do behave bitfield structs? You change one field in interest, and the other fields are preserved (rewritten). What happens when you rewrite fields (flags), which already are set (1)? They in fact are cleared, not preserved.

You didn't explain what doesn't work in your code, but it can't work without glitches until you fix buggy flag clearing sequences.

1,452件の閲覧回数
Pogo
Contributor III

Hi sir,

Thanks a lot for your reply.

First time, I changed PITTF_PTF0 = 1 to PITTF = 0x01, it doens't work. (The other timer don't receive any interrupt)

When I changed PITTF_PTF0 = 1 to PITTF = (1<<0), it works fine. I don't understand what difference in PITTF = 0x01 and PITTF = (1<<0).

Anyway, thanks a lot.

Pogo Lin

0 件の賞賛
返信
1,452件の閲覧回数
kef2
Senior Contributor V

PITTF = (1<<0); // clear PTF0

PITTF = (1<<1); // clear PTF1

PITTF = (1<<2); // clear PTF2

PITTF = (1<<3); // clear PTF3

Compiler calculates (1<<3) at compile time and produces the same code in both cases PITTF=8 or PITTF=(1<<3). So why to bother calculating those constants in your brains? At the other hand It is also more readable (at least for me).

1,452件の閲覧回数
Pogo
Contributor III

Hi Edward,

Could you explain to me why PITT_PTF0 = 1 will clear all four PTTF flags?


I changed PITTF_PTF0 to  PITTF = (1<<0), PITTF_PTF1 to PITTF = (1<<1) and PITTF = (1<<2), but it still has same problem.

I can't receive any the 2nd or 3rd timer's interrupt.

0 件の賞賛
返信
1,452件の閲覧回数
RadekS
NXP Employee
NXP Employee

Note: More details about clearing flags you can get from AN2554 Clearing and Disabling Interrupt Flags

http://www.freescale.com/files/microcontrollers/doc/app_note/AN2554.pdf