简体   繁体   English

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

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

Initially I had Timer0 working fine during the run mode. 最初我在运行模式下使Timer0工作正常。 The only problem is when the device goes to sleep mode, Timer0 stops counting up until awaken. 唯一的问题是当器件进入休眠模式时,Timer0会一直停止计数直到唤醒。 In the datasheet it says to use Timer1 to be able to monitor time during sleep mode. 在数据表中,它说使用Timer1能够在睡眠模式下监控时间。 I modified timer0 existing code to timer1 new configurations, the other code is pretty much the same. 我将timer0现有代码修改为timer1新配置,其他代码几乎相同。 However, there is something I might have missed that is different about timer1 than timer0, since the timer1 is not counting up at all. 然而,我可能已经错过了一些与timer0不同的东西,而不是timer0,因为timer1根本没有计数。 The PIC I'm using is PIC18F87J11 with MPLAB C18. 我正在使用的PIC是带有MPLAB C18的PIC18F87J11

I will share the code that seems relevant and upon request I will add more as needed. 我将分享看似相关的代码,并根据要求我将根据需要添加更多。

Timer0 Snippet Code ( From Header File) 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 (From C File) Timer0(来自C文件)

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

Timer0 (Where I increment the time) Timer0(我增加时间的地方)

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

Output: Passed here 输出: 通过这里


Timer1 Snippet Code ( From Header File) 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 (From C File) Timer1(来自C文件)

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

Timer1 (Where I increment the time) Timer1(我增加时间的地方)

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

Output: Did not come through 输出: 未通过

Edit:Added the CLOCK_DIVIDER_SETTING code as requested. 编辑:根据请求添加了CLOCK_DIVIDER_SETTING代码。 This is being used for timer0 and timer1 这用于timer0和timer1

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

I still did not put the device on sleep mode to test timer1 in that condition, first I have to figure out why timer1 is not counting up during the run mode. 我仍然没有将设备置于睡眠模式以在这种情况下测试timer1,首先我必须弄清楚为什么timer1在运行模式期间没有计数。 I will appreciate any help or ideas related to my problem, Thanks! 我将非常感谢与我的问题有关的任何帮助或想法,谢谢!

Edit 2: Some questions that I like to be answered 编辑2:我想回答一些问题

Q1 : Can Timer1 still be used with the internal oscillator just like timer0? Q1 :Timer1仍然可以像Timer0一样与内部振荡器一起使用吗?

Q2 : How do you calculate the correct CLOCK_DIVIDER_SETTING for T1CON ? Q2 :如何为T1CON计算正确的CLOCK_DIVIDER_SETTING? (Do I need it if T1SYNC is set and the prescaler?) (如果设置了T1SYNC和预分频器,我是否需要它?)

According to PIC18F87J11 FAMILY datashet , you need to add external crystal on T1OSO and T1OSI pins if you are setting Timer1 clock derived from Timer1 oscilator (which you do by setting T1RUN bit in T1CON register). 根据PIC18F87J11 FAMILY datashet ,如果要设置从Timer1振荡器得到的Timer1时钟(通过设置T1CON寄存器中的T1RUN位,则需要在T1OSO和T1OSI引脚上添加外部晶振)。

Also note, that although assigning CLOCK_DIVIDER_SETTING to T0CON register correctly sets clock prescaler, it wrong to assign the same CLOCK_DIVIDER_SETTING to T1CON register becouse of different bit locations (in this case you are effectively setting bit T1SYNC, which you already set) and different size of prescaler. 另请注意,虽然将TOCK_IVIDER_SETTING分配给T0CON寄存器可以正确设置时钟预分频器,但由于不同的位位置(在这种情况下,您有效地设置了已经设置的位T1SYNC)和不同的大小,因此将相同的CLOCK_DIVIDER_SETTING分配给T1CON寄存器是错误的。预分频器。

I also hope that you are setting registers TMR1H, TMR1L, TMR0L and TMR0H somewhere in code before enabling timers. 我还希望您在启用定时器之前在代码中的某处设置寄存器TMR1H,TMR1L,TMR0L和TMR0H。

EDIT Added answers to additional questions. 编辑添加了其他问题的答案。

1: Yes, Timer1 have two sources of clock - external oscillator and internal clock (Fosc/4). 1:是的,Timer1有两个时钟源 - 外部振荡器和内部时钟(Fosc / 4)。 To enable internal clock you have to clear bit TMR1CS in T1CON register. 要使能内部时钟,必须清零T1CON寄存器中的TMR1CS位。

Please note, that during sleep all clocks are disabled except Timer1 oscillator and INTRC (31 kHz clock, which cannot be used by Timer1), so you can measure time with Timer1 during sleep only if Timer1 is clocked by external oscillator. 请注意,在睡眠期间,除Timer1振荡器和INTRC(31 kHz时钟,Timer1不能使用)外,所有时钟都被禁用,因此只有Timer1由外部振荡器提供时钟时,才能在休眠期间测量Timer1的时间。

2: T1CKPS bits are bits 4 and 5 in T1CON register, so simply shifting clock divider setting by four bits should be fine. 2: T1CKPS位是T1CON寄存器中的第4位和第5位,因此将时钟分频器设置简单地移位4位应该没问题。 Remember, that Timer1 clock prescaler is only two bits wide, and it can divide clock by maximum factor of 8. 请记住,Timer1时钟预分频比仅为2位宽,它可以将时钟分频为最大8倍。

T1SYNC bit is ignored if you use internal clock. 如果使用内部时钟,则忽略T1SYNC位。 If you plan using external oscillator with Timer1 during sleep mode, you should set T1SYNC to disable synchronisation of external clock input (during sleep external clock cannot be synchronised becouse there is no internal clock to be synchronised to and Timer1 will not count). 如果您计划在休眠模式下使用带有Timer1的外部振荡器,则应将T1SYNC设置为禁用外部时钟输入的同步(在休眠期间外部时钟不能同步,因为没有内部时钟要同步,并且Timer1不会计数)。

Configuration of Timer1 should look something like this 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;

If you want to use internal clock, then T1_clock = Fosc/4. 如果要使用内部时钟,则T1_clock = Fosc / 4。

If you use internal oscillator as system clock, then you can change postscaler of system clock by writing to IRCF bits in OSCCON register, but this will affect speed of whole microcontroller. 如果使用内部振荡器作为系统时钟,则可以通过写入OSCCON寄存器中的IRCF位来更改系统时钟的后分频器,但这会影响整个单片机的速度。

The default setting is 4 MHz, so T1_clock would be 1 MHz, and after T1 prescaler it would be 125 kHz. 默认设置为4 MHz,因此T1_clock为1 MHz,T1预分频器后为125 kHz。

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

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