本帖最后由 永远的不知 于 2012-3-7 21:28 编辑
11# modernthink
基于我楼上所说,最好不要直接异步读定时器。以下引用N年前,TI的Vincent给我的答复,很专业。
There is a possible problem with the software code in this line:
mov.w &TAR,rComTemp; //记录进入中断时间
Please refer to the diagram below:
见图1
The Timer Clock is your 455KHz TAR input clock.
Our TAR counter is a ripple counter.
The MCU is run using DCO clock, this clock is asynchronous with the Timer Clock.
So when you try to capture the TAR value by reading the TAR register, it is similar to the CCI event above.
The actual read may happen between the value n-1 and n when the internal counter bits are changing.
As a result you may read a wrong number which is not n nor n-1. This number can be very wrong.
This can upset your timing offset calculation.
The best way to deal with this is to use the hardware provided by Timer_A.
Use the Timer_A capture mode with the SCS bit set to enable Synchronous Capture Mode.
Setting the SCS bit will synchronize the capture with the next timer clock as shown below.
见图2
Now the captured value is always safe.
Attached are example codes in C and assembly for UART TX/RX which demonstrate this feature.
Please note this line which enables the synchronous mode:
SetupRX mov.w #CM1+CCIS0+SCS+OUTMOD0+CAP+CCIE,&CCTL0; Neg Edge,Sync,cap
Additional information can be found in our Users Guide 11.2.4 Capture/Compare Blocks
I notice that you are using I/O port for your interrupt.
In which case your are not using th built in hardware of Timer_A and you need to use a software check.
In C it looks like this:
unsigned int a,b,c;
do
{
a=TAR;
b=TAR;
c=b-a;
}
while(abs(c)>10);
This function tries to catch an erroneous read from TAR. It only finishes when two TAR reads are within a small difference.
The value 10 is arbitrary and you can adjust it to suit your program.
Obviously I would recommend you to use the hardware provided by the Timer_A since this gives you the best solution.
|