5893|9

53

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

Hanker TI M4 开发板开发应用教程第三章第五节:看门狗 [复制链接]

第四章Hanker TM4C123 外设应用
4.5 TM4C123 的看门狗
4.51 原理分析:
在实际的MCU 应用系统中,由于常常会受到来自外界的某些干扰,有可能(对规范的设计概率极小)造成程序的跑飞而陷入死循环,从而导致整个系统的陷入停滞状态并且不会自动恢复到可控的工作状态。所以出于对MCU 运行的安全考虑,便引入了一种专门的复位监控电路,俗称看门狗(WatchDog)。

看门狗电路所起的作用是一旦MCU 运行出现故障,就强制对MCU 进行硬件复位,使整个系统重新处于可控状态(要想精确恢复到故障之前的运行状态从技术上讲难度大成本高,而复位是最简单且可靠的处理手段)。

现在大部分MCU 都集成了看门狗的功能。在TM4C123 系列CORTEX M4 里集成有硬件的看门狗定时器模块。看门狗定时器在到达超时值时会产生不可屏蔽的中断或复位。当系统由于软件错误而无法响应或外部器件不能以期望的方式响应时,使用看门狗定时器可重新获得控制。

最实用的看门狗就是用在:当系统跑飞后,产生一个中断复位,使系统重新复位运行。为了防止在程序跑飞时意外修改看门狗模块的配置,特意引入了一个锁定寄存器。在配置看门狗定时器之后,只要写入锁定寄存器一个不是0x1ACCE551 的任何数值,看门狗模块的所有配置都会被锁定,拒绝软件修改。因此以后要修改看门狗模块的配置,包括清除中断状态(即喂狗操作),都必须要首先解锁。解锁方法是向锁定寄存器写入数值0x1ACCE551。这是个很特别的数字,程序跑飞本身已是罕见的事件,而在一旦发生此罕见事件的情况下又恰好会把这个特别的数字写入锁定寄存器更是不可能。因此可以保证中断复位的产生。

但是,正常情况下,程序跑飞是小概率事件,大家如果遇到程序跑飞的情况,应该首先考虑是否是软件编程错误或者硬件的设计错误,这才是跑飞情况下的大概率事件。

4.52 硬件设计:
如图所示:我们采用QF-TM4C123 开发板板上的1 个LED 作为实验用。

4.53 软件设计:.
软件设计时首先都是设置外设,看门狗设置需要实用下面几个语句,看门狗可以在第一次超时产生一个中断,第二次超时喂狗。当32 位计数器在使能后倒计数到0 状态时,看门狗定时器模块产生第一个超时信号,并产生中断触发信号。在发生了第一个超时事件后,32 位计数器自动重装并重新递减计数。如果没有清除第一个超时中断状态,则当计数器再次递减到0 时,且复位功能已使能,则看门狗定时器会向处理器发出复位信号。

我们下面来编写这样一个功能函数来验证看门狗的功效:
程序正常运行时,可以设置任何运行状态,比如串口输出,这里没有设置,并喂狗。当按键按下时,触发GPIO 按键中断,模拟出现故障,处理器进入死循环,看门狗定时器产生第一个超时信号,进入看门狗中断服务程序,LED2 不断闪烁,直到看门狗定时器产生第二次超时信号,导致系统复位,系统再次正常运行,正常任何恢复.

那么首先我们建立工程项目如下图所示:

其中lcd_320X240_ili932x.c 文件为液晶触摸屏的驱动文件,如果不使用液晶屏的话
就可以不加入,要使用的时候还必须结合图形驱动库文件一起使用。

Main 函数就是我们用户编写的代码,由于我们使用了库函数编写,所以要加入外设驱动库封装.lib 文件,这里面封装了所有的外设驱动,下面我们在下面文件夹找到
driverlib/watchdog.c 查找下面几个要使用的函数:

1.WatchdogEnable( )
功能
使能看门狗定时器
原型
  1. void WatchdogEnable(unsigned long ulBase)
复制代码
参数
ulBase:看门狗定时器模块的基址,取值WATCHDOG_BASE
返回


2.WatchdogReloadSet( )
功能
设置看门狗定时器的重装值
原型
  1. void WatchdogReloadSet(unsigned long ulBase, unsigned long ulLoadVal)
复制代码
参数
ulBase:看门狗定时器模块的基址,取值WATCHDOG_BASE
ulLoadVal:32 位装载值
返回


3.WatchdogIntEnable( )
功能
使能看门狗定时器中断
原型
  1. void WatchdogIntEnable(unsigned long ulBase)
复制代码
参数
ulBase:看门狗定时器模块的基址,取值WATCHDOG_BASE
返回


4.WatchdogLock( )
功能
使能看门狗定时器的锁定机制
原型
  1. void WatchdogLock(unsigned long ulBase)
复制代码
参数
ulBase:看门狗定时器模块的基址,取值WATCHDOG_BASE
返回

更多函数请查看外设驱动函数PDF

程序基本设置步骤可以归纳如下:
1. 使能看门狗中断
2.设置看门狗定时器的重载值
3.使能看门狗定时器的复位功能
4.使能看门狗定时器的中断
5.使能看门狗定时器的锁定机制
上面五步设置成功后就可以开始运行看门狗了。程序如下:
这里面需要详细介绍下:
  1. 01. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. 02. //-----------------------------------------------------------------------------
  3. 03. /
  4. 04. //-----------------------------------------------------------------------------
  5. 05. // 文件名: watchdog.c
  6. 06. // 作者: 青风
  7. 07. // ARM 内核: Cortex-M4
  8. 08. // 使用芯片: LM4F232H5QD
  9. 09. // 开发环境: KEIL
  10. 10. // 版本记录: V1.00 2012-1-26 14:30
  11. 11. // 功能说明:
  12. 12. //函数功能说明:
  13. 13. //-----------------------------------------------------------------------------
  14. 14. //*****************************************************************************
  15. 15. #include "inc/hw_types.h" //定义常用的宏
  16. 16. #include "inc/hw_memmap.h" //定义功能存储映射
  17. 17. #include "inc/hw_ints.h"
  18. 18. #include "grlib/grlib.h"
  19. 19. #include "driverlib/debug.h"
  20. 20. #include "drivers/lcd_320x240_ili932x.h"
  21. 21. #include "driverlib/sysctl.h"
  22. 22. #include "driverlib/gpio.h"
  23. 23. #include "driverlib/pin_map.h"
  24. 24. #include "driverlib/fpu.h"
  25. 25. #include "driverlib/interrupt.h" //定义中断分配数
  26. 26. #include "driverlib/systick.h"
  27. 27. #include "driverlib/watchdog.h"
  28. 28.
  29. 29. #define KEY GPIO_PIN_0 // 定义KEY PG0
  30. 30. #define LED2 GPIO_PIN_7 // 定义LED2 PC7
  31. 31. //-----------------------------------------------------------------------------
  32. 32. // 子函数功能说明: 使程序进入死循环
  33. 33. //-----------------------------------------------------------------------------
  34. 34. void INT_PortG(void)
  35. 35. {
  36. 36. while(1);
  37. 37. }
  38. 38. //-----------------------------------------------------------------------------
  39. 39. // 子函数功能说明: 简单的延时函数
  40. 40. //-----------------------------------------------------------------------------
  41. 41. void delay (unsigned long ulTime)
  42. 42. {
  43. 43. while (--ulTime != 0);
  44. 44. }
  45. 45. //-----------------------------------------------------------------------------
  46. 46. // 子函数功能说明: 反转LED 灯
  47. 47. //-----------------------------------------------------------------------------
  48. 48. void Watchdog_Timer (void)
  49. 49. {
  50. 50. while(1){
  51. 51. GPIOPinWrite(GPIO_PORTC_BASE,LED2,~GPIOPinRead(GPIO_PORTC_BASE,LED2));
  52. 52. delay(100000);
  53. 53. }
  54. 54. }
  55. 55. //-----------------------------------------------------------------------------
  56. 56. // 主函数
  57. 57. //-----------------------------------------------------------------------------
  58. 58. int main (void)
  59. 59. {
  60. 60. tContext sContext;
  61. 61. tRectangle sRect;
  62. 62. FPUEnable(); //FPU 使能
  63. 63. FPULazyStackingEnable(); //使能FPU 堆栈
  64. 64. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_XTAL_16MHZ |
  65. 65. SYSCTL_OSC_MAIN); //系统时钟设置
  66. 66. lcd_ili932x_init(); //初始化LCD 驱动
  67. 67. GrContextInit(&sContext, &g_sLcdDisplay);//初始化图形库
  68. 68. lcd_backlight_on();
  69. 69. lcd_ili932x_flush(&sContext);
  70. 70. sRect.sXMin = 0;
  71. 71. sRect.sYMin = 0;
  72. 72. sRect.sXMax = GrContextDpyWidthGet(&sContext) - 1;
  73. 73. sRect.sYMax = 23;
  74. 74. GrContextForegroundSet(&sContext, ClrDarkBlue);
  75. 75. GrRectFill(&sContext, &sRect); // 填充蓝色方块
  76. 76. GrContextForegroundSet(&sContext, ClrWhite);
  77. 77. GrRectDraw(&sContext, &sRect); // 加白色框框
  78. 78. GrContextFontSet(&sContext, &g_sFontCm20);
  79. 79. GrStringDrawCentered(&sContext, "watchdog", -1,
  80. 80. GrContextDpyWidthGet(&sContext) / 2, 10, 0); // 显示KEY 中断实验标志
  81. 81. GrContextFontSet(&sContext, &g_sFontCm30);
  82. 82. GrStringDrawCentered(&sContext, "watchdog START!", -1,
  83. 83. GrContextDpyWidthGet(&sContext) / 2,
  84. 84. ((GrContextDpyHeightGet(&sContext) - 20) / 2),
  85. 85. 0);
  86. 86. // 显示提示实验开始
  87. 87. SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG); // 使能看门狗定时器
  88. 88. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); // 使能GPIO G 口
  89. 89. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); // 使能GPIO C 口
  90. 90. GPIOPadConfigSet(GPIO_PORTG_BASE, KEY, GPIO_STRENGTH_2MA,
  91. GPIO_PIN_TYPE_STD_WPU);
  92. 91. GPIODirModeSet(GPIO_PORTG_BASE, KEY, GPIO_DIR_MODE_IN); /
  93. 92. / 设置连接KEY 为输入
  94. 93. GPIOPadConfigSet(GPIO_PORTC_BASE, LED2, GPIO_STRENGTH_2MA,
  95. 94. GPIO_PIN_TYPE_STD_WPU);
  96. 95. GPIODirModeSet(GPIO_PORTC_BASE, LED2, GPIO_DIR_MODE_OUT);
  97. 96. // 设置连接LED2 为输出
  98. 97. IntPrioritySet(INT_WATCHDOG,0x00); // 设置看门狗中断优先级为高
  99. 98. IntPrioritySet(INT_GPIOG,0x40); // 设置GPIO F 口的中断优先级为低
  100. 99. GPIOIntTypeSet(GPIO_PORTG_BASE, KEY, GPIO_LOW_LEVEL);
  101. 100. // 设置KEY 中断触发为IO 口下降沿触发发
  102. 101. GPIOPinIntEnable(GPIO_PORTG_BASE, KEY); //使能KEY 中断
  103. 102. IntEnable(INT_GPIOG); // 使能GPIO F 口中断
  104. 103. IntEnable(INT_WATCHDOG); // 使能看门狗中断
  105. 104. WatchdogReloadSet(WATCHDOG_BASE, 6000000);
  106. 105. // 设置看门狗定时器的重载值
  107. 106. WatchdogResetEnable(WATCHDOG_BASE);
  108. 107. // 使能看门狗定时器的复位功能
  109. 108. WatchdogEnable(WATCHDOG_BASE); // 使能看门狗定时器的中断
  110. 109. WatchdogLock(WATCHDOG_BASE);
  111. 110. // 使能看门狗定时器的锁定机制
  112. 111. while (1){
  113. 112. delay(500000); // 延时
  114. 113. WatchdogIntClear(WATCHDOG_BASE);//清除看门狗的中断标志、"喂狗"
  115. 114. }
  116. 115.
  117. 116.}
  118. 117.
复制代码
本代码用了两个中断,一个是中断模拟故障,一个是看门狗中断,因此需要在startup.s 文件中进行声明:



下载成功后出现下面现象:当按键按下时,触发GPIO 按键中断,模拟出现故障,处理器进入死循环,看门狗定时器产生第一个超时信号,进入看门狗中断服务程序,LED2不断闪烁,直到看门狗定时器产生第二次超时信号,导致系统复位,系统再次正常运行,正常任何恢复

最新回复

为什么我移植到TIVAWARE上不能运行,提示WATCHDOG_BASE没定义,该加的头文件和驱动库我都添加了啊  详情 回复 发表于 2016-3-27 13:06
 
点赞 关注(2)

回复
举报

484

帖子

12

TA的资源

纯净的硅(高级)

推荐
 
原帖由 vvv9876 于 2013-9-24 21:36 发表
在TivaWare可以运行的

呵呵,我认真看了你贴的程序,是可以在TivaWare上运行的,不过,你只是把stellariesware程序迁移到了Tiva上
如果仅作为一个开发板的测试实验是可以的,也是比较好的做法。

[ 本帖最后由 平湖秋月 于 2013-9-24 22:49 编辑 ]
 
 

回复

484

帖子

12

TA的资源

纯净的硅(高级)

沙发
 

回复 楼主vvv9876 的帖子

写的很不错,赞一个。

[ 本帖最后由 平湖秋月 于 2013-9-24 20:28 编辑 ]
 
 
 

回复

2002

帖子

24

TA的资源

五彩晶圆(高级)

板凳
 
我觉得学习还是多查查寄存器的好,会更熟悉更透彻
 
 
 

回复

53

帖子

0

TA的资源

纯净的硅(中级)

4
 

回复 沙发平湖秋月 的帖子

差异就是少 定义几个寄存器而已,基本一样
 
 
 

回复

484

帖子

12

TA的资源

纯净的硅(高级)

5
 

回复 4楼vvv9876 的帖子

你可以把你原来写的那些程序稍微改改,就可以在TivaWare上运行了,
我原来做的那些在M4上的程序也在改
 
 
 

回复

53

帖子

0

TA的资源

纯净的硅(中级)

6
 
在TivaWare可以运行的
 
 
 

回复

53

帖子

0

TA的资源

纯净的硅(中级)

8
 
平湖秋月 发表于 2013-9-24 22:34
呵呵,我认真看了你贴的程序,是可以在TivaWare上运行的,不过,你只是把stellariesware程序迁移到了Tiva ...

对寄存器底层定义清楚么?TI的底层定义几乎没变,我可以告诉你,他们只是把库函数简化了一下,不要认为TI就有多牛,之前的库一样用,项目做的多这个根本不是问题,不知道为什么很多学生朋友总是纠结着用哪个的库,实在不想用库的朋友建议直接上寄存器,只要你有这个能力。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(中级)

9
 
平湖秋月 发表于 2013-9-24 22:34
呵呵,我认真看了你贴的程序,是可以在TivaWare上运行的,不过,你只是把stellariesware程序迁移到了Tiva ...

是的
能移植就好在这里
减轻了工作量
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(中级)

10
 
为什么我移植到TIVAWARE上不能运行,提示WATCHDOG_BASE没定义,该加的头文件和驱动库我都添加了啊
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表