关于TIMER0的配置和使用,我有点疑问
code中这么初始化的:
TIMER0->CSR = T_CRST | T_MODE_PERIODIC | T_WR_TCMP_NO_RST | T_TDR_EN + 21 ;
所以更新timer0的CMP寄存器时,只要当TCMP <= TDR时才会重新从0开始计数:
Periodic Mode Behavior Selection
0 = In One-shot or Periodic mode, when write new TCMP, timer counter will reset.
1 = In One-shot or Periodic mode, when write new TCMP if new TCMP > TDR(current
counter) , timer counter keep counting and will not reset. If new TCMP <= TDR(current
counter) , timer counter will reset.
再看运用:
void TMR1_IRQHandler(void)
{
uint32_t PeriodLast ;
TIMER0->CMPR = ~0 ; // ~0 is 0xFFFFFFFF
TIMER1->ISR = ~0 ; // Clear all interrupt flag
ZeroDeadline = PeriodNow << 1 ;
do{
if((*pPhase) & DetectUpBit){
if(ACMP->SR & AcmpOutBit){ ++StepCount; break; } // up zero
}
else{
if((ACMP->SR & AcmpOutBit)==0){ ++StepCount; break; } // down zero
}
}while(TIMER0->DR < ZeroDeadline) ;
PeriodLast = (TIMER1->DR - ZeroTick) & 0xFFFFFF ;
这里ZeroDeadline 的值是周期的一半,按while条件中的比较,TIMER0->DR从0开始计数才是合理的,但是前面TIMER0->CMPR赋予的是最大值,所以定时器0不会RST,
TIMER0->DR不会从0开始计数。这个while的延时条件是有问题的。
================================
我认为应该这么做:
只要更新TIMER0->CMPR值,就会重新从0开始计数
TIMER0->CSR = T_CRST | T_MODE_PERIODIC | T_TDR_EN + 21 ;
然后再修改一处地方:
if(PeriodNow > PeriodMax) PeriodNow = PeriodMax ;
TIMER0->CMPR = TIMER0->DR + ((PeriodNow*PhaseAngle) >> 6) ; // Set TIMER0 period
TIMER1->CMPR = TIMER1->DR + ((PeriodNow*3)>>2) ; // Set TIMER1 interrupt
修改成:
if(PeriodNow > PeriodMax) PeriodNow = PeriodMax ;
TIMER0->CMPR = ((PeriodNow*PhaseAngle) >> 6) ; // Set TIMER0 period
TIMER1->CMPR = TIMER1->DR + ((PeriodNow*3)>>2) ; // Set TIMER1 interrupt
|