简体   繁体   English

PIC18 上的门控定时器将 TMR3IF 标志设置为延迟,而对于 Fosc/4,它无论如何都不会设置

[英]Gated Timer on PIC18 sets TMR3IF flag to late & with Fosc/4 it doesn't set it anyway

I have already spent several nights debugging gated timer on PIC18F26K80.我已经花了几个晚上调试 PIC18F26K80 上的门控定时器。 I use MPLAB v4.15 and XC8 v2.32.我使用 MPLAB v4.15 和 XC8 v2.32。 I want to run a long period timer, so I chose Timer 3 gated by Timer 4. I've read Microchip's documentation and tried to find answers anywhere, but I cannot understand:我想运行一个长周期定时器,所以我选择了由定时器 4 门控的定时器 3。我已经阅读了 Microchip 的文档并试图在任何地方找到答案,但我无法理解:

  1. Why it doesn't set TMR3IF flag (and doesn't fire appropriate interruption) using Fosc/4 as a clock source of Timer 3 (so I use Fosc with prescale 1:4 - it works, but... why Fosc/4 doesn't?)为什么它不使用 Fosc/4 作为定时器 3 的时钟源设置 TMR3IF 标志(并且不触发适当的中断)(所以我使用 Fosc 和预分频比 1:4 - 它有效,但是......为什么 Fosc/4不是吗?)
  2. Why TMR3IF flag fires in TMR3 state 0x0001?为什么 TMR3IF 标志在 TMR3 state 0x0001 中触发? It should fire from 0xFFFF to 0x0000 and with PR4 = 0x63 there is no need to step over 0x0000 so fast.它应该从 0xFFFF 到 0x0000 触发,并且 PR4 = 0x63 不需要那么快地跨过 0x0000。

So these 2 points are the most important points, there are some other miracles, but, if you could, help me with these.所以这两点是最重要的一点,还有一些其他的奇迹,但是,如果可以的话,请帮我解决这些问题。

/* 
 * Test file for Gated timer
 */
// PIC18F26K80 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1L
#pragma config RETEN = OFF      // VREG Sleep Enable bit (Ultra low-power regulator is Disabled (Controlled by REGSLP bit))
#pragma config INTOSCSEL = HIGH // LF-INTOSC Low-power Enable bit (LF-INTOSC in High-power mode during Sleep)
#pragma config SOSCSEL = DIG   // SOSC Power Selection and mode Configuration bits (High Power SOSC circuit selected)
#pragma config XINST = OFF      // Extended Instruction Set (Disabled)

// CONFIG1H
#pragma config FOSC = INTIO2    // Oscillator (Internal RC oscillator)
#pragma config PLLCFG = OFF     // PLL x4 Enable bit (Disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor (Disabled)
#pragma config IESO = OFF       // Internal External Oscillator Switch Over Mode (Disabled)

// CONFIG2L
#pragma config PWRTEN = OFF     // Power Up Timer (Disabled)
#pragma config BOREN = SBORDIS  // Brown Out Detect (Enabled in hardware, SBOREN disabled)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (1.8V)
#pragma config BORPWR = ZPBORMV // BORMV Power level (ZPBORMV instead of BORMV is selected)

// CONFIG2H
#pragma config WDTEN = SWDTDIS  // Watchdog Timer (WDT enabled in hardware; SWDTEN bit disabled)
#pragma config WDTPS = 1048576  // Watchdog Postscaler (1:1048576)

// CONFIG3H
#pragma config CANMX = PORTB    // ECAN Mux bit (ECAN TX and RX pins are located on RB2 and RB3, respectively)
#pragma config MSSPMSK = MSK7   // MSSP address masking (7 Bit address masking mode)
#pragma config MCLRE = ON       // Master Clear Enable (MCLR Enabled, RE3 Disabled)

// CONFIG4L
#pragma config STVREN = ON      // Stack Overflow Reset (Enabled)
#pragma config BBSIZ = BB2K     // Boot Block Size (2K word Boot Block size)

// CONFIG5L
#pragma config CP0 = OFF        // Code Protect 00800-03FFF (Disabled)
#pragma config CP1 = OFF        // Code Protect 04000-07FFF (Disabled)
#pragma config CP2 = OFF        // Code Protect 08000-0BFFF (Disabled)
#pragma config CP3 = OFF        // Code Protect 0C000-0FFFF (Disabled)

// CONFIG5H
#pragma config CPB = OFF        // Code Protect Boot (Disabled)
#pragma config CPD = OFF        // Data EE Read Protect (Disabled)

// CONFIG6L
#pragma config WRT0 = OFF       // Table Write Protect 00800-03FFF (Disabled)
#pragma config WRT1 = OFF       // Table Write Protect 04000-07FFF (Disabled)
#pragma config WRT2 = OFF       // Table Write Protect 08000-0BFFF (Disabled)
#pragma config WRT3 = OFF       // Table Write Protect 0C000-0FFFF (Disabled)

// CONFIG6H
#pragma config WRTC = OFF       // Config. Write Protect (Disabled)
#pragma config WRTB = OFF       // Table Write Protect Boot (Disabled)
#pragma config WRTD = OFF       // Data EE Write Protect (Disabled)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protect 00800-03FFF (Disabled)
#pragma config EBTR1 = OFF      // Table Read Protect 04000-07FFF (Disabled)
#pragma config EBTR2 = OFF      // Table Read Protect 08000-0BFFF (Disabled)
#pragma config EBTR3 = OFF      // Table Read Protect 0C000-0FFFF (Disabled)

// CONFIG7H
#pragma config EBTRB = OFF      // Table Read Protect Boot (Disabled)


// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdint.h>

uint8_t tmr3Lprev = 0x00u;

void interrupt ISR(void){
    
        if(TMR3IF){
            if(TMR3L == 0x00u){  //after TMR3IF fires, TMR3L should be 0 (if PR4 is > cca 0x20)
                asm("BTG LATA, 2, 0"); //toggles with an output
            }else{
                LATAbits.LATA6 = 1;  // a failure flag
            }
            asm("BTG LATA, 1, 0"); //toggles with an output
            TMR3IF = 0;
        }
    
        if(TMR4IF){
            if(TMR3L == ++tmr3Lprev){  //TMR3L should increment on every T4 rollover
                asm("BTG LATA, 0, 0"); //toggles with an output
            }else{
                LATAbits.LATA5 = 1;  // a failure flag
            }
            TMR4IF = 0;
        }
        
    return;
}



void main(void) {
    
    //Clock setting (clock for system and all modules)
    OSCCONbits.IRCF = 0b111;
    OSCTUNEbits.PLLEN = 1; //turn on 4x Phase Lock Loop = 64MHz Clock
    
     //sets ports to output
    TRISA = 0x00; //A vse prepnout na vystup
    LATA = 0x00;

    //Timer4 initialization
    T4CONbits.T4OUTPS = 0;    //postscale, I don't know why, but doesen't effect length of T4 rollover
    T4CONbits.T4CKPS1 = 1;    //I dont know why, but T4CKPS = 0x11 doesnt set T4CKPS1 
    PR4 = 0x63;               //loop periode
    T4CONbits.TMR4ON = 1;     //1 = Timer 4 Enabled

    //Timer3 initialization
    T3CONbits.TMR3CS = 0b01;  //Clock source, 1 = system clock = Fosc; 0 = instruction clock = Fosc/4
    T3CONbits.T3CKPS = 0b10;  // 0b11 = 1:8 Prescale value; 0b10 = 1:4 Prescale value; 0b01 = 1:2 Prescale value; 0b00 = 1:1 Prescale value
    T3CONbits.SOSCEN = 0;
    T3CONbits.RD16   = 1;     //16bits wide register
    T3CONbits.TMR3ON = 1;     //1 = Timer 3 Enabled
    
    T3GCONbits.TMR3GE = 1; //Timer 3 is gated
    T3GCONbits.T3GPOL = 1; //high/low level of timer4 enables Timer3
    T3GCONbits.T3GTM = 0;  //Toggle mode disabled
    T3GCONbits.T3GSPM = 0; //Single pulse mode disabled
    T3GCONbits.T3GSS = 0x01; //TMR4 as a source

    WRITETIMER3(0x0000ul);
    TMR4 = 0x00;
    

    //interrupts handling
    PIE2bits.TMR3IE = 1;
    PIE4bits.TMR4IE = 1;
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;  
    
    //the infinite loop
    while(1){
  
    }
}

I have spent plenty of time solving this problem (even there: https://www.microchip.com/forums/m1211315.aspx ) and my conclusion is, that it is most probably a HW bug.我花了很多时间来解决这个问题(甚至在那里: https://www.microchip.com/forums/m1211315.aspx ),我的结论是,它很可能是硬件错误。 So Timers 1 and 3 with gated control (from Timer 2/4) works properly as a timer (their registers TMR1/3H/L increment well), but they fail in triggering interrupts and setting appropriate PIR flags.因此,带门控的定时器 1 和 3(来自定时器 2/4)作为定时器正常工作(它们的寄存器 TMR1/3H/L 递增良好),但它们无法触发中断和设置适当的 PIR 标志。 So my resolution for another applications is:所以我对另一个应用程序的解决方案是:

  1. let's use Timers 1/3 as counters of TMR2/4 rollovers (and make a 24bit wide timer), it works well and is useful;让我们使用定时器 1/3 作为 TMR2/4 翻转的计数器(并制作一个 24 位宽的定时器),它运行良好并且很有用;
  2. but do not use any (including CCP) ISR function (or PIR values) rising from Timer 1/3 with gated control from Timer 2/4.但不要使用任何(包括 CCP)ISR function(或 PIR 值)从定时器 1/3 上升到定时器 2/4 的门控。 I simply use ISR rising from Timer 2/4 and test Timer 1/3 state by SW.我只是简单地使用从 Timer 2/4 上升起的 ISR,并通过 SW 测试 Timer 1/3 state。

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

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