繁体   English   中英

为什么Timer1没有在PIC18上计数?

[英]Why is Timer1 not counting up on PIC18?

最初我在运行模式下使Timer0工作正常。 唯一的问题是当器件进入休眠模式时,Timer0会一直停止计数直到唤醒。 在数据表中,它说使用Timer1能够在睡眠模式下监控时间。 我将timer0现有代码修改为timer1新配置,其他代码几乎相同。 然而,我可能已经错过了一些与timer0不同的东西,而不是timer0,因为timer1根本没有计数。 我正在使用的PIC是带有MPLAB C18的PIC18F87J11

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

Timer0代码段(来自头文件)

#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 

Timer0(来自C文件)

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

Timer0(我增加时间的地方)

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

输出: 通过这里


Timer1代码段(来自头文件)

#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

Timer1(来自C文件)

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

Timer1(我增加时间的地方)

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

输出: 未通过

编辑:根据请求添加了CLOCK_DIVIDER_SETTING代码。 这用于timer0和timer1

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

我仍然没有将设备置于睡眠模式以在这种情况下测试timer1,首先我必须弄清楚为什么timer1在运行模式期间没有计数。 我将非常感谢与我的问题有关的任何帮助或想法,谢谢!

编辑2:我想回答一些问题

Q1 :Timer1仍然可以像Timer0一样与内部振荡器一起使用吗?

Q2 :如何为T1CON计算正确的CLOCK_DIVIDER_SETTING? (如果设置了T1SYNC和预分频器,我是否需要它?)

根据PIC18F87J11 FAMILY datashet ,如果要设置从Timer1振荡器得到的Timer1时钟(通过设置T1CON寄存器中的T1RUN位,则需要在T1OSO和T1OSI引脚上添加外部晶振)。

另请注意,虽然将TOCK_IVIDER_SETTING分配给T0CON寄存器可以正确设置时钟预分频器,但由于不同的位位置(在这种情况下,您有效地设置了已经设置的位T1SYNC)和不同的大小,因此将相同的CLOCK_DIVIDER_SETTING分配给T1CON寄存器是错误的。预分频器。

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

编辑添加了其他问题的答案。

1:是的,Timer1有两个时钟源 - 外部振荡器和内部时钟(Fosc / 4)。 要使能内部时钟,必须清零T1CON寄存器中的TMR1CS位。

请注意,在睡眠期间,除Timer1振荡器和INTRC(31 kHz时钟,Timer1不能使用)外,所有时钟都被禁用,因此只有Timer1由外部振荡器提供时钟时,才能在休眠期间测量Timer1的时间。

2: T1CKPS位是T1CON寄存器中的第4位和第5位,因此将时钟分频器设置简单地移位4位应该没问题。 请记住,Timer1时钟预分频比仅为2位宽,它可以将时钟分频为最大8倍。

如果使用内部时钟,则忽略T1SYNC位。 如果您计划在休眠模式下使用带有Timer1的外部振荡器,则应将T1SYNC设置为禁用外部时钟输入的同步(在休眠期间外部时钟不能同步,因为没有内部时钟要同步,并且Timer1不会计数)。

Timer1的配置应如下所示

#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位来更改系统时钟的后分频器,但这会影响整个单片机的速度。

默认设置为4 MHz,因此T1_clock为1 MHz,T1预分频器后为125 kHz。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM