单片机成长之路(51基础篇) - 026 基于stm89c52之单片机看门狗

早过忘川 提交于 2019-12-01 17:09:50

基于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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!