为什么定时器1不PIC18计数?(Why is Timer1 not counting up on

2019-11-02 07:01发布

起初我有定时器0运行模式下正常工作。 唯一的问题是当设备进入睡眠模式,定时器0停止计数,直到醒来。 在数据表它说,使用定时器1,能够在睡眠模式监视时间。 我修改定时器0现有代码TIMER1新的配置,其他代码几乎是一样的。 然而,有件事我可能已经错过了大约TIMER1定时器0比不同,因为Timer1不计数的。 我使用的PIC是PIC18F87J11与MPLAB C18。

我将分享这似乎相关的代码,并根据要求需要我会添加更多。

定时器0代码段(从头文件)

#define TMR_IF          INTCONbits.TMR0IF
#define TMR_IE          INTCONbits.TMR0IE
#define TMR_IP          INTCON2bits.TMR0IP
#define TMR_ON          T0CONbits.TMR0ON
#define TMR_CON         T0CON
#define TMR_L           TMR0L
#define TMR_H           TMR0H 

定时器0(由C文件)

TMR_CON = 0b00000000 | CLOCK_DIVIDER_SETTING;
TMR_IP = 1;
TMR_IF = 0;
TMR_IE = 1;
TMR_ON = 1;

定时器0(如果我增加的时间)

if(TMR_IF)
        {
        printf("\r\n Passed here");
        timer_counter_high++; 
        }

输出: 这里传递


定时器1代码段(从头文件)

#define TMR_IF          PIR1bits.TMR1IF
#define TMR_IE          PIE1bits.TMR1IE
#define TMR_IP          IPR1bits.TMR1IP
#define TMR_ON          T1CONbits.TMR1ON
#define TMR_CON         T1CON
#define TMR_L           TMR1L
#define TMR_H           TMR1H

定时器1(由C文件)

TMR_CON = 0b11101101 | CLOCK_DIVIDER_SETTING;
TMR_IP = 1;
TMR_IF = 0;
TMR_IE = 1;
TMR_ON = 1;

定时器1(如果我增加的时间)

   if(TMR_IF)
        {
        printf("\r\n Passed here");
        timer_counter_high++; 
        }
        else
        {
        printf("\r\n Did not come through");
        }

输出: 没有来过

编辑:增加了CLOCK_DIVIDER_SETTING代码的要求。 这是正在使用的定时器0和定时器

#elif(CLOCK_FREQ <= 8000000)
        #define CLOCK_DIVIDER 32
        #define CLOCK_DIVIDER_SETTING 0x04
        #define SYMBOL_TO_TICK_RATE 8000000

我还是没有把睡眠模式,该器件在这种条件下进行测试定时器1,首先,我要弄清楚为什么Timer1是不是运行模式中计数。 我会很高兴与我的问题,任何帮助或想法,谢谢!

编辑2:我喜欢回答一些问题

Q1:可以定时器1仍与内部振荡器就像TIMER0使用吗?

Q2:你如何计算T1CON正确CLOCK_DIVIDER_SETTING? (我需要它,如果T1SYNC置和预分频器?)

Answer 1:

据PIC18F87J11系列datashet ,你需要在T1OSO和T1OSI引脚添加外部晶振如果要设置定时器1 oscilator(这可以通过设置T1RUN位T1CON寄存器做)衍生Timer1时钟。

还要注意的是,尽管分配CLOCK_DIVIDER_SETTING到T0CON寄存器正确设置时钟分频器,它错误地分配相同的CLOCK_DIVIDER_SETTING到T1CON寄存器becouse不同位的位置(在这种情况下,您可以有效设置位T1SYNC,你已经设置)和不同大小预分频器。

我也希望你在某处代码启用定时器之前设置寄存器TMR1H,TMR1L,TMR0L和TMR0H。

编辑添加回答更多的问题。

1:是,定时器1具有时钟的两个源-外部振荡器和内部时钟(FOSC / 4)。 为了使内部时钟,你必须清除位TMR1CS在T1CON寄存器中。

请注意,在睡眠期间所有的时钟都定时器1除外振荡器和INTRC(31 kHz时钟,不能由定时器1使用)禁用,所以你只能如果Timer1由外部振荡器时钟睡眠时测量时间与Timer1。

2:T1CKPS位是位4和5中T1CON寄存器,所以简单地通过四个比特移位时钟分频器设置要细。 记住,Timer1时钟分频器是只有两个比特宽,它可以通过的最大8除以因子时钟。

如果使用内部时钟T1SYNC位被忽略。 如果计划使用在休眠模式期间与Timer1外部振荡器,应该设置T1SYNC禁用外部时钟输入的同步(睡眠外部时钟期间不能被同步becouse有被同步到没有内部时钟和定时器将不计算)。

定时器1的配置应该是这个样子

#define CLOCK_DIVIDER_SETTING_T1 0x03 // divide clock by 8 (T1_clock/8)

// RD16 cleared
// T1OSCEN set - Timer1 oscillator is enabled
// T1SYNC set - Does not synchronize external clock input
// TMR1CS set - External clock from the RC0/T1OSO/T13CKI pin (on the rising edge)
// TMR1ON cleared - wait with enabling Timer1 until everything is configured
TMR_CON = 0b00001110 | (CLOCK_DIVIDER_SETTING_T1<<4);
TMR_IP = 1;
TMR_IF = 0;
TMR_IE = 1;
TMR_ON = 1;

如果你想使用内部时钟,然后T1_clock = FOSC / 4。

如果您使用内部振荡器作为系统时钟,那么你可以通过写OSCCON寄存器的IRCF位改变系统时钟分频器,但是这会影响整个微控制器的速度。

默认设置为4MHz,所以T1_clock将是1兆赫,和T1预分频之后将是125千赫。



文章来源: Why is Timer1 not counting up on PIC18?