2017-11-18 111 views
0

我想配置PIC24F16KA102的Timer1来对其进行计数。时钟源必须是8 MHz的内部时钟。我配置了寄存器T1CON并在高电平上设置了TON位来启动定时器。 Timer1设置为每隔100 us进入一次溢出,然后在一段时间内我将增加可变计数。我不明白,因为timer1不起作用,我观察到它不会增加。为什么?PIC24F16KA102上的Timer1不工作

#include <xc.h> 
    #include "config.h" 

    int count = 0; 

    void main(void) { 

     TRISB = 0;  

     T1CON = 0;  //TRM1 stopped, internal clock source, prescaler 1:1 

     _TON = 1; 
     TMR1 = 65135; //overflow of TM1 every 100 us (400 counts) 

     while (1) { 

      if (TMR1 == 65535) { 

      count++;  // increase every 100 us 
      TMR1 = 65135; 

      } 

     } 
    } 

回答

1

尝试设置定时器1周期寄存器(PR1)并使用中断而不是尝试捕获并重载TMR1的最终计数。你试图在65535上完全捕获TMR1,而这几乎不会工作,因为一旦TMR1命中65535,它就会溢出并从0再次开始计数。 编辑:当然,这个假设它根本算不了什么。我不知道当你将周期寄存器设置为0时定时器的行为是什么。它可以简单地计数到最大值65535,然后复位为0,或者根本不会计数,并将PRx连续加载到TMRx中,因为它们匹配在0

PRx旨在定义给定定时器所需的时间段,在本例中为100uS。 PR1 = 400.一旦TMR1 = PR1,定时器将自动复位并产生一个中断,提醒您计时器已经过去。

volatile unsigned int count = 0; //Vars that change in an ISR should be volatile 
PR1 = 400;   //Set Period for Timer1 (100us) 
T1CON = 0x8000;  //Enable Timer1 

IEC0bits.T1IE = 1;  //Enable Timer1 Interrupt 
IPC0bits.T1IP = 0b011; 

将这些信息与一个ISR功能递增计数,每当经过计时器:

void __attribute__ ((interrupt,no_auto_psv)) _T1Interrupt (void) 
{ 
count++; 
IFS0bits.T1IF = 0; //Make sure to clear the interrupt flag 
} 

你也可以尝试这样的事情,没有任何中断:

void main(void){ 
unsigned int count = 0; 
TMR1 = 0; 
T1CON = 0x8000; //TON = 1 

    while(1){ 
     if (TMR1 >= 400){ 
      count++; 
      TMR1=0; 
     } 
    } 
} 

不过,我会建议使用PR寄存器和ISR。这就是它的意图。

编辑:我也建议阅读定时器的PIC24F参考手册: Here