CC2541蓝牙学习——看门狗

看门狗是在软件跑飞的情况下CPU自恢复的一个方式,看门狗分为硬狗和软狗,硬狗就是由专门的看门狗硬件电路实现看门狗功能,看门狗芯片也比较多,比如DS1232,除了看门狗功能外还有电源电压监测功能。软狗就是由软件实现的看门狗功能,现在很多CPU都自带了软狗,很难说硬狗好还是软狗好,如果软狗够用,尽量使用软狗简化设计,看门狗说白了就是一个定时器!,当软件在选定的时间间隔内不能置位看门狗定时器(WDT),WDT就复位系统。看门狗可用于电噪声,电源故障或静电放电等恶劣工作环境或高可靠性要求的环境。如果系统不需要应用到看门狗,则WDT可配置成间隔定时器,当时间间隔到达产生中断。 WDT的特性如下:

  1. 4个可选择的时间间隔
  2. 看门狗模式
  3. 定时器模式
  4. 定时器模式下产生中断请求

CC2541的看门狗定时器(WDT)可以配置成看门狗模式或者普通的间隔定时器,WDT包括一个15位定时/计数器,它的频率由32.768KHz的晶振决定,用户不能查看计数器的值。

看门狗的模式由寄存器WDCTL来配置,寄存器WDCTL的定义如下:

WDCTL.INT[1:0]:定时器定时间隔选择位,有四种可选的时间间隔,32.768KHz时钟下,1s、0.25s、15.625ms、1.9ms分别对应32768、8192、512和64个时钟周期。注意,定时时间间隔只能在看门狗处于空闲(IDLE)模式下才能配置有效。

WDCTL.MODE[1:0]:模式选择位,有三种模式可选择,空闲模式、看门狗模式和计时器模式,在计时器模式下,设置该位为00空闲模式则停止该计数器,当需要从计数器模式转换到看门狗模式,必须首先使该位为00使之处于空闲模式,然后再赋值10,转换到看门狗模式。如果处于看门狗模式,则不管向该位写入什么值都不起作用了,始终处于看门狗模式。一般来说,也不会在程序里切换模式,都是作单一用途的。

WDCTL.CLR[3:0]:看门狗定时器清零位,在看门狗模式下,先向该位写入0xa,再写入0x5,定时器计数值清0,注意的是写入0x5必须紧跟着写入0xa,这两条语句之间不能插入其他语句。当处于空闲模式下,写该位不会产生任何影响

 1 /******************************************************************************
 2 *函 数 名:FeetDog
 3 *功    能:喂狗,计数器清0
 4 *入口参数:无
 5 *出口参数:无
 6 ******************************************************************************/
 7 void FeetDog(void)
 8 {
 9   WDCTL = 0xa0;   //清除定时器。当0xA 跟随0x5 写到这些位,定时器被清除
10   WDCTL = 0x50;
11 }

计时器模式下WDCTL.CLR[0]位置1(其他三位不管写入什么值),则计数器清0(0x0000),但计数器不会停止计数,WDCTL.MODE[1:0]设置为00,计时器模式下计数器才停止并且计数值清0。

1、看门狗模式

系统复位后默认是处于空闲模式的,所以需要人为设置为看门狗模式,将WDCTL.MODE[1:0]设置为10,此时看门狗计数器开始从0计数,一旦处于看门狗模式,就没有办法停止该计数器了,向WDCTL.MODE[1:0]写入00或者其他值都没有作用了。

如果计数器计数到设定的计数值(32768、8192、512或者64),就会产生一个系统复位信号,如果计数器被清0,则此时计数器又从0开始计数,此过程称为”喂狗“,所以在程序合适的位置放置喂狗代码,程序运行一次循环则会清除计数器一次(喂狗一次),计数器就不会溢出,如果程序跑飞了,就执行不到喂狗代码,超过设定的时间间隔,计数器就会溢出,对系统复位。看门狗模式下不会产生中断。另外前面说过定时间隔只能在看门狗处于空闲(IDLE)模式下才能配置有效,而一旦设定为看门狗模式,就不会回到空闲(IDLE)模式,所以定时时间间隔也是不可更改的了。注意:看门狗的时间间隔应该大于喂狗程序执行一次所需的时间!不然还没喂狗计数器就溢出复位了。一般的1s都够了,没有哪个程序执行一次的时间会超过1s吧,呵呵。

2、计时器模式

将WDCTL.MODE[1:0]设置为11,WDT处于计时器模式。一旦设定WDCTL.MODE[1:0]为11,计数器就开始从0计数,当计数值达到设定的的计数值(32768、8192、512或者64),便会产生看门狗中断请求,IEN2.WDTIE看门狗中断使能的情况下,IRCON2.WDTIF看门狗中断标志位变为1。注意中断使能信号放在WDCTL.MODE[1:0]配置前面,不然计数器开始计时了,还没有开中断。

在计数器模式下,WDCTL.CLR[0]为1则清除计数器,然后从0开始计数,并不会停止计数器,WDCTL.MODE[1:0]设置为00,计数器停止工作并且计数值清0。在计数器工作的时候,写入

WDCTL.INT[1:0] 无效,定时时间间隔无法改变,当计数器达到设定值时,并不会产生系统复位信号。如果定时器不够用的时候可以用该定时器,但是定时的时间只有4种选择。

看门狗模式

示例程序:WDT为看门狗模式,时间间隔为1s,定时喂狗,如果没有喂狗,则系统不断复位,LED灯每隔1s亮灭一次,无需第87行延时程序,因为看门狗的时间间隔设定为1s,LED刚好亮1s。

 1 /******************************************************************************
 2 *文 件 名:WDT.c
 3 *作    者:陈照
 4 *时    间:2015-06-01
 5 *版    本:1.0
 6 *描    述:看门狗程序
 7 ******************************************************************************/
 8 #include <iocc2541.h>
 9
10 #define LED1 P1_0
11
12 /******************************************************************************
13 *函 数 名:Delay1ms
14 *功    能:延时1ms
15 *入口参数:uiDelay,延时参数,值越大,延时越长
16 *出口参数:无
17 ******************************************************************************/
18 void Delay1ms(unsigned int uiDelay)
19 {
20   unsigned int i,j;
21   for(i = 0; i < uiDelay; i++)
22   {
23     for(j = 0;j < 1322; j++);
24   }
25 }
26
27 /****************************************************************
28 *函 数 名:InitClock
29 *功    能:系统时钟初始化
30 *入口参数:无
31 *出口参数:无
32 *****************************************************************/
33 void InitClock(void)
34 {
35   CLKCONCMD &= ~(1 << 6);       //选择32MHz晶振
36   while(CLKCONSTA & (1 << 6));  //等待时钟稳定
37   CLKCONCMD &= ~0x47;           //系统时钟和定时器时钟都是32M
38 }
39
40 /******************************************************************************
41 *函 数 名:InitLED
42 *功    能:LED灯初始化
43 *入口参数:无
44 *出口参数:无
45 ******************************************************************************/
46 void InitLED(void)
47 {
48   P1SEL &= ~0x01;      //P1.0设置为通用I/O口
49   P1DIR |=  0x01;      //P1.0设置为输出
50 }
51
52 /******************************************************************************
53 *函 数 名:Init_Watchdog
54 *功    能:看门狗初始化
55 *入口参数:无
56 *出口参数:无
57 ******************************************************************************/
58 void Init_Watchdog(void)
59 {
60   WDCTL = 0x00;  //打开IDLE 才能设置看门狗
61   WDCTL |= 0x08; //定时器间隔选择,间隔一秒,设定为看门狗模式
62 }
63
64 /******************************************************************************
65 *函 数 名:FeetDog
66 *功    能:喂狗,计数器清0
67 *入口参数:无
68 *出口参数:无
69 ******************************************************************************/
70 void FeetDog(void)
71 {
72   WDCTL = 0xa0;   //清除定时器。当0xA 跟随0x5 写到这些位,定时器被清除
73   WDCTL = 0x50;
74   LED1 = 1;      //系统不复位LED1 灯长亮
75 }
76
77 /******************************************************************************
78 *程序入口函数
79 ******************************************************************************/
80 int main(void)
81 {
82   InitClock();               //时钟初始化,32MHz
83   InitLED();                 //LED初始化
84   LED1 = 0;                  //熄灭LED1
85   Delay1ms(1000);
86   LED1 = 1;                  //点亮LED1
87   //Delay1ms(1000);
88   Init_Watchdog();           //看门狗初始化
89
90   while(1)
91   {
92      FeetDog();              //喂狗程序
93                               //注释掉次子函数,系统不断复位,LED1闪烁
94   }
95 }

 

计时器模式

示例:WDT处于计时器模式,中断方式,LED灯闪烁,0.25s状态改变一次

 1 /******************************************************************************
 2 *文 件 名:WDT.c
 3 *作    者:陈照
 4 *时    间:2015-06-01
 5 *版    本:1.0
 6 *描    述:WDT计时器模式
 7 ******************************************************************************/
 8 #include <iocc2541.h>
 9
10 typedef unsigned char uchar;
11 typedef unsigned int  uint;
12
13 #define LED1 P1_0
14
15 /******************************************************************************
16 *函 数 名:Delay1ms
17 *功    能:延时1ms
18 *入口参数:uiDelay,延时参数,值越大,延时越长
19 *出口参数:无
20 ******************************************************************************/
21 void Delay1ms(unsigned int uiDelay)
22 {
23   unsigned int i,j;
24   for(i = 0; i < uiDelay; i++)
25   {
26     for(j = 0;j < 1322; j++);
27   }
28 }
29
30 /****************************************************************
31 *函 数 名:InitClock
32 *功    能:系统时钟初始化
33 *入口参数:无
34 *出口参数:无
35 *****************************************************************/
36 void InitClock(void)
37 {
38   CLKCONCMD &= ~(1 << 6);       //选择32MHz晶振
39   while(CLKCONSTA & (1 << 6));  //等待时钟稳定
40   CLKCONCMD &= ~0x47;           //系统时钟和定时器时钟都是32M
41 }
42
43 /******************************************************************************
44 *函 数 名:InitLED
45 *功    能:LED灯初始化
46 *入口参数:mode,mode为1则点亮所有LED,mode为0则熄灭所有LED
47 *出口参数:无
48 ******************************************************************************/
49 void InitLED(uchar mode)
50 {
51   P1SEL &= ~0x01;      //P1.0设置为通用I/O口
52   P1DIR |=  0x01;      //P1.0设置为输出
53   LED1 = mode;         //LED灯亮熄控制
54 }
55
56 /******************************************************************************
57 *函 数 名:Init_Watchdog
58 *功    能:看门狗初始化
59 *入口参数:无
60 *出口参数:无
61 ******************************************************************************/
62 void Init_Watchdog(void)
63 {
64   WDCTL = 0x00;  //打开IDLE 才能设置计时器间隔时间
65   WDCTL |= 0x0d; //设定为计时器模式,定时器间隔为0.25秒
66 }
67
68 /******************************************************************************
69 *函 数 名:WDT_ISR
70 *功    能:WDT计时器模式中断服务程序
71 *入口参数:无
72 *出口参数:无
73 ******************************************************************************/
74 #pragma vector = WDT_VECTOR
75 __interrupt void WDT_ISR(void)
76 {
77   WDTIF = 0;      //看门狗中断清除
78   LED1 = ~LED1;   //定时时间到,LED状态翻转
79 }
80
81 /******************************************************************************
82 *程序入口函数
83 ******************************************************************************/
84 int main(void)
85 {
86   InitClock();               //时钟初始化,32MHz
87   InitLED(0);                //LED初始化,熄灭LED1
88   IEN2 |= 0x20;              //看门狗中断使能
89   EA = 1;                    //开总中断
90   Init_Watchdog();           //看门狗初始化
91
92   while(1)
93   {
94   };
95 }

拓展问题:CC2541在睡眠模式下,看门狗如何工作。初步认识为看门狗继续工作,计数器一直计数,有待后续验证!

时间: 2024-10-08 17:00:55

CC2541蓝牙学习——看门狗的相关文章

CC2541蓝牙学习——外设I/O

学习目标:I/O口的配置,掌握I/O外设功能及位置分布,寄存器“PERCFG”.“P2SEL”和“P2DIR”. 前面CC2541蓝牙学习——I/O口介绍过CC2541有21个I/O引脚,这些引脚可以作为通用I/O引脚,同时通过独立编程还可以作为外设I/O引脚用作ADC.串口.定时器和调试接口.当设置为外设I/O时,需要将对应的寄存器位PxSEL置1,每个外设单元对应两组可以选择的I/O引脚,即“外设位置1”和“外设位置2”,如下表所示. 从表中我们可以看出整个P0口都可作为ADC使用,因此可以

CC2541蓝牙学习——通用I/O口中断

学习目标:掌握中断使能寄存器IEN0.IEN1.IEN2,中断标志寄存器PxIFG.IRCON.IRCON2,端口中断触发沿控制寄存器PICTL CC2541有18个中断源,每个中断源都可以产生中断请求,这18个中断源如下 中断请求通过SFR寄存器IEN0.IEN1.IEN2使能或禁止,定义如下: 其中IEN0和IEN1可以位寻址,寄存器IEN2不可以位寻址 EA:1开总中断 IEN1.P0IE:P0端口中断使能 IEN2.P1IE:P1端口中断使能 IEN2.P2IE:P2端口中断使能 IEN

CC2541蓝牙学习——定时器1自由运行模式

学习目标:定时器1的自由运行模式 CC2541有4个定时器,分别实现不同的功能,定时器1是一个独立的16位定时器,支持典型的定时/计数功能,比如输入捕获,输出比较和PWM功能.定时器1有5个独立的捕获/比较通道,每个通道定时器使用一个I/O引脚. 定时器1的功能如下: 五个捕获/比较通道 上升沿.下降沿或任何的边沿输入捕获 设置.清除或切换输出比较 自由运行.模或正技术/倒技术操作 可被1.8.32.128整除的时钟分频器 在每个捕获/比较和最终计数上生成中断请求 DMA触发功能 定时器包括一个

CC2541蓝牙学习——时钟设置

CC2541有四个振荡器,分别是: 32MHz外部晶振 16MHz内部RC振荡器 32kHz外部晶振 32kHz内部RC振荡器 由此可以看出,CC2541内部自带了振荡器,也就是说即使外部电路不接振荡器,CC2541也可以工作,答案是肯定的,但是作为无线RF收发,只能使用外部32MHz晶振,除非准备将CC2541当做一个普通的增强型51单片机来用,否者32MHz外部晶振是必不可少的,那么这4个晶振有什么区别和用途呢? 32MHz的外部晶振有两个作用:为内部时钟提供时钟源和用于RF收发器 16MH

CC2541蓝牙学习——ADC

CC2541的ADC支持多达14位的模拟数字转换与高达12位的有效位数.它包括一个模拟多路转换器,具有多达8个各自可独立配置的通道,一个参考电压发生器.转换结果通过DMA写入存储器.还具有若干运行模式. ADC主要特性如下: 可选的抽取率,设置了7~12位的分辨率: 8个独立输入通道,可接受单端或差分信号: 参考电压可选为内部,外部单端,外部差分,或AVDD5: 产生中断请求: 转换结束时的DMA触发: 温度传感器输入: 电池测量功能. 图1 P0引脚上的信号可以作为ADC输入来使用.在下面,这

CC2541蓝牙学习——定时器1的捕获/比较功能

CC2541定时器1有5个捕获/比较通道,首先介绍什么是捕获和比较功能. 捕获通道: 设置的捕获开始的时候,CPU会将计数寄存器的值复制到捕获比较寄存器中并开始计数,当再次捕捉到电平变化时,这时 计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获.下降沿捕获.或者上升沿下降沿 都捕获.捕获通道可以用来测量信号的频率周期或者波形的宽度,捕获通道类似于秒表的功能. 比较通道: 这里有两个单元:一个计数器单元和一个比较单元,比较单元就是个双缓冲寄存器,比较单元的值是可以根据不

CC2541蓝牙学习——定时器3和定时器4

定时器3和定时器4与定时器1功能类似,都有三种模式:自由运行模式.模模式.正计数/倒计数模式,都有输入捕获和输出比较功能,不同的是定时器3和定时器4是8位计数器,而定时器1是16位的,另外定时器3和定时器4只有2个通道,定时器多了一个模式:倒计数模式.由于定时器3和定时器4相似,下面以定时器3为例说明. 定时器3和定时器4是两个8位定时器,每个定时器有两个独立的捕获/比较通道,每一通道使用一个I/O引脚. 定时器3/4有以下特点: 两个捕获/比较通道: 设置,清除或切换输出比较: 每时钟可以被以

zigbee学习之路(十一):看门狗

一.前言 今天,我们要通过实验学习和认识一下看门狗的使用,看门狗是为了防止防止程序跑飞的,通过不断的喂狗,使看门狗能持续监管程序的运行状态,当程序跑飞时,能及时把程序拽回来. 二.原理与分析 在CPU 可能受到一个软件颠覆的情况下,看门狗定时器(WDT)用作一个恢复的方法.当软件在选定时间间隔内不能清除WDT 时,WDT 必须就复位系统.看门狗可用于受到电气噪音.电源故障.静电放电等影响的应用,或需要高可靠性的环境.如果一个应用不需要看门狗功能,可以配置看门狗定时器为一个间隔定时器,这样可以用于

5、CC2541芯片中级教程-OSAL操作系统(PWM+看门狗)

本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 中级教程-OSAL操作系统(OSAL系统解基本套路) 中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~ 中级教程-OSAL操作系统(ADC-光敏电阻) OSAL操作系统-实验16 串口波特率扩展 OSAL操作系统-实验1