簡體   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