IAR AVR 看门狗
- 格式:docx
- 大小:14.36 KB
- 文档页数:2
Proteus 环境下Avr I/O 电平反复变化(看门狗复位)
学习了一个月的avr 单片机了,从点亮一个二极管到通信部分,以前都是
直接上硬件,下载验证,昨天开始下载了Proteus 使用仿真,下载地址是verycd/topics/2733851/ 发现点亮一个简单的二极管都不成功,cvavr 下的程序如下:#include
void main()
{
DDRB=0XFF;
PORTB=0X00;
while(1);
}
然而就是这么简单的一个程序得到的仿真结果是:
一会高一会低,非常郁闷,学了这么长时间,居然让一个灯常亮都不行了于
是群里问可惜没人回答
终于,搜索中找到了以下是原文:
这个问题主要会出现在用CVAVR 来编译的程序中。
之前学AVR 有用到proteus 仿真,我用的是proteus7.4,拿一个ATMega16 出来,用AVR 编译出来的一些简单的程序,根本不能正常的运行,这把我搞
的相当的郁闷,后
来在仿真日志中发现原来是看门狗一直都开着,我又没喂狗,因此一直都把
处理器复位了,这回我更郁闷,我又没开看门狗,又没配置fuse,为什么自己
会开呢,搞了N 久后,发。
看门狗定时器用来防止程序因供电电源、空间电磁干扰或其它原因引起的强烈干扰噪声而跑飞的事故。
在很多单片机中都内置了看门狗,看门狗本身是一个定时器,当定时器溢出时即进行系统复位,因此需要在程序中对看门狗定时器进行清零,即常说的喂狗。
由于我用过AVR的单片机,和AVR的相比,MSP430的看门狗要灵活的多,首先默认看门狗是开着的,因此如果不使用看门狗的话要关闭,指令如下:WDTCTL = WDTPW + WDTHOLD如果打开看门狗则需要在程序中清零,指令如下:WDTCTL=WDTPW+WDTCNTCL从头文件的定义中可以看出主要有两种方式,一种就是当做普通的定时器使用,一种才是作为看门狗,另外就是时钟源可选,选择8M或者32K的晶振来获得不同的延时,通过上面可以看出看门狗定时器最大的时间可以到1S,在程序中可以灵活的利用看门狗定时器实现想要的功能。
下面介绍两个典型应用:1、在动态数码管显示中的应用,具体代码可以参考我之前的笔记,部分代码如下:WDTCTL = WDT_ADLY_1_9; // 设置内部看门狗工作在定时器模式,1.9ms中断一次//可以去看头文件中具体的配置,这里使用的手表晶振64分频计算可得是1.9msIE1 |= WDTIE; // 使能看门狗中断__interrupt void watchdog_timer(void){}这个程序主要是将看门狗定时器当做普通定时器使用,1.9ms刚好适合动态扫描间隔,在看门狗中断中对数码管进行动态扫描,这样使用相对于开一个定时器来说要有所方便。
因此在需要的定时与看门狗定时器的几个时间相同时可以考虑使用看门狗。
2、普通延时WDTCTL = WDT_ADLY_1000; //间隔定时器,定时1000ms//延时2sfor(i = 0; i< 3; i++){IFG1 &= ~WDTIFG;while(!(IFG1 & WDTIFG));IFG1 &= ~WDTIFG;}这个程序同样是将看门狗当普通定时器使用,在主程序中读取中断标志位,实现延时效果,上面的程序为什么是延时2S自己分析。
AVR的一点驯狗心得新的AVR 系列(例如,ATMEGA168 等)使用增强功能的看门狗(Enhanced Watchdog Timer),与原来的看门狗相比较,除了有相同复位的功能以外,还增加了中断的功能设计时。
使用看门狗的中断功能,可以实现从Power Down 状态唤醒CPU;另外同时能使中断和复位功能,可以在系统发生错误时,先进入中断状态,保存关键数据到EEPROM,然后在进行系统复位。
AVR 新的看门狗与旧狗(例如,ATMEGA16 等)比较,增加了新的功能的同时脾气也有了不少改变。
设计时要摸清它的脾气,以防被狗咬。
下面说明以ATMEGA16 和ATMEGA168 作一个简单比较为例,简要地说明一下注意要点: 看门狗定时器控制寄存器– WDTCR: Atmega16: Atmega168: 1.A1tmega168 由于具有中断功能,所以WDTCR 增加了WDIF 和WDIE 两个额外的bit 的功能; 2.增加了WDP3,溢出周期可以有长达8 秒; 3.新的看门狗在初始化时,WDT 的值不再一定是0。
只要MCUSR 寄存器上的WDRF 置位,WDT 也将被强制置位。
这时,如果WDE 要清零,必须要WDRF 先清零。
4.在设计时即使不用WDT,它也可能在无意中被能使,例如在runaway 指针和调电情况下。
因此即使不用WDT,在初始代码中一定要检查复位标志,如果WDT 系统复位发生要采取处理步骤。
最近重新设计一个项目,由原先使用的ATMEGA16 更新到ATMEGA168。
把原代码转换后,测试结果异常。
经过一天多的测试,才发现是新的看门狗惹的祸。
以前用ATMEGA16,在初始化后才开始喂狗,可是新的AVR 系列(例如ATMEGA168 等),系统复位发生时(除上电复位外) ,WDT可能继续运行,并使用最小溢出周期(大约15mS) ,造成了系统不断复位。
根据datasheet,在程序开始时的关狗后一切就恢复正常了: #include #include uint8_t mcusr_mirror; void get_mcusr(void) __attribute__((naked))。
关于AVR单片机的看门狗看门狗这个东西以前没接触过理解它费了一点周折。
使用它的复位MCU 的功能实现LED 的闪烁。
准备工作是设定WDT 的超时时间(如1s)首先使能看门狗(wdt_enable),然后喂狗(wdt_reset),再延时灯的闪烁时间(delay=0.5s),使灯亮(SET_LED);再用一个恰当的比较长的延时(delay>0.5s)饿死狗。
之后MCU 重启,如此往复。
(1)延时可以调用库函数,还可以使用定时器;(2)SET_LED; while(1) wdt_reset(); 表示不断喂狗,从而不让MCU 重启,使灯一直亮着。
程序中使用这些代码的用途待考证,可以给作者发email 嘿嘿~(3)软件看门狗和硬件看门狗。
软件看门狗可以用wdt_disable 来禁掉。
而硬件看门狗不能。
AVR 可以通过修改熔丝位来分别实现软硬看门狗。
(4)wdt_enable(timeout)的参数timeout 表示看门狗的超时时间,即timeout时间内不喂狗,狗就会叫,mcu 就会复位。
=================================================================================================#include#include#include#define uchar unsigned char#define uint unsigned int#define SET_LED PORTA&=0XFE //PA0 输出低电平,黄灯亮#define CLR_LED PORTA|=0X01//PA0 输出高电平,黄灯灭。
单片机看门狗(Watchdog)的工作原理及其应用2010年05月16日星期日 23:00在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环。
程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果。
所以,出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测单片机程序运行状态的芯片,俗称"看门狗"(watchdog)。
看门狗电路的应用,使单片机可以在无人状态下实现连续工作,其工作原理是:看门狗芯片和单片机的一个I/O引脚相连,该I/O引脚通过程序控制它定时地往看门狗的这个引脚上送入高电平(或低电平),这一程序语句是分散地放在单片机其他控制语句中间的,一旦单片机由于干扰造成程序跑飞后而陷入某一程序段进入死循环状态时,写看门狗引脚的程序便不能被执行。
这个时候,看门狗电路就会由于得不到单片机送来的信号。
便在它和单片机复位引脚相连的引脚上送出一个复位信号。
使单片机发生复位,即程序从程序存储器的起始位置开始执行,这样便实现了单片机的自动复位。
看门狗,又叫 watchdog timer,是一个定时器电路。
一般有一个输入,叫喂狗(kicking the dog or service the dog),一个输出到MCU的RST端,MCU 正常工作的时候,每隔一端时间输出一个信号到喂狗端,给 WDT 清零。
如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就会给出一个复位信号到MCU,是MCU复位,防止MCU死机。
看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
工作原理:在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。
所以,在使用有看门狗的芯片时要注意清看门狗。
MSP430单片机的看门狗使用方法
以MSP430F2274 为例。
其中汇编实现采用的是IAR 汇编,CCE 汇编实现稍作修改即可。
1. 看门狗有三种工作模式:停止模式,计时器模式,看门狗模式。
2. 其中后两种模式可以选择的时钟源有:SMCLK 和ACLK。
3. 在使用后两种模式时候要注意单片机所处的状态下看门狗能否工作,如单片机处在LPM3 时候只有ACLK 时钟,处在LPM4 下,没有时钟可以使用。
4. 看门狗模式的使用方法:当看门狗计数溢出时,程序复位。
在程序中开启看门狗,在计数溢出前清空看门狗,或重置看门狗,以使其重新计数。
若程序
跑飞,看门狗可能没有被清空或重置,就会溢,使程序复位。
5. 在MSP430F2274 中,看门狗模式下可以计时最长为1s,若需要以更长的时间复位,可采取的方法,使用其他计数器,计数满后执行((void (*)()) RESET_VECTOR)();或计数满后往看门狗控制寄存器写个错误值或执行一条无效命令:如((void (*)())0x170)();0x170 是外围模块的一个地址,不可能是一个函数地址,所以执行此句将使程序复位。
停止模式:关闭看门狗
C 语言实现:WDTCTL = WDTPW + WDTHOLD
汇编语言实现:mov.w #WDTPW+WDTHOLD,&WDTCTL
计时器模式:作为一个计时器使用,计数器满产生中断时执行看门狗中断函数。
C 语言实现:
主程序中:开启看门狗计时器,如:WDTCTL = WDT_MDLY_8;或WDTCTL = WDT_ADLY_250;等。
AVR看门狗
本文资料源于网络程序由Free_Bird整理共同进步
主要参考/apple_guet/article/details/6715070写的很细;AVR的看门狗是软狗,也是硬狗!如果熔丝位不设定,就是软狗,因为程序可
以关闭,也可以打开如果熔丝位设定了,就是硬狗,因为程序只可以清除,而无法打开或关闭!如果你的while(1)循环体内每循环一次的时间不超过看门狗的复位时间,只要喂狗一次就可以了。
程序如下:
/*-----------------------------------------main.c-----------------------------------------------*/
#include <iom32.h>
#include <intrinsics.h> //这个头文件包含了开关全局中断函数、延时函数、看门狗的清零函数
#include "Watch_DoG.h"
void delay_ms(unsigned int x) //16M晶振下Xms延时函数
{
unsigned int i = 0,j = 0;
for(i = 0; i < x; i++)
{
for(j = 0; j < 2282; j++);
}
}
void Device_Init(void)
{
WDT_Init();
}
void main()
{
Device_Init();
__watchdog_reset();//看门狗清零(喂狗)
while(1)
{
delay_ms(1500); //仿真时:调节此处即调节喂狗时间,可验证看门狗是否看家__watchdog_reset();
}
}
/*-----------------------------------------Watch_DoG.c-----------------------------------------------*/ #include "Watch_DoG.h"
void WDT_off(void)
{
__disable_interrupt();
__watchdog_reset();//this prevents a timout on enabling
/* 置位WDTOE 和WDE */
WDTCR = (1<<WDTOE) | (1<<WDE);
/* 关闭WDT */
WDTCR = 0x00;
__enable_interrupt();
}
void WDT_Init(void)//开启看门狗,溢出时间:2.1S
{
__disable_interrupt();
__watchdog_reset();//this prevents a timout on enabling
/* 置位WDTOE 和WDE */
WDTCR = 0x1f; //特别注意这一条不是ICC生成的,是后来加上的,很重要/* 打开WDT */
WDTCR = 0x0f; //WATCHDOG ENABLED - dont forget to issue WDRs
__enable_interrupt();
}
/*-----------------------------------------Watch_DoG.h-----------------------------------------------*/ #ifndef _WATCH_DOG_
#define _WATCH_DOG_
#include <iom32.h>
#include <intrinsics.h>
void WDT_off(void); //关闭看门狗
void WDT_Init(void);//开启看门狗,溢出时间:2.1S
#endif。