在这篇博客中,我们将探讨如何在PIC16F1719微控制器上使用看门狗定时器(WDT)来实现LED控制。本篇示例展示了如何配置WDT,使LED每隔16秒闪烁一次,并且在WDT超时后唤醒CPU。
看门狗定时器是一种硬件定时器,通常用于确保系统的可靠性。当系统进入睡眠模式后,WDT计时开始,在设定的时间内,如果没有重置WDT,系统会触发一个超时事件,通常会导致系统复位或从睡眠状态唤醒。
本程序演示了如何利用PIC16F1719的看门狗定时器来控制LED。程序执行如下操作:
通过这种方式,可以使用WDT在低功耗模式下进行周期性任务,比如节省能源的情况下控制设备的状态指示灯。
我们使用了PIC16F1719的配置位,具体设置如下:
c#pragma config FOSC = INTOSC /* 振荡器选择 (内部振荡器) */
#pragma config WDTE = OFF /* 看门狗定时器禁用,稍后在代码中启用 */
#pragma config MCLRE = ON /* MCLR引脚功能启用 */
#pragma config LVP = ON /* 低电压编程使能 */
这些配置位定义了系统的基础设置,例如振荡器源和看门狗定时器的状态。程序中启用WDT时,程序会动态调整WDT的超时时间。
下面是主程序的核心代码:
cvoid main(void) {
OSCCON = 0xF0; /* 设置内部振荡器为8MHz,并使用4xPLL使系统频率达到32MHz */
INTCON = 0; /* 禁用所有中断源 */
/* 设置端口模式 */
ANSELA = 0x00; // 所有A端口引脚设置为数字模式
ANSELB = 0x00; // 所有B端口引脚设置为数字模式
ANSELC = 0x00; // 所有C端口引脚设置为数字模式
// 设置D1引脚为输出模式
TRISDbits.TRISD1 = 0;
LATDbits.LATD1 = 0; // 初始关闭LED
/* 配置看门狗定时器 */
WDTCONbits.WDTPS = 0b01110; // 设置WDT超时时间为16秒
while (1) {
// LED闪烁
LATDbits.LATD1 = 1;
__delay_ms(3000); // LED亮3秒
LATDbits.LATD1 = 0;
// 进入睡眠模式
SLEEP();
}
}
在这段代码中,WDT定时周期被设置为16秒。配置行如下:
cWDTCONbits.WDTPS = 0b01110; // 设置WDT周期为16秒
通过这一设置,WDT将在16秒后超时并唤醒CPU。
在主循环中,LED每3秒亮一次,并且随后系统进入睡眠模式,等待WDT超时。在WDT超时后,系统被唤醒,LED再次被控制亮起。
当系统调用SLEEP()
函数时,CPU会进入睡眠模式,所有操作停止,直到WDT超时后系统被唤醒。此时,程序会从上次暂停的地方继续执行。
c/* PIC16F1719 配置位设置 */
#pragma config FOSC = INTOSC /* 振荡器选择位 (INTOSC 振荡器: CLKIN 引脚上的 I/O 功能) */
#pragma config WDTE = OFF /* 看门狗定时器使能 (WDT 禁用) */
#pragma config PWRTE = OFF /* 上电定时器使能 (PWRT 禁用) */
#pragma config MCLRE = ON /* MCLR 引脚功能选择 (MCLR/VPP 引脚功能为 MCLR) */
#pragma config CP = OFF /* 闪存程序存储器代码保护 (程序存储器代码保护禁用) */
#pragma config BOREN = OFF /* 低电压复位使能 (低电压复位禁用) */
#pragma config CLKOUTEN = OFF /* 时钟输出使能 (CLKOUT 功能禁用。CLKOUT 引脚上的 I/O 或振荡器功能) */
#pragma config IESO = ON /* 内外部切换模式 (内外部切换模式使能) */
#pragma config FCMEN = ON /* 故障安全时钟监控器使能 (故障安全时钟监控器使能) */
#pragma config WRT = OFF /* 闪存自写保护 (写保护关闭) */
#pragma config PPS1WAY = OFF /* 外设引脚选择单向控制 (PPSLOCK 位可以通过软件反复设置和清除) */
#pragma config ZCDDIS = ON /* 零交叉检测禁用 (ZCD 禁用。ZCD 可以通过设置 ZCDCON 的 ZCDSEN 位来启用) */
#pragma config PLLEN = ON /* 锁相环使能 (4x PLL 使能) */
#pragma config STVREN = ON /* 栈溢出/下溢复位使能 (栈溢出或下溢将导致复位) */
#pragma config BORV = LO /* 低电压复位电压选择 (低电压复位电压 (Vbor),选择低触发点。) */
#pragma config LPBOR = OFF /* 低功率低电压复位 (低功率低电压复位禁用) */
#pragma config LVP = ON /* 低电压编程使能 (低电压编程使能) */
/* 定义系统振荡器频率 */
#define _XTAL_FREQ (32000000ul)
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//counter variable
int count = 0;
void main(void) {
unsigned char index = 0;
/* 程序初始化设置 */
OSCCON = 0xF0; /* 设置 INTOSC 为 8MHz,并使用 4xPLL,使系统振荡器达到 32MHz */
INTCON = 0; /* 禁用所有中断源 */
PIE1 = 0;
PIE2 = 0;
PIE3 = 0;
// Allow PLL startup time ~2 ms
__delay_ms(10);
ANSELA = 0x00; // 将所有A端口引脚设置为数字模式
ANSELB = 0x00; // 将所有B端口引脚设置为数字模式
ANSELC = 0x00; // 将所有C端口引脚设置为数字模式
// Set PIN D1 as output
TRISDbits.TRISD1 = 0;
// Turn off LED
LATDbits.LATD1 = 0;
// Set PIN B0 as input
TRISBbits.TRISB0 = 1;
// Configure ANSELB0
ANSELBbits.ANSB0 = 0;
////////////////////////////
// Configure Watchdog timer
////////////////////////////
// Set WDT period to 16s
WDTCONbits.WDTPS = 0b01110;
INTCONbits.PEIE = 1; // 使能外设中断
INTCONbits.GIE = 1; // 使能全局中断
while (1) {
// flash LED
LATDbits.LATD1 = 1;
__delay_ms(3000);
LATDbits.LATD1 = 0;
// Sleep
SLEEP();
}
}
通过这篇文章,我们学习了如何使用PIC16F1719的看门狗定时器进行LED控制。WDT不仅能用来监控系统是否卡死,还可以实现低功耗设备的周期性操作。在该示例中,LED每16秒闪烁一次,同时系统进入睡眠节省电能。
这是一种高效的硬件定时器使用方式,特别适用于需要在低功耗条件下执行定期任务的嵌入式系统。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!