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

PIC10F320的TMR0计数器异常及触摸传感器复位失效问题求助

PIC10F320 触摸传感器复位TMR0功能调试问题

我是PIC编程新手,当前采用C语言开发(ASM汇编学习成本较高暂未使用),基于PIC10F320开发时遇到基础问题:自行配置的TMR0计数器工作异常,用于复位计数器的触摸传感器无响应,卡壳许久特来求助,感谢大家帮忙排查。

更新

大家好,感谢Kozmotronik指出错误,我已重新计算参数并重新分配寄存器位,解决了全局中断溢出问题;因T0CS默认是8位定时器,已移除option_reg相关错误配置,在Proteus中仿真10秒后定时器工作已恢复正常。目前仅剩触摸传感器复位功能未调试通,因没有触摸传感器仿真模型,我暂用普通按键替代,已附上Proteus电路图,麻烦各位帮忙查看问题,相关代码如下:

// CONFIG
#pragma config FOSC = INTOSC  // 振荡器选择
#pragma config BOREN = OFF    // 掉电复位关闭
#pragma config WDTE = OFF    // 看门狗定时器关闭
#pragma config PWRTE = OFF    // 上电定时器关闭
#pragma config MCLRE = OFF   // MCLR引脚功能选择位->MCLR引脚为数字输入,内部接VDD
#pragma config CP = OFF      // 代码保护关闭
#pragma config LVP = OFF     // 低压编程关闭
#pragma config LPBOR = OFF    // 掉电复位选择位关闭
#pragma config BORV = LO    // 掉电复位电压选择为低阈值
#pragma config WRT = OFF    // 闪存自写保护关闭

// #pragma配置语句需放在项目文件包含之前
// 开关状态请使用枚举定义,不要用#define定义ON/OFF
#include <xc.h>
#include <pic10f320.h>

#define _XTAL_FREQ 8000000
#define SWITCH PORTAbits.RA2
#define PWMPin PORTAbits.RA1
#define LEDPin PORTAbits.RA0

unsigned long cnt;
/*
                            主应用
    */


void setup(void)
{    
        /**
    LATx寄存器配置
    */
    LATA = 0x00;

    /**
    TRISx寄存器配置
    */
    TRISA = 0x04;

    /**
    ANSELx寄存器配置
    */
    ANSELA = 0x00;

    // 清空占空比寄存器
    PR2 = 255;   
    T2CONbits.T2CKPS = 0b00;
    T2CONbits.TMR2ON = 0x01;

    /*
     * 计算说明:
     * 8MHz主频下,Tosc为125ns,Tcyc=4*Tosc=500ns
     * PR2设为十进制52、预分频器为1时,PWM周期为Tcyc*(PR2+1) = 500ns*53 = 26.5us
     * 100%占空比时:
     * 脉宽 = PWMxDCH/L(10位) * Tosc * 1(预分频系数)
     * 26.5us/125ns = PWMxDCH/L = 十进制212
     * PWMxDCH = 0xd4
     * PWMxDCL = 0x00
     * 
     * 75%占空比时,需计数的脉宽为26.5us*0.75=19.9us
     * 19.9us/125ns = PWMxDCH/L = 十进制159
     * PWMxDCH = 0x9f
     * PWMxDCL = 0x00
     */
    
    // 配置TMR0用于生成延时
    TMR0 = 0xFF;  // 初始化TMR0值
//  OPTION_REG = 0x07;
    //INTCON = 0xA0;
   
>  INTCONbits.TMR0IF = 0; // 清除TMR0中断标志位
>  INTCONbits.TMR0IE = 1;


    OPTION_REGbits.T0CS = 0; // TMR0时钟源选择为系统时钟
    OPTION_REGbits.PSA = 1; // TMR0不分配预分频器
    /*
     * 计算公式:
       Fosc/4 = 8MHZ/4 = 2MHZ 

       单计数周期= 1 / 2MHZ = 0.0000005s

       8位计数器溢出周期 = 0.0000005 * 256 = 0.000128s
     * 
     * 每128us溢出一次
     * 1秒延时所需溢出次数 = 1000000*(1/128) = 7812.5
     * 1分钟所需计数 = 7812.5*60 = 468750
     * 1小时所需计数 = 468750*60 = 28125000
     * 12小时所需计数 = 28125000*12 = 337500000
     */
}


void main(void)
{
    setup();
    cnt = 0;
    
    //OSCCON = 2;
    
    while(1){
        PWMPin = 1;
        LEDPin = 1;
        
        if(SWITCH==1){
            cnt++;    
        }
        
        if(INTCONbits.TMR0IF){
            cnt++; 
            

          > TMR0 = 0 ;  /// 重置TMR0值

            INTCONbits.TMR0IF=0; // 重置定时器中断标志位
            
        }
            // 达到10秒阈值时触发(修改该数值可调整延时长度)
        if(cnt>78125){
                // RA1输出75%占空比
                // PWM1POL高电平有效;PWM1OE输出使能;PWM1EN模块使能; 
            PWM2CON = 0xC0;   
            PWM1CONbits.PWM1OE = 0x01;   // 开启PWM1输出
            PWM1CONbits.PWM1EN = 0x01;  // 使能PWM1模块
            PWM2DCH = 0x00;
            PWM2DCL = 0x00;  
            PWM1DCH = 0x00;
            PWM1DCL = 0x00;
                    
            PWM2DCH = 0xBF;
            PWM2DCL = 0x00;
            
            // LED呼吸灯效果
            for(int i=0;i<212;i++){
                PWM1DCH = i;
                __delay_ms(25);
            }
            for(int i=212;i>0;i--){
                PWM1DCH = i;
                __delay_ms(25);
            }
        }
    }
}

问题排查与修复方案

根据你提供的代码和描述,按键复位功能异常的核心问题和修复方式如下:

  1. 按键逻辑错误:当前代码检测到按键按下时执行cnt++,而非你需要的重置计数器逻辑,这是最直接的问题
  2. 缺少按键消抖处理:机械按键按下/释放时会产生电平抖动,直接检测电平会导致触发不灵敏或误触发,需添加10~20ms的消抖逻辑
  3. TMR0初始值错误:setup函数中你将TMR0初始化为0xFF,会导致第一次溢出时间远短于128us,建议改为0保持计数周期一致
  4. 全局中断未开启:你已经开启了TMR0的中断使能位TMR0IE,但未开启全局中断使能位GIE和外设中断使能位PEIE,当前轮询TMR0IF的工作模式不受影响,后续如果启用中断功能必须补充这两个配置

修复后的核心代码片段

// setup函数补充配置
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
TMR0 = 0; // 修正TMR0初始值

// 主循环按键逻辑修改为:
if(SWITCH==1){
    __delay_ms(20); // 消抖
    if(SWITCH==1){ // 二次确认按键状态
        cnt = 0; // 重置计数器
        while(SWITCH==1); // 等待按键释放,避免单次按下多次触发
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:15:04