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
Solved! Go to Solution.
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
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.
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
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
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.
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
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