基于stc89c52的看门狗,代码如下:
main.c
#include "stc89c5x_Quick_configuration.h" // 自定义头文件
#include "data.h"
#include "bsp_gpio.h"
#include "bsp_wdt.h" void init_OS_Time(void){
DATA.Time.Time_Interrupt = ; // 设置步长
DATA.Time.Interrupt_count = ; // 设置单位步数
DATA.Time.Time_s = ; // 时间 s
DATA.Time.Time_h = ; // 时间 h
DATA.Time.Time_day = ; // 时间 日
DATA.Time.Time_month = ; // 时间 月
DATA.Time.Time_year = ; // 时间 年
} void main(void){
init_OS_Time();
init_WDT();
while(){
;
}
}
bsp_wdt.h
#ifndef __BSP_WDT_H_
#define __BSP_WDT_H_ /*------------------------------ 函数实现 -------------------------------*/
void Watchdog_timer_prescaler(void); // 看门狗定时器分频
void init_WDT(void); // 初始化看门狗 // 系统寄存器配置
struct OS_Register{
unsigned char WDT_Prescaler:; // 看门狗预分配系数
}; #endif
bsp_wdt.c
#include "BSP_WDT.h"
#include "stc89c5x_Quick_configuration.h"
#include "data.h" /*-------------------------------- 函数实现 --------------------------------*/
// 看门狗分频
void Watchdog_timer_prescaler(void){
if(DATA.Register_con.WDT_Prescaler > Watchdog_timer_prescaler_MAX)DATA.Register_con.WDT_Prescaler = Watchdog_timer_prescaler_MAX;
if(DATA.Register_con.WDT_Prescaler < Watchdog_timer_prescaler_MIN)DATA.Register_con.WDT_Prescaler = Watchdog_timer_prescaler_MIN;
WDT_CONTR &=~0x07; // 清除配置
WDT_CONTR |=Watchdog_timer_prescaler_MAX; // 配置
}
// 初始化看门狗
void init_WDT(void){
set_WDT_EN; // 打开看门狗
set_WDT_IDLE; // 打开“空闲模式”计时
Watchdog_timer_prescaler(); // 设置PS
}
data.h
#ifndef __DATA_H__
#define __DATA_H__ #include "BSP_WDT.h" // 终端时钟
struct OS_DATA{
struct OS_Register Register_con; // 看门狗
}; extern struct OS_DATA DATA; #endif
data.c
#include "data.h"
#include <STC89C5xRC.H> struct OS_DATA DATA;
stc89c5x_Quick_configuration.h(自定义头文件)
/*
stc89c5x_Quick_configuration.h
*/
#ifndef __STC89C5X_QUICK_CONFIGURATION_H__
#define __STC89C5X_QUICK_CONFIGURATION_H__
// stc 头文件
/*--------------------------------------------------------- 寄存器 ---------------------------------------------------------*/
sfr P0 = 0x80; // 引脚寄存器 P0
sfr SP = 0x81; // 堆栈指针
sfr DPL = 0x82; // 数据(DPTR)指针(低)
sfr DPH = 0x83; // 数据(DPTR)指针(高)
sfr PCON = 0x87; // 电源控制寄存器
sfr TCON = 0x88; // 定时器控制寄存器
sfr TMOD = 0x89; // 定时器工作方式寄存器
sfr TL0 = 0x8A; // 定时器0低8位寄存器
sfr TL1 = 0x8B; // 定时器1低8位寄存器
sfr TH0 = 0x8C; // 定时器0高8位寄存器
sfr TH1 = 0x8D; // 定时器1高8位寄存器
sfr AUXR = 0x8E; // 辅助寄存器(STC附加)
sfr P1 = 0x90; // 引脚寄存器 P1
sfr SCON = 0x98; // 串口控制寄存器
sfr SBUF = 0x99; // 串口数据缓冲器
sfr P2 = 0xA0; // 引脚寄存器 P2
sfr AUXR1 = 0xA2; // 辅助寄存器1(STC附加)
sfr IE = 0xA8; // 中断允许寄存
sfr SADDR = 0xA9; // 从机地址控制寄存器
sfr P3 = 0xB0; // 引脚寄存器 P3
sfr IPH = 0xb7; // 中断优先级寄存器(STC附加)
sfr IP = 0xB8; // 中断优先级寄存器
sfr SADEN = 0xB9; // 从机地址掩模寄存器
sfr XICON = 0xc0; // 辅助中断控制器
sfr T2CON = 0xC8; // 定时器/计数器2 控制
sfr T2MOD = 0xC9; // 定时器/计数器2 模式
sfr RCAP2L = 0xCA; // 定时器/计数器2 重新加载/捕获低字节
sfr RCAP2H = 0xCB; // 定时器/计数器2 重新加载/捕获高字节
sfr TL2 = 0xCC; // 定时器/计数器2 低字节
sfr TH2 = 0xCD; // 定时器/计数器2 高字节
sfr PSW = 0xD0; // 程序状态字寄存器
sfr ACC = 0xE0; // 累加器
sfr WDT_CONTR = 0xe1; // 看门狗控制寄存器
sfr ISP_DATA = 0xe2; // ISP/IAP 数据寄存器
sfr ISP_ADDRH = 0xe3; // ISP/IAP 高8位地址寄存
sfr ISP_ADDRL = 0xe4; // ISP/IAP 低8位地址寄存
sfr ISP_CMD = 0xe5; // ISP/IAP 命令寄存器
sfr ISP_TRIG = 0xe6; // ISP/IAP 命令触发寄存
sfr ISP_CONTR = 0xe7; // ISP/IAP控制寄存
sfr P4 = 0xe8; // 引脚寄存器 P4
sfr B = 0xF0; // B寄存器 /*--------------------------------------------------------- 位寻址 ---------------------------------------------------------*/
// P0 0x80
sbit P07 = P0^;
sbit P06 = P0^;
sbit P05 = P0^;
sbit P04 = P0^;
sbit P03 = P0^;
sbit P02 = P0^;
sbit P01 = P0^;
sbit P00 = P0^;
//TCON 0x88
sbit TF1 = TCON^; // 定时器1溢出中断标志: T1溢出中断标志。T1被允许计数以后,从初值开始加1计数。当产生溢出时由硬件置“1”TF1,向CPU请求中断,一直保持到CPU响应中断时,才由 硬件清“0”(也可由查询软件清“0”)。
sbit TR1 = TCON^; // 定时器1运行控制位
sbit TF0 = TCON^; // 定时器0溢出中断标志
sbit TR0 = TCON^; // 定时器0运行控制位
sbit IE1 = TCON^; // 外部中断1标志 (当检测到外部中断1边沿/低电平时由硬件置位该标志。中断处理时由硬件清零,或通过软件清零。)
sbit IT1 = TCON^; // 外部中断1中断源类型选择位(IT1=0,INT1/P3.3引脚上的低电平信号可触发外部中断1。IT1=1,外部中断1为下降沿触发方式。)
sbit IE0 = TCON^; // 外部中断0标志
sbit IT0 = TCON^; // 外部中断0中断源类型选择位
// set
#define set_TCON_TF1 TF1 = 1 // 设置中断标志位(硬件设置)
//#define // P1 0x90
sbit P17 = P1^;
sbit P16 = P1^;
sbit P15 = P1^;
sbit P14 = P1^;
sbit P13 = P1^;
sbit P12 = P1^;
sbit P11 = P1^;
sbit T2EX = P1^;
sbit P10 = P1^;
sbit T2 = P1^;
// SCON 0x98
sbit SM0 = SCON^; // alternatively "FE"
sbit FE = SCON^;
sbit SM1 = SCON^;
sbit SM2 = SCON^;
sbit REN = SCON^;
sbit TB8 = SCON^;
sbit RB8 = SCON^;
sbit TI = SCON^;
sbit RI = SCON^;
// P2 0xA0
sbit P27 = P2^;
sbit P26 = P2^;
sbit P25 = P2^;
sbit P24 = P2^;
sbit P23 = P2^;
sbit P22 = P2^;
sbit P21 = P2^;
sbit P20 = P2^;
//IE 0xA8
sbit EA = IE^;
sbit EC = IE^;
sbit ET2 = IE^;
sbit ES = IE^;
sbit ET1 = IE^;
sbit EX1 = IE^;
sbit ET0 = IE^;
sbit EX0 = IE^;
// P3 0xB0
sbit P37 = P3^;
sbit P36 = P3^;
sbit P35 = P3^;
sbit P34 = P3^;
sbit P33 = P3^;
sbit P32 = P3^;
sbit P31 = P3^;
sbit P30 = P3^;
// P3 0xB0
sbit RD = P3^;
sbit WR = P3^;
sbit T1 = P3^;
sbit T0 = P3^;
sbit INT1 = P3^;
sbit INT0 = P3^;
sbit TXD = P3^;
sbit RXD = P3^;
// IP 0xB8
// sbit PPC = IP^6; // 功能不明
sbit PT2 = IP^;
sbit PS = IP^;
sbit PT1 = IP^;
sbit PX1 = IP^;
sbit PT0 = IP^;
sbit PX0 = IP^;
//XICON 0xC0
sbit PX3 = XICON^; // 置位表明外部中断3的优先级为高,优先级最终由[PX3H,PX3]=[0,0];[0,1];[1,0];[1,1]来决定。
sbit EX3 = XICON^; // 如被设置成1,允许外部中断3中断;如被清成0,禁止外部中断3中断。
sbit IE3 = XICON^; // 外部中断3中断请求标志位,中断条件成立后,IE3=1,可由硬件自动清零。
sbit IT3 = XICON^; // 外部中断3中断源类型选择位。IT3=0,INT3/P4.2引脚上的低电平可触发外部中断3。IT3=1,外部中断3为下降沿触发方式。
sbit PX2 = XICON^; // 置位表明外部中断2的优先级为高,优先级最终由[PX2H,PX2]=[0,0];[0,1];[1,0];[1,1]来决定。
sbit EX2 = XICON^; // 如被设置成1,允许外部中断2中断;如被清成0,禁止外部中断2中断。
sbit IE2 = XICON^; // 外部中断2中断请求标志位,中断条件成立后,IE2=1,可由硬件自动清零。
sbit IT2 = XICON^; // 外部中断2中断源类型选择位。IT2=0,INT2/P4.3引脚上的低电平可触发外部中断2。IT2=1,外部中断2为下降沿触发方式。
/*
STC89C52系列单片机复位以后,IE和XICON被清0,由用户程序置“1”或 清“0”IE和XICON
相应的位,实现允许或禁止各中断源的中断申请,若使某一个中断源允许中断必须同时
使CPU开放中断。更新IE和XICON的内容可由位操作指令来实现(SETB BIT;CLR BIT),
也可用字节操作指令实现(即MOV IE,#DATA,ANL IE,#DATA;ORL IE,#DATA;MOV
IE,A等)。
*/
//T2CON 0xC8
sbit TF2 = T2CON^;
sbit EXF2 = T2CON^;
sbit RCLK = T2CON^;
sbit TCLK = T2CON^;
sbit EXEN2 = T2CON^;
sbit TR2 = T2CON^;
sbit C_T2 = T2CON^;
sbit CP_RL2= T2CON^;
//PSW 0xD0
sbit CY = PSW^;
sbit AC = PSW^;
sbit F0 = PSW^;
sbit RS1 = PSW^;
sbit RS0 = PSW^;
sbit OV = PSW^;
sbit P = PSW^;
//P4 0xE8
sbit P43 = P4^;
sbit P42 = P4^;
sbit P41 = P4^;
sbit P40 = P4^; /*---------------------------------------------------------------- 位定义 ----------------------------------------------------------------*/
/*-----------------------宏定义数据-----------------------*/
// bit
#define BIT0 (0x01<<0)
#define BIT1 (0x01<<1)
#define BIT2 (0x01<<2)
#define BIT3 (0x01<<3)
#define BIT4 (0x01<<4)
#define BIT5 (0x01<<5)
#define BIT6 (0x01<<6)
#define BIT7 (0x01<<7)
/*-------------------------------- 看门狗(0xe1) --------------------------------*/
/***********************************************************
sbit EN_WDT = WDT_CONTR^5; // 看门狗使能
sbit CLR_WDT = WDT_CONTR^4; // 看门狗清“0”位,当设为“1”时,看门狗将重新计数。硬件将自动清“0”此位。
sbit IDLE_WDT = WDT_CONTR^3; // 看门狗“IDLE”模式位,当设置为“1”时,看门狗定时器在“空闲模式”计数。当清“0”该位时, 看门狗定时器在“空闲模式”时不计数
sbit PS2 = WDT_CONTR^2; // 看门狗定时器预分频控制器 2
sbit PS1 = WDT_CONTR^1; // 看门狗定时器预分频控制器 1
sbit PS0 = WDT_CONTR^0; // 看门狗定时器预分频控制器 0 PS2 PS1 PS0 Pre_scale预分频 WDT Period @ 20MHz and 12 clocks mode
0 0 0 2 39.3mS
0 0 1 4 78.6mS
0 1 0 8 157.3mS
0 1 1 16 314.6mS
1 0 0 32 629.1mS
1 0 1 64 1.25S
1 1 0 128 2.5S
1 1 1 256 5S
看门狗溢出时间=( N x Pre_scale x 32768) / Oscillator frequency
***********************************************************/
/******************* WDT_CONTR ***********************/
// set
#define set_WDT_EN WDT_CONTR |=BIT5 // 打开看门狗
#define set_WDT_CLR WDT_CONTR |=BIT4 // 喂狗
#define set_WDT_IDLE WDT_CONTR |=BIT3 // 打开“空闲模式”计时
#define set_WDT_PS2 WDT_CONTR |=BIT2 // 看门狗定时器预分频控制器 2
#define set_WDT_PS1 WDT_CONTR |=BIT1 // 看门狗定时器预分频控制器 1
#define set_WDT_PS0 WDT_CONTR |=BIT0 // 看门狗定时器预分频控制器 0
// clear
#define clear_WDT_EN WDT_CONTR &=(~BIT5) // 关闭看门狗
#define clear_WDT_CLR WDT_CONTR &=(~BIT4) // 喂狗结束,硬件自动清理为0
#define clear_WDT_IDLE WDT_CONTR &=(~BIT3) // 看门狗定时器在“空闲模式”时不计数
#define clear_WDT_PS2 WDT_CONTR &=(~BIT2) // 看门狗定时器预分频控制器 2
#define clear_WDT_PS1 WDT_CONTR &=(~BIT1) // 看门狗定时器预分频控制器 1
#define clear_WDT_PS0 WDT_CONTR &=(~BIT0) // 看门狗定时器预分频控制器 0
// range
#define Watchdog_timer_prescaler_MIN 0 // 看门狗最小分频系数
#define Watchdog_timer_prescaler_MAX 7 // 看门狗最大分频系数 /* PCON(0x87) 电源控制寄存器
SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。
SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0
POF:上电复位标志位,单片机停电后,上电复位标志位为1,可由软件清0。实际应用:要判断是冷启动复位(断电),还是热复位(外部复位脚输入复位信号产生的复位,还是内部看门狗复位,软件复位或者其他复位)在初始化程序中,判断POF/PCON.4是否为1,如果为1,是冷启动,将其清零。如果为零,说明为热启动。
GF1,GF0 :两个通用工作标志位,用户可以任意使用。
PD :将其置1时,进入Power Down模式,可由外部中断低电平触发或下降沿触发唤醒,进入掉电模式时,内部时钟停振,由于无时钟CPU、定时器、串行口等功能部件停止工作,只有外部中断继续工作。掉电模式可由外部中断唤醒,中断返回后,继续执行原程序。掉电模式也叫停机模式,此时功耗<0.1uA。
IDL :将其置1,进入IDLE模式(空闲),除系统不给CPU供时钟,CPU不执行指令外,其余功能部件
05-27 14:59