You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PIC18F26K80门控Timer3 TMR3IF标志置位异常求助

PIC18F26K80门控定时器调试问题求助

我花费数晚调试PIC18F26K80单片机的门控定时器功能,所用开发环境为MPLAB v4.15、XC8 v2.32。因项目需要实现长周期定时,我选用Timer4作为门控信号源驱动Timer3,查阅Microchip官方文档并多方检索相关资料后,仍无法解释以下两个核心异常问题:

  • Timer3时钟源配置为Fosc/4时,TMR3IF中断标志始终无法置位,也无法触发对应中断;临时改用Fosc时钟搭配1:4预分频的配置可正常工作,但无法定位Fosc/4时钟源失效的根本原因。
  • TMR3IF标志会在TMR3计数值为0x0001时提前触发。按照芯片设计逻辑,该标志应在Timer3计数值从0xFFFF溢出到0x0000时置位,当前PR4配置为0x63,理论上不应出现计数值过快跨过0x0000产生溢出的情况。

调试过程中还遇到其他异常现象,现优先求助上述两个问题的解决方案,完整测试代码如下:

/* 
 * 门控定时器测试文件
 */
// PIC18F26K80 配置位设置
// C语言源码配置位声明
// CONFIG1L
#pragma config RETEN = OFF      // VREG休眠使能位(超低压差稳压器禁用,由REGSLP位控制)
#pragma config INTOSCSEL = HIGH // LF-INTOSC低功耗使能位(休眠模式下LF-INTOSC工作在高功耗模式)
#pragma config SOSCSEL = DIG   // SOSC电源选择与模式配置位(选择高功耗SOSC电路)
#pragma config XINST = OFF      // 扩展指令集(禁用)

// CONFIG1H
#pragma config FOSC = INTIO2    // 振荡器配置(内部RC振荡器)
#pragma config PLLCFG = OFF     // PLL 4倍频使能位(禁用)
#pragma config FCMEN = OFF      // 故障保护时钟监视器(禁用)
#pragma config IESO = OFF       // 内外振荡器切换模式(禁用)

// CONFIG2L
#pragma config PWRTEN = OFF     // 上电定时器(禁用)
#pragma config BOREN = SBORDIS  // 掉电检测(硬件使能,SBOREN位禁用)
#pragma config BORV = 3         // 掉电复位电压位(1.8V)
#pragma config BORPWR = ZPBORMV // BORMV功耗等级(选择ZPBORMV而非BORMV)

// CONFIG2H
#pragma config WDTEN = SWDTDIS  // 看门狗定时器(硬件使能WDT,SWDTEN位禁用)
#pragma config WDTPS = 1048576  // 看门狗后分频器(1:1048576)

// CONFIG3H
#pragma config CANMX = PORTB    // ECAN复用位(ECAN收发引脚分别映射到RB2、RB3)
#pragma config MSSPMSK = MSK7   // MSSP地址屏蔽(7位地址屏蔽模式)
#pragma config MCLRE = ON       // 主清除使能(MCLR引脚使能,RE3引脚禁用)

// CONFIG4L
#pragma config STVREN = ON      // 栈溢出复位(使能)
#pragma config BBSIZ = BB2K     // 引导块大小(2K字引导块大小)

// CONFIG5L
#pragma config CP0 = OFF        // 代码保护 00800-03FFF(禁用)
#pragma config CP1 = OFF        // 代码保护 04000-07FFF(禁用)
#pragma config CP2 = OFF        // 代码保护 08000-0BFFF(禁用)
#pragma config CP3 = OFF        // 代码保护 0C000-0FFFF(禁用)

// CONFIG5H
#pragma config CPB = OFF        // 引导区代码保护(禁用)
#pragma config CPD = OFF        // 数据EEPROM读保护(禁用)

// CONFIG6L
#pragma config WRT0 = OFF       // 表写保护 00800-03FFF(禁用)
#pragma config WRT1 = OFF       // 表写保护 04000-07FFF(禁用)
#pragma config WRT2 = OFF       // 表写保护 08000-0BFFF(禁用)
#pragma config WRT3 = OFF       // 表写保护 0C000-0FFFF(禁用)

// CONFIG6H
#pragma config WRTC = OFF       // 配置位写保护(禁用)
#pragma config WRTB = OFF       // 引导区表写保护(禁用)
#pragma config WRTD = OFF       // 数据EEPROM写保护(禁用)

// CONFIG7L
#pragma config EBTR0 = OFF      // 表读保护 00800-03FFF(禁用)
#pragma config EBTR1 = OFF      // 表读保护 04000-07FFF(禁用)
#pragma config EBTR2 = OFF      // 表读保护 08000-0BFFF(禁用)
#pragma config EBTR3 = OFF      // 表读保护 0C000-0FFFF(禁用)

// CONFIG7H
#pragma config EBTRB = OFF      // 引导区表读保护(禁用)


// #pragma配置位声明必须放在项目头文件包含之前
// 请使用项目枚举值而非#define来定义ON和OFF

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

uint8_t tmr3Lprev = 0x00u;

void interrupt ISR(void){
    
        if(TMR3IF){
            if(TMR3L == 0x00u){  //TMR3IF触发后,TMR3L应为0(PR4大于约0x20时)
                asm("BTG LATA, 2, 0"); //翻转输出引脚电平
            }else{
                LATAbits.LATA6 = 1;  // 故障标志位
            }
            asm("BTG LATA, 1, 0"); //翻转输出引脚电平
            TMR3IF = 0;
        }
    
        if(TMR4IF){
            if(TMR3L == ++tmr3Lprev){  //TMR4每次溢出时TMR3L应加1
                asm("BTG LATA, 0, 0"); //翻转输出引脚电平
            }else{
                LATAbits.LATA5 = 1;  // 故障标志位
            }
            TMR4IF = 0;
        }
        
    return;
}



void main(void) {
    
    //时钟配置(系统及所有外设模块时钟源)
    OSCCONbits.IRCF = 0b111;
    OSCTUNEbits.PLLEN = 1; //开启4倍频锁相环,时钟频率为64MHz
    
     //将端口设置为输出
    TRISA = 0x00; //将A口全部设置为输出
    LATA = 0x00;

    //Timer4初始化
    T4CONbits.T4OUTPS = 0;    //后分频系数,实测不影响T4溢出周期
    T4CONbits.T4CKPS1 = 1;    //实测直接给T4CKPS赋值0x11时无法正确置位T4CKPS1
    PR4 = 0x63;               //循环周期值
    T4CONbits.TMR4ON = 1;     //1 = 使能Timer4

    //Timer3初始化
    T3CONbits.TMR3CS = 0b01;  //时钟源选择,1 = 系统时钟Fosc;0 = 指令时钟Fosc/4
    T3CONbits.T3CKPS = 0b10;  // 0b11 = 1:8预分频;0b10 = 1:4预分频;0b01 = 1:2预分频;0b00 = 1:1预分频
    T3CONbits.SOSCEN = 0;
    T3CONbits.RD16   = 1;     //16位寄存器读写模式
    T3CONbits.TMR3ON = 1;     //1 = 使能Timer3
    
    T3GCONbits.TMR3GE = 1; //使能Timer3门控
    T3GCONbits.T3GPOL = 1; //Timer4输出高/低电平时使能Timer3计数
    T3GCONbits.T3GTM = 0;  //禁用翻转模式
    T3GCONbits.T3GSPM = 0; //禁用单脉冲模式
    T3GCONbits.T3GSS = 0x01; //选择TMR4输出作为门控源

    WRITETIMER3(0x0000ul);
    TMR4 = 0x00;
    

    //中断配置
    PIE2bits.TMR3IE = 1;
    PIE4bits.TMR4IE = 1;
    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;  
    
    //死循环
    while(1){
  
    }
}

内容的提问来源于stack exchange,提问作者OndraCER552

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:15:41