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

PIC12F675休眠时WDT复位问题:需实现长间隔唤醒

解决PIC12F675长休眠唤醒的WDT复位问题

问题概述

基于PIC12F675的项目需求:

  • 利用GPIO1内置ADC采集电压,根据测量结果控制LED点亮2秒
  • 进入休眠状态,约1~2小时后自动唤醒,重复采集流程

当前遇到的问题:看门狗定时器(WDT)最长仅支持约2.3秒超时,将SLEEP()放入循环后,单片机仍会在2.3秒后被WDT复位,无法实现长周期休眠。要求无需外部触发,解决该WDT复位问题。

问题根源

代码中仅通过配置位开启了WDT(WDTE = ON),但未将WDT设置为唤醒模式。默认情况下,PIC12F675的WDT超时会触发单片机复位,而非仅唤醒休眠状态,导致循环休眠逻辑失效。

解决方案

1. 切换WDT至唤醒模式

通过OPTION_REG寄存器的WDTE位(运行时寄存器位,非配置位)将WDT设置为唤醒模式:

  • WDTE = 0:WDT超时仅唤醒休眠,不触发复位
  • WDTE = 1:WDT超时触发复位(默认状态)

2. 配置WDT最大预分频

将WDT预分频器设为最大(1:128),对应最长约2.3秒的超时时间,通过多次休眠循环累计实现长周期休眠。

3. 休眠前的必要操作

每次休眠前调用CLRWDT()清除WDT定时器,确保从0开始计时,避免提前超时。

修正后的代码

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTRCIO   // Internal oscillator
#pragma config WDTE = ON        // Enable WDT (required for wake-up)
#pragma config PWRTE = OFF      // Disable Power-up Timer
#pragma config MCLRE = OFF      // MCLR pin is digital I/O
#pragma config BOREN = ON       // Enable Brown-out Reset
#pragma config CP = OFF         // Disable Code Protection

#define _XTAL_FREQ 4000000     // Internal oscillator frequency for delay functions
#define SLEEP_CYCLES_1H 1563   // ~2.3s per cycle × 1563 ≈ 3600s (1 hour)
#define SLEEP_CYCLES_2H 3126   // ~2.3s per cycle × 3126 ≈ 7200s (2 hours)

void main() {
    TRISIO = 0b00000010;      // GP1 (ADC input) = input, GP0 (LED output) = output
    ANSEL = 0b00000010;       // Set GP1 as analog input
    OPTION_REG = 0b00000111;  // WDT prescaler 1:128 (~2.3s timeout), WDTE=0 (wake-up mode)
    
    while (1) {
        // ADC Measurement
        ADCON0 = 0b00000001;  // Select GP1 as ADC channel
        __delay_us(20);       // ADC acquisition delay
        GO_nDONE = 1;         // Start conversion
        while (GO_nDONE);     // Wait for conversion complete
        
        // Control LED based on ADC result
        uint16_t adcResult = ((ADRESH << 8) + ADRESL);
        if (adcResult > 512) {
            GP0 = 1;
            __delay_ms(2000);
            GP0 = 0;
        }
        
        // Cycle sleep to accumulate total duration
        for (unsigned int i = 0; i < SLEEP_CYCLES_1H; i++) {
            CLRWDT();          // Reset WDT timer before sleep
            SLEEP();           // Enter sleep, wake on WDT timeout
        }
    }
}

关键细节说明

  • OPTION_REG配置:0b00000111的最后三位(PS2-PS0)设置为111,对应WDT预分频比1:128,结合内部振荡器得到最长约2.3秒的超时周期。
  • 休眠次数计算:1小时=3600秒,3600÷2.3≈1563次循环,以此累计实现长休眠。
  • CLRWDT():必须在每次休眠前调用,确保WDT从头开始计时,避免因残留计时导致提前唤醒或复位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:50:19