2017-11-18 87 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