我正在开发一个使用 PIC12F675 微控制器的项目。我的目标是使用 GPIO1 上的内置 ADC 读取电压,并根据测量结果,我想打开 LED 几秒钟。之后,我打算使用 SLEEP() 宏让微控制器进入睡眠状态,并在大约一小时后重复测量过程(更长的持续时间,例如 2 小时也是可以接受的)。
我的问题是看门狗定时器(WDT)只能设置为大约2.3秒。即使当我尝试将 SLEEP() 宏包含在循环中时,WDT 也会在 2.3 秒后自动重置微控制器。我想知道是否有其他方法可以在较长时间后将微控制器从睡眠状态唤醒,而无需使用外部触发器。不幸的是,我无法使用外部触发器来实现此目的。谁能提供有关如何在不遇到 WDT 重置问题的情况下实现所需唤醒间隔的指导吗?
这是我的代码:
#include <xc.h>
// Configuration bits
#pragma config FOSC = INTRCIO // Internal oscillator
#pragma config WDTE = ON // Watchdog Timer enabled
#pragma config PWRTE = OFF // Power-up Timer disabled
#pragma config MCLRE = OFF // MCLR pin function is digital I/O
#pragma config BOREN = ON // Brown-out Reset enabled
#pragma config CP = OFF // Code protection disabled
#define _XTAL_FREQ 4000000 // Internal oscillator frequency for delay functions
void main() {
TRISIO = 0b00000010; // GP1 (ADC input) is an input, GP0 (LED output) is an output
ANSEL = 0b00000010; // Set GP1 as analog input
while (1) {
// Perform ADC measurement
ADCON0 = 0b00000001; // Select GP1 as ADC input
__delay_us(20); // Delay for ADC charging time
GO_nDONE = 1; // Start ADC conversion
while (GO_nDONE); // Wait for conversion to complete
// Read ADC result and control LED
uint16_t adcResult = ((ADRESH << 8) + ADRESL);
if (adcResult > 512) {
GP0 = 1; // Turn ON LED
__delay_ms(2000); // Keep LED ON for 2 seconds
GP0 = 0; // Turn OFF LED
}
for (unsigned int i = 0; i < 3600; i++) { // Loop for approximately 1 hour
SLEEP(); // Put microcontroller to sleep using WDT
}
}
}
由于除了预分频器之外无法通过其他方式更改看门狗的 RC 振荡器频率,因此我们无法比您所做的进一步减慢它的速度。
PIC12F675的睡眠指令描述如下(重点是我的):
掉电状态位, PD 已清除。超时状态 位,TO 被设置。 看门狗定时器 及其预分频器被清除。 处理器进入睡眠状态 振荡器停止的模式。
看门狗的描述(第9.6点):
正常情况下 操作时,WDT 超时会产生器件复位。 如果器件处于 SLEEP 模式,则 WDT 超时 导致设备唤醒并继续正常运行 操作
鉴于此,您提供的代码应该可以工作,并且似乎是获得较长睡眠时间的唯一合理方法。请注意,在您的睡眠循环中,MCU 每次唤醒时仅运行约 10 us(唤醒延迟和一些指令),这只是其在睡眠模式下花费的时间的一小部分,可以忽略不计。
更重要的是,当MCU处于睡眠模式时,ADC仍然会消耗功率,因此在进入睡眠模式之前将其关闭(ADCON0寄存器的ADON)并在进入睡眠模式后再次启用它。
我正在做类似的事情。您应该将 WDT 超时设置为 2.3 并检查您的电流消耗,看看您的 SLEEP() 是否实际上停止了 Fclk 时钟并重置了 WDT。