0

我想配置PIC24F16KA102的timer1来计数。时钟源必须是 8 MHz 的内部时钟。我配置了寄存器 T1CON 并将 TON 位设置为高电平以启动定时器。Timer1 设置为每 100 us 溢出一次,然后在一段时间内我将增加变量计数。我不明白,因为 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;

             }

        }
   }
4

1 回答 1

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 参考手册: 这里

于 2017-11-20T15:25:18.877 回答