[MC9S12C64] Interrupt Priority for Input Capture

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

[MC9S12C64] Interrupt Priority for Input Capture

跳至解决方案
801 次查看
Pogo
Contributor III

Hi All,

 

I've two IOC pin IOC0 and IOC3 and use them to capture input signal's pulse width. The frequency of IOC0's signal is greater than IOC3's. But sometimes the IOC3 pin will lost to capture some signals. If I want to guarantee that the signal to IOC3 pin will not lost to capture signal. How can I do?

Changing the priority of interrupt for IOC3 as highest. (HPRIO = 0xE8) ? Or you have another solution, please tell me. Thanks a lot.

 

Reagrds,

Pogo

标签 (1)
0 项奖励
1 解答
477 次查看
kef
Specialist I

So I was right suspecting that you are clearing timer flags incorrectly.

 

    TFLG1 |= 0x01; //Clear flag
 ^^ here you are clearing all TFLG1 flags, including channel 0 and 3 flags

 

    TFLG1 |= 0x08; //Clear flag
Same  ^^ here. You are clearing all TFLG1 flags, including channel 0 and 3 flags

 

Search forum for flag clearing like stuf and you will find it desribed many times. Reading TFLG1, ORing read bit pattern with  mask of flag  you are interested in, then writing resulting bitpattern back to TFLG1, you are writing "1" not just to flag you are interested in, but you write more "1"-es and clearing not just flag you are interested in. Correct code to clear channel 3 flag is either

 

   TFLG1 = (1<<3);

 

or

 

  TFLG1 &= (1<<3); // please note that there's no ~ operator in front of bitpattern on the right

 

在原帖中查看解决方案

0 项奖励
6 回复数
477 次查看
kef
Specialist I

How does clear flag code looks like? C? Asm?

Input capture misses events only when input pulse is too narrow (<2 bus clocks as stated in datasheets).

Another problem maybe that new capture event overwrites old TCx, so you need to service IC on time (ECT timer has some extra capture features like buffered capture etc).

HPRIO won't help a lot. It is effective only when two or more interrupts ar pending at the same time. It matters when you expect two or more interrupts happening at exactly the same time, and you wish to service one of them first.

0 项奖励
477 次查看
Pogo
Contributor III
interrupt void ISR_Timer0(void){    ...  //local variable define    TFLG1 |= 0x01; //Clear flag    ...  // do some calculation}interrupt void ISR_Timer3(void){    ...  //local variable define    TFLG1 |= 0x08; //Clear flag    ...  //do some calculation}

 Now, the ISR_Timer3 will lost some signal interrupt.  If I clear flag after doing some calculation, can I solve this problem?

Thanks for your reply!!

 

Pogo

0 项奖励
478 次查看
kef
Specialist I

So I was right suspecting that you are clearing timer flags incorrectly.

 

    TFLG1 |= 0x01; //Clear flag
 ^^ here you are clearing all TFLG1 flags, including channel 0 and 3 flags

 

    TFLG1 |= 0x08; //Clear flag
Same  ^^ here. You are clearing all TFLG1 flags, including channel 0 and 3 flags

 

Search forum for flag clearing like stuf and you will find it desribed many times. Reading TFLG1, ORing read bit pattern with  mask of flag  you are interested in, then writing resulting bitpattern back to TFLG1, you are writing "1" not just to flag you are interested in, but you write more "1"-es and clearing not just flag you are interested in. Correct code to clear channel 3 flag is either

 

   TFLG1 = (1<<3);

 

or

 

  TFLG1 &= (1<<3); // please note that there's no ~ operator in front of bitpattern on the right

 

0 项奖励
477 次查看
Lundin
Senior Contributor IV

Always, I repeat, always disassemble ISRs where you clear interrupt source flags. Incorrectly cleared interrupt flags is possibly the greatest cause of bugs in embedded systems, no matter what MCU flavour you are using. You have to read the disassembly and see what actually goes on, and whether this is compatible with the hardware registers or not.

 

For this particular case, Kef is likely assuming that you are using the Codewarrior, where the code TFLG |= 0x01 is indeed incorrect. CW will translate that to a read-modify-write access, and since TFLG is cleared by writing 1 to a flag, all flags will be cleared and not just the one you were interested in. But on another compiler, the same code could give the correct output, using a single bit set instruction instead.

0 项奖励
477 次查看
kef
Specialist I

Lundin, pelase stop spreading rumors about read modify write instructions. You are wrong! First of all I didn't say that TFLG1 |= 0x1 is correct. Second, IT DOESN'T MATTER WHAT COMPILER you will use, and if that compiler will use BSET or LDAA/ORAA/STAA like sequence, in all imagineable cases it won't work properly and will clear all flags that are set in this flags register! The same applies to bitfields provided by Freescale compilers. TFLG1_C0F = 1 will clear all TFLG1 flags. TFLG1_C0F = 0 will clear all TFLG1 flags except C0F.

INDEED READ MODIFY WRITE instructions are ABSULUTELY OK, provided you are using them properly. What's wrong with these codes to clear bit 3 in TFLG1? These work perfectly well:

 

    TFLG1 &= (1<<3); // please note that there's no ~ on the righ like would be used to clear bits in regular variables.

 

and

 

   BCLR  TFLG1, #~(1<<3)   or equivalent   BCLR TFLG1, #0xF7

0 项奖励
477 次查看
Pogo
Contributor III

Hi kef,

 

Thanks for your reply.

I've serach all "clear flag" keyword in this forum.

If I want to clear Timer0 and Timer3, I need to write the belowing code to clear them.

TFLG1  = 0x01; //Clear Timer 0 flag

 

TFLG1 = 0x08; //Clear Timer 3 flag.

 

 

Pogo

 

0 项奖励