基于stc89c52的看门狗,代码如下:
main.c
1 #include "stc89c5x_Quick_configuration.h" // 自定义头文件 2 #include "data.h" 3 #include "bsp_gpio.h" 4 #include "bsp_wdt.h" 5 6 void init_OS_Time(void){ 7 DATA.Time.Time_Interrupt = 1; // 设置步长 8 DATA.Time.Interrupt_count = 0; // 设置单位步数 9 DATA.Time.Time_s = 0; // 时间 s 10 DATA.Time.Time_h = 0; // 时间 h 11 DATA.Time.Time_day = 0; // 时间 日 12 DATA.Time.Time_month = 0; // 时间 月 13 DATA.Time.Time_year = 0; // 时间 年 14 } 15 16 void main(void){ 17 init_OS_Time(); 18 init_WDT(); 19 while(1){ 20 ; 21 } 22 }
bsp_wdt.h
1 #ifndef __BSP_WDT_H_ 2 #define __BSP_WDT_H_ 3 4 /*------------------------------ 函数实现 -------------------------------*/ 5 void Watchdog_timer_prescaler(void); // 看门狗定时器分频 6 void init_WDT(void); // 初始化看门狗 7 8 // 系统寄存器配置 9 struct OS_Register{ 10 unsigned char WDT_Prescaler:3; // 看门狗预分配系数 11 }; 12 13 #endif
bsp_wdt.c
1 #include "BSP_WDT.h" 2 #include "stc89c5x_Quick_configuration.h" 3 #include "data.h" 4 5 /*-------------------------------- 函数实现 --------------------------------*/ 6 // 看门狗分频 7 void Watchdog_timer_prescaler(void){ 8 if(DATA.Register_con.WDT_Prescaler > Watchdog_timer_prescaler_MAX)DATA.Register_con.WDT_Prescaler = Watchdog_timer_prescaler_MAX; 9 if(DATA.Register_con.WDT_Prescaler < Watchdog_timer_prescaler_MIN)DATA.Register_con.WDT_Prescaler = Watchdog_timer_prescaler_MIN; 10 WDT_CONTR &=~0x07; // 清除配置 11 WDT_CONTR |=Watchdog_timer_prescaler_MAX; // 配置 12 } 13 // 初始化看门狗 14 void init_WDT(void){ 15 set_WDT_EN; // 打开看门狗 16 set_WDT_IDLE; // 打开“空闲模式”计时 17 Watchdog_timer_prescaler(); // 设置PS 18 }
data.h
1 #ifndef __DATA_H__ 2 #define __DATA_H__ 3 4 #include "BSP_WDT.h" 5 6 // 终端时钟 7 struct OS_DATA{ 8 struct OS_Register Register_con; // 看门狗 9 }; 10 11 extern struct OS_DATA DATA; 12 13 #endif
data.c
1 #include "data.h" 2 #include <STC89C5xRC.H> 3 4 struct OS_DATA DATA;
stc89c5x_Quick_configuration.h(自定义头文件)
1 /* 2 stc89c5x_Quick_configuration.h 3 */ 4 #ifndef __STC89C5X_QUICK_CONFIGURATION_H__ 5 #define __STC89C5X_QUICK_CONFIGURATION_H__ 6 // stc 头文件 7 /*--------------------------------------------------------- 寄存器 ---------------------------------------------------------*/ 8 sfr P0 = 0x80; // 引脚寄存器 P0 9 sfr SP = 0x81; // 堆栈指针 10 sfr DPL = 0x82; // 数据(DPTR)指针(低) 11 sfr DPH = 0x83; // 数据(DPTR)指针(高) 12 sfr PCON = 0x87; // 电源控制寄存器 13 sfr TCON = 0x88; // 定时器控制寄存器 14 sfr TMOD = 0x89; // 定时器工作方式寄存器 15 sfr TL0 = 0x8A; // 定时器0低8位寄存器 16 sfr TL1 = 0x8B; // 定时器1低8位寄存器 17 sfr TH0 = 0x8C; // 定时器0高8位寄存器 18 sfr TH1 = 0x8D; // 定时器1高8位寄存器 19 sfr AUXR = 0x8E; // 辅助寄存器(STC附加) 20 sfr P1 = 0x90; // 引脚寄存器 P1 21 sfr SCON = 0x98; // 串口控制寄存器 22 sfr SBUF = 0x99; // 串口数据缓冲器 23 sfr P2 = 0xA0; // 引脚寄存器 P2 24 sfr AUXR1 = 0xA2; // 辅助寄存器1(STC附加) 25 sfr IE = 0xA8; // 中断允许寄存 26 sfr SADDR = 0xA9; // 从机地址控制寄存器 27 sfr P3 = 0xB0; // 引脚寄存器 P3 28 sfr IPH = 0xb7; // 中断优先级寄存器(STC附加) 29 sfr IP = 0xB8; // 中断优先级寄存器 30 sfr SADEN = 0xB9; // 从机地址掩模寄存器 31 sfr XICON = 0xc0; // 辅助中断控制器 32 sfr T2CON = 0xC8; // 定时器/计数器2 控制 33 sfr T2MOD = 0xC9; // 定时器/计数器2 模式 34 sfr RCAP2L = 0xCA; // 定时器/计数器2 重新加载/捕获低字节 35 sfr RCAP2H = 0xCB; // 定时器/计数器2 重新加载/捕获高字节 36 sfr TL2 = 0xCC; // 定时器/计数器2 低字节 37 sfr TH2 = 0xCD; // 定时器/计数器2 高字节 38 sfr PSW = 0xD0; // 程序状态字寄存器 39 sfr ACC = 0xE0; // 累加器 40 sfr WDT_CONTR = 0xe1; // 看门狗控制寄存器 41 sfr ISP_DATA = 0xe2; // ISP/IAP 数据寄存器 42 sfr ISP_ADDRH = 0xe3; // ISP/IAP 高8位地址寄存 43 sfr ISP_ADDRL = 0xe4; // ISP/IAP 低8位地址寄存 44 sfr ISP_CMD = 0xe5; // ISP/IAP 命令寄存器 45 sfr ISP_TRIG = 0xe6; // ISP/IAP 命令触发寄存 46 sfr ISP_CONTR = 0xe7; // ISP/IAP控制寄存 47 sfr P4 = 0xe8; // 引脚寄存器 P4 48 sfr B = 0xF0; // B寄存器 49 50 /*--------------------------------------------------------- 位寻址 ---------------------------------------------------------*/ 51 // P0 0x80 52 sbit P07 = P0^7; 53 sbit P06 = P0^6; 54 sbit P05 = P0^5; 55 sbit P04 = P0^4; 56 sbit P03 = P0^3; 57 sbit P02 = P0^2; 58 sbit P01 = P0^1; 59 sbit P00 = P0^0; 60 //TCON 0x88 61 sbit TF1 = TCON^7; // 定时器1溢出中断标志: T1溢出中断标志。T1被允许计数以后,从初值开始加1计数。当产生溢出时由硬件置“1”TF1,向CPU请求中断,一直保持到CPU响应中断时,才由 硬件清“0”(也可由查询软件清“0”)。 62 sbit TR1 = TCON^6; // 定时器1运行控制位 63 sbit TF0 = TCON^5; // 定时器0溢出中断标志 64 sbit TR0 = TCON^4; // 定时器0运行控制位 65 sbit IE1 = TCON^3; // 外部中断1标志 (当检测到外部中断1边沿/低电平时由硬件置位该标志。中断处理时由硬件清零,或通过软件清零。) 66 sbit IT1 = TCON^2; // 外部中断1中断源类型选择位(IT1=0,INT1/P3.3引脚上的低电平信号可触发外部中断1。IT1=1,外部中断1为下降沿触发方式。) 67 sbit IE0 = TCON^1; // 外部中断0标志 68 sbit IT0 = TCON^0; // 外部中断0中断源类型选择位 69 // set 70 #define set_TCON_TF1 TF1 = 1 // 设置中断标志位(硬件设置) 71 //#define 72 73 74 // P1 0x90 75 sbit P17 = P1^7; 76 sbit P16 = P1^6; 77 sbit P15 = P1^5; 78 sbit P14 = P1^4; 79 sbit P13 = P1^3; 80 sbit P12 = P1^2; 81 sbit P11 = P1^1; 82 sbit T2EX = P1^1; 83 sbit P10 = P1^0; 84 sbit T2 = P1^0; 85 // SCON 0x98 86 sbit SM0 = SCON^7; // alternatively "FE" 87 sbit FE = SCON^7; 88 sbit SM1 = SCON^6; 89 sbit SM2 = SCON^5; 90 sbit REN = SCON^4; 91 sbit TB8 = SCON^3; 92 sbit RB8 = SCON^2; 93 sbit TI = SCON^1; 94 sbit RI = SCON^0; 95 // P2 0xA0 96 sbit P27 = P2^7; 97 sbit P26 = P2^6; 98 sbit P25 = P2^5; 99 sbit P24 = P2^4; 100 sbit P23 = P2^3; 101 sbit P22 = P2^2; 102 sbit P21 = P2^1; 103 sbit P20 = P2^0; 104 //IE 0xA8 105 sbit EA = IE^7; 106 sbit EC = IE^6; 107 sbit ET2 = IE^5; 108 sbit ES = IE^4; 109 sbit ET1 = IE^3; 110 sbit EX1 = IE^2; 111 sbit ET0 = IE^1; 112 sbit EX0 = IE^0; 113 // P3 0xB0 114 sbit P37 = P3^7; 115 sbit P36 = P3^6; 116 sbit P35 = P3^5; 117 sbit P34 = P3^4; 118 sbit P33 = P3^3; 119 sbit P32 = P3^2; 120 sbit P31 = P3^1; 121 sbit P30 = P3^0; 122 // P3 0xB0 123 sbit RD = P3^7; 124 sbit WR = P3^6; 125 sbit T1 = P3^5; 126 sbit T0 = P3^4; 127 sbit INT1 = P3^3; 128 sbit INT0 = P3^2; 129 sbit TXD = P3^1; 130 sbit RXD = P3^0; 131 // IP 0xB8 132 // sbit PPC = IP^6; // 功能不明 133 sbit PT2 = IP^5; 134 sbit PS = IP^4; 135 sbit PT1 = IP^3; 136 sbit PX1 = IP^2; 137 sbit PT0 = IP^1; 138 sbit PX0 = IP^0; 139 //XICON 0xC0 140 sbit PX3 = XICON^7; // 置位表明外部中断3的优先级为高,优先级最终由[PX3H,PX3]=[0,0];[0,1];[1,0];[1,1]来决定。 141 sbit EX3 = XICON^6; // 如被设置成1,允许外部中断3中断;如被清成0,禁止外部中断3中断。 142 sbit IE3 = XICON^5; // 外部中断3中断请求标志位,中断条件成立后,IE3=1,可由硬件自动清零。 143 sbit IT3 = XICON^4; // 外部中断3中断源类型选择位。IT3=0,INT3/P4.2引脚上的低电平可触发外部中断3。IT3=1,外部中断3为下降沿触发方式。 144 sbit PX2 = XICON^3; // 置位表明外部中断2的优先级为高,优先级最终由[PX2H,PX2]=[0,0];[0,1];[1,0];[1,1]来决定。 145 sbit EX2 = XICON^2; // 如被设置成1,允许外部中断2中断;如被清成0,禁止外部中断2中断。 146 sbit IE2 = XICON^1; // 外部中断2中断请求标志位,中断条件成立后,IE2=1,可由硬件自动清零。 147 sbit IT2 = XICON^0; // 外部中断2中断源类型选择位。IT2=0,INT2/P4.3引脚上的低电平可触发外部中断2。IT2=1,外部中断2为下降沿触发方式。 148 /* 149 STC89C52系列单片机复位以后,IE和XICON被清0,由用户程序置“1”或 清“0”IE和XICON 150 相应的位,实现允许或禁止各中断源的中断申请,若使某一个中断源允许中断必须同时 151 使CPU开放中断。更新IE和XICON的内容可由位操作指令来实现(SETB BIT;CLR BIT), 152 也可用字节操作指令实现(即MOV IE,#DATA,ANL IE,#DATA;ORL IE,#DATA;MOV 153 IE,A等)。 154 */ 155 //T2CON 0xC8 156 sbit TF2 = T2CON^7; 157 sbit EXF2 = T2CON^6; 158 sbit RCLK = T2CON^5; 159 sbit TCLK = T2CON^4; 160 sbit EXEN2 = T2CON^3; 161 sbit TR2 = T2CON^2; 162 sbit C_T2 = T2CON^1; 163 sbit CP_RL2= T2CON^0; 164 //PSW 0xD0 165 sbit CY = PSW^7; 166 sbit AC = PSW^6; 167 sbit F0 = PSW^5; 168 sbit RS1 = PSW^4; 169 sbit RS0 = PSW^3; 170 sbit OV = PSW^2; 171 sbit P = PSW^0; 172 //P4 0xE8 173 sbit P43 = P4^3; 174 sbit P42 = P4^2; 175 sbit P41 = P4^1; 176 sbit P40 = P4^0; 177 178 /*---------------------------------------------------------------- 位定义 ----------------------------------------------------------------*/ 179 /*-----------------------宏定义数据-----------------------*/ 180 // bit 181 #define BIT0 (0x01<<0) 182 #define BIT1 (0x01<<1) 183 #define BIT2 (0x01<<2) 184 #define BIT3 (0x01<<3) 185 #define BIT4 (0x01<<4) 186 #define BIT5 (0x01<<5) 187 #define BIT6 (0x01<<6) 188 #define BIT7 (0x01<<7) 189 /*-------------------------------- 看门狗(0xe1) --------------------------------*/ 190 /*********************************************************** 191 sbit EN_WDT = WDT_CONTR^5; // 看门狗使能 192 sbit CLR_WDT = WDT_CONTR^4; // 看门狗清“0”位,当设为“1”时,看门狗将重新计数。硬件将自动清“0”此位。 193 sbit IDLE_WDT = WDT_CONTR^3; // 看门狗“IDLE”模式位,当设置为“1”时,看门狗定时器在“空闲模式”计数。当清“0”该位时, 看门狗定时器在“空闲模式”时不计数 194 sbit PS2 = WDT_CONTR^2; // 看门狗定时器预分频控制器 2 195 sbit PS1 = WDT_CONTR^1; // 看门狗定时器预分频控制器 1 196 sbit PS0 = WDT_CONTR^0; // 看门狗定时器预分频控制器 0 197 198 PS2 PS1 PS0 Pre_scale预分频 WDT Period @ 20MHz and 12 clocks mode 199 0 0 0 2 39.3mS 200 0 0 1 4 78.6mS 201 0 1 0 8 157.3mS 202 0 1 1 16 314.6mS 203 1 0 0 32 629.1mS 204 1 0 1 64 1.25S 205 1 1 0 128 2.5S 206 1 1 1 256 5S 207 看门狗溢出时间=( N x Pre_scale x 32768) / Oscillator frequency 208 ***********************************************************/ 209 /******************* WDT_CONTR ***********************/ 210 // set 211 #define set_WDT_EN WDT_CONTR |=BIT5 // 打开看门狗 212 #define set_WDT_CLR WDT_CONTR |=BIT4 // 喂狗 213 #define set_WDT_IDLE WDT_CONTR |=BIT3 // 打开“空闲模式”计时 214 #define set_WDT_PS2 WDT_CONTR |=BIT2 // 看门狗定时器预分频控制器 2 215 #define set_WDT_PS1 WDT_CONTR |=BIT1 // 看门狗定时器预分频控制器 1 216 #define set_WDT_PS0 WDT_CONTR |=BIT0 // 看门狗定时器预分频控制器 0 217 // clear 218 #define clear_WDT_EN WDT_CONTR &=(~BIT5) // 关闭看门狗 219 #define clear_WDT_CLR WDT_CONTR &=(~BIT4) // 喂狗结束,硬件自动清理为0 220 #define clear_WDT_IDLE WDT_CONTR &=(~BIT3) // 看门狗定时器在“空闲模式”时不计数 221 #define clear_WDT_PS2 WDT_CONTR &=(~BIT2) // 看门狗定时器预分频控制器 2 222 #define clear_WDT_PS1 WDT_CONTR &=(~BIT1) // 看门狗定时器预分频控制器 1 223 #define clear_WDT_PS0 WDT_CONTR &=(~BIT0) // 看门狗定时器预分频控制器 0 224 // range 225 #define Watchdog_timer_prescaler_MIN 0 // 看门狗最小分频系数 226 #define Watchdog_timer_prescaler_MAX 7 // 看门狗最大分频系数 227 228 229 /* PCON(0x87) 电源控制寄存器 230 SMOD:波特率选择位。当用软件置位SMOD,即SMOD=1,则使串行通信方式1、2、3的波特率加倍;SMOD=0,则各工作方式的波特率加倍。复位时SMOD=0。 231 SMOD0:帧错误检测有效控制位。当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;当SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。复位时SMOD0=0 232 POF:上电复位标志位,单片机停电后,上电复位标志位为1,可由软件清0。实际应用:要判断是冷启动复位(断电),还是热复位(外部复位脚输入复位信号产生的复位,还是内部看门狗复位,软件复位或者其他复位)在初始化程序中,判断POF/PCON.4是否为1,如果为1,是冷启动,将其清零。如果为零,说明为热启动。 233 GF1,GF0 :两个通用工作标志位,用户可以任意使用。 234 PD :将其置1时,进入Power Down模式,可由外部中断低电平触发或下降沿触发唤醒,进入掉电模式时,内部时钟停振,由于无时钟CPU、定时器、串行口等功能部件停止工作,只有外部中断继续工作。掉电模式可由外部中断唤醒,中断返回后,继续执行原程序。掉电模式也叫停机模式,此时功耗<0.1uA。 235 IDL :将其置1,进入IDLE模式(空闲),除系统不给CPU供时钟,CPU不执行指令外,其余功能部件仍可继续工作,可由任何一个中断唤醒。 236 */ 237 // set 238 #define set_PCON_SMOD PCON |=BIT7; // 使串口通信方式1,2,3的波特率加倍 239 #define set_PCON_SMOD0 PCON |=BIT6; // SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能 240 #define set_PCON_POF PCON |=BIT4; // 上电复位标志 241 #define set_PCON_GF1 PCON |=BIT3; // user 自定义使用标志位 1(公共) 242 #define set_PCON_GF0 PCON |=BIT2; // user 自定义使用标志位 0(公共) 243 #define set_PCON_PD PCON |=BIT1; // 将其置1时,进入Power Down模式 244 #define set_PCON_IDL PCON |=BIT0; // 进入空闲模式 245 // clear 246 #define clear_PCON_SMOD PCON &=(~BIT7); // 各工作方式的波特率加倍。复位时SMOD=0。 247 #define clear_PCON_SMOD0 PCON &=(~BIT6); // SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式 248 #define clear_PCON_POF PCON &=(~BIT4); // 上电复位标志 249 #define clear_PCON_GF1 PCON &=(~BIT3); // user 自定义使用标志位 1(公共) 250 #define clear_PCON_GF0 PCON &=(~BIT2); // user 自定义使用标志位 0(公共) 251 #define clear_PCON_PD PCON &=(~BIT1); // 将其置1时,进入Power Down模式(掉电模式) 252 #define clear_PCON_IDL PCON &=(~BIT0); // 不进入空闲模式 253 // get 254 #define get_PCON_SMOD (bit)((PCON^BIT7)>>0x07) // 获取波特率加倍 255 #define get_PCON_SMOD0 (bit)((PCON^BIT6)>>0x06) // 帧错误检测 256 #define get_PCON_POF (bit)((PCON^BIT4)>>0x04) // 获取上电复位标志,(1为上电复位,1为非上电复位) 257 #define get_PCON_GF1 (bit)((PCON^BIT3)>>0x03) // 获取 user 自定义使用标志位 1(公共) 258 #define get_PCON_GF0 (bit)((PCON^BIT2)>>0x02) // 获取 user 自定义使用标志位 1(公共) 259 #define get_PCON_PD (bit)((PCON^BIT1)>>0x01) // 获取(掉电模式)状态标志位 260 #define get_PCON_IDL (bit)((PCON^BIT0)>>0x00) // 获取空闲模式标志位 261 262 263 264 265 266 267 #endif