最新动态

工业物联网通讯专家!
认真做好每一件事,设计简单、可靠、价格合理的产品!

AVR单片机 看门狗范例 GCCAVR WDR 复位检测和控制看门狗

/***********************************************
****      AVR  复位检测和控制看门狗的范例       ***
****                                           ***
**** 作者:  HJJourAVR                        ***
**** 编译器:WINAVR20050214                   ***
****                                         ***
****      www.OurAVR.com     2005.9.28           ***
***********************************************/
/*
本程序简单的示范了AVRATMEGA16的复位检测和控制看门狗
        系统控制和复位
        复位来源的检测
            JTAG复位指示
            看门狗复位指示
            BOD复位指示
            RESET引脚复位指示
            上电复位指示
        看门狗的控制
 
出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器。
熔丝位设置
1 使能BOD功能 BODEN=0 
2 选择BOD电平 BODLEVEL=1  2.7V(VCC=3V)  (可选)
             BODLEVEL=0  4.0V(VCC=5V)  (可选)
*/

#include <avr/io.h>
#include <avr/delay.h>
//时钟定为内部RC 1MHz,F_CPU=1000000 也可以采用其他时钟
#include <avr/wdt.h>
/*
wdt.h里面
看门狗溢出时间常量定义
    #define WDTO_15MS   0
    #define WDTO_30MS   1
    #define WDTO_60MS   2
    #define WDTO_120MS  3
    #define WDTO_250MS  4
    #define WDTO_500MS  5
    #define WDTO_1S     6
    #define WDTO_2S     7
    下面的4S/8S定义只能用于 ATtiny2313, ATmega48, ATmega88 and the ATmega168.
    #define WDTO_4S     8
    #define WDTO_8S     9
看门狗操作函数
    wdt_disable()
    关闭看门狗
    wdt_enable(timeout)
    使能看门狗及溢出时间设定
    wdt_reset()
    复位看门狗(喂狗)
*/
//管脚定义

#define  WDT_EN        7    //PA7 看门狗的喂狗控制引脚
                        // 高电平,不喂狗
                        // 低电平,喂狗

#define  LED_JT        4    //PA4 JTAG复位指示
#define  LED_WD        3    //PA3 看门狗复位指示
#define  LED_BO        2    //PA2 BOD复位指示
#define  LED_EXT    1    //PA1 RESET引脚复位指示
#define  LED_PO        0    //PA0 上电复位指示
//以上信号皆为低电平有效

int main(void)
{
    unsigned char CPU_STATUS;
    unsigned char i;
    //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
    PORTB =0xFF;                                    //不用的管脚使能内部上拉电阻。
    PORTC =0xFF;
    PORTD =0xFF;
    PORTA =0xFF;
    DDRA  =(1<<LED_JT)|(1<<LED_WD)|(1<<LED_BO)|(1<<LED_EXT)|(1<<LED_PO);    //输出驱动LED

    CPU_STATUS =MCUCSR;            //读取MCU控制和状态寄存器
    //可以在JTAG调试时直接观察 MCUCSR的状态。
    CPU_STATUS&=0x1F;
    switch (CPU_STATUS)
    {
    case (1<<JTRF):            //JTAG引起的复位?
        PORTA&=~(1<<LED_JT);
        break;
    case (1<<WDRF):            //看门狗引起的复位?
        PORTA&=~(1<<LED_WD);
        break;
    case (1<<BORF):            //BOD引起的复位?
        PORTA&=~(1<<LED_BO);
        break;
    case (1<<EXTRF):        //RESET引脚引起的复位?
        PORTA&=~(1<<LED_EXT);
        break;
    case (1<<PORF):            //上电引起的复位?
        PORTA&=~(1<<LED_PO);
        break;
    default:                //多种复位同时发生?
        PORTA=~CPU_STATUS;   
        break;
    }
    MCUCSR=0x00;            //清除标志位
   
    for(i=0;i<200;i++)
        _delay_ms(10);        //延时2秒
    wdt_enable(WDTO_2S);    //使能看门狗,溢出时间为2秒左右
    while(1)
    {
        if (!(PINA&(1<<WDT_EN)))
            wdt_reset();        //如果PA7为低电平时,复位看门狗(喂狗)
    }
}


/*
程序运行效果
    如果PA7是高电平,不喂狗,则每2秒钟看门狗复位一次,LED_WD亮
    如果PA7是低电平,喂狗,则方便作如下实验
        第一次上电时,发生上电复位事件,LED_PO亮
        按下复位按键,发上外部复位事件,LED_EXT亮
        调节电源电压调到4.0V(或2.7V)以下,然后调回5.0V(3.0V),发生BOD复位事件,LED_BO亮
        在JTAG调试时,使用[reset]功能,发生JTAG复位事件,LED_JT亮
    注意:有时候会出现多种复位事件同时发生,例如:
        上电的同时按住复位按键,将会同时发生  上电复位事件和外部复位事件
*/

/*
系统控制和复位
    复位AVR 复位时所有的I/O 寄存器都被设置为初始值,程序从复位向量处开始执行。
    复位向量处的指令必须是绝对跳转JMP 指令,以使程序跳转到复位处理例程。
    如果程序永远不利用中断功能,中断向量可以由一般的程序代码所覆盖。
    这个处理方法同样适用于当复位向量位于应用程序区,中断向量位于Boot 区 — 或者反过来 — 的时候。
    复位源有效时I/O 端口立即复位为初始值。此时不要求任何时钟处于正常运行状态。
   
    所有的复位信号消失之后,芯片内部的一个延迟计数器被激活,将内部复位的时间延长。
    这种处理方式使得在MCU 正常工作之前有一定的时间让电源达到稳定的电平。
    延迟计数器的溢出时间通过熔丝位SUT 与CKSEL 设定。延迟时间的选择请参见 P23“ 时钟源” 。
   
复位源ATmega16 有5 个复位源:
    上电复位。电源电压低于上电复位门限 VPOT 时, MCU 复位。
    外部复位。引脚 RESET 上的低电平持续时间大于最小脉冲宽度时MCU 复位。
    看门狗复位。看门狗使能并且看门狗定时器溢出时复位发生。
    掉电检测复位。掉电检测复位功能使能,且电源电压低于掉电检测复位门限 VBOT 时MCU 即复位。
    JTAG AVR复位。复位寄存器为1时MCU复位。详见 P215“IEEE 1149.1 (JTAG) 边界扫描” 。
   
上电复位
    上电复位(POR) 脉冲由片内检测电路产生。
    无论何时VCC 低于检测电平POR 即发生。
    POR 电路可以用来触发启动复位,或者用来检测电源故障。
    POR电路保证器件在上电时复位。
    VCC 达到上电门限电压后触发延迟计数器。在计数器溢出之前器件一直保持为复位状态。
    当VCC 下降时,只要低于检测门限,RESET 信号立即生效。
 
外部复位
    外部复位由外加于RESET 引脚的低电平产生。
    当复位低电平持续时间大于最小脉冲宽度时即触发复位过程,即使此时并没有时钟信号在运行。
    当外加信号达到复位门限电压VRST( 上升沿) 时, tTOUT 延时周期开始。
    延时结束后MCU 即启动。
   
掉电检测
    ATmega16 具有片内BOD(Brown-out Detection) 电路,通过与固定的触发电平的对比来检测工作过程中VCC 的变化。
    此触发电平通过熔丝位BODLEVEL 来设定, 2.7V(BODLEVEL 未编程),4.0V (BODLEVEL 已编程)。
    BOD 的触发电平具有迟滞功能以消除电源尖峰的影响。
    这个迟滞功能可以解释为VBOT+ = VBOT + VHYST/2 以及VBOT- = VBOT- VHYST/2。
    BOD 电路的开关由熔丝位BODEN控制。
    当BOD使能后(BODEN被编程),一旦VCC下降到触发电平以下(VBOT-), BOD 复位立即被激发。
    当VCC 上升到触发电平以上时(VBOT+),延时计数器开始计数,一旦超过溢出时间tTOUT,MCU即恢复工作。
    如果VCC一直低于触发电平并保持tBOD时间, BOD电路将只检测电压跌落。
 
看门狗复位
    看门狗定时器溢出时将产生持续时间为1 个CK 周期的复位脉冲。
    在脉冲的下降沿,延时定时器开始对tTOUT 记数
   
MCU控制和状态寄存器-MCUCSR
    MCU 控制和状态寄存器提供了有关引起MCU 复位的复位源的信息
        Bit 4 – JTRF: JTAG 复位标志
            通过JTAG 指令AVR_RESET 可以使JTAG 复位寄存器置位,并引发MCU 复位,并使JTRF 置位。
            上电复位将使其清零,也可以通过写”0” 来清除。
        Bit 3 – WDRF: 看门狗复位标志
            看门狗复位发生时置位。
            上电复位将使其清零,也可以通过写”0” 来清除。
        Bit 2 – BORF: 掉电检测复位标志
            掉电检测复位发生时置位。
            上电复位将使其清零,也可以通过写”0” 来清除。
        Bit 1 – EXTRF: 外部复位标志
            外部复位发生时置位。
            上电复位将使其清零,也可以通过写”0” 来清除。
        Bit 0 – PORF: 上电复位标志
            上电复位发生时置位。
            只能通过写”0” 来清除。
    为了使用这些复位标志来识别复位条件,用户应该尽早读取此寄存器的数据,然后将其复位。
    如果在其他复位发生之前将此寄存器复位,则后续复位源可以通过检查复位标志来了解
   
看门狗定时器
    看门狗定时器由独立的1Mhz 片内振荡器驱动。这是VCC = 5V 时的典型值。
    通过设置看门狗定时器的预分频器可以调节看门狗复位的时间间隔。
    看门狗复位指令WDR 用来复位看门狗定时器。
    此外,禁止看门狗定时器或发生复位时定时器也被复位。
    复位时间有8 个选项。
    如果没有及时复位定时器,一旦时间超过复位周期, ATmega16 就复位,并执行复位向量指向的程序。
   
    为了防止无意之间禁止看门狗定时器,在看门狗禁用后必须跟一个特定的修改序列。
        1. 在同一个指令内对WDTOE 和WDE 写"1“,即使WDE 已经为"1“
        2. 在紧接的4 个时钟周期之内对WDE 写"0”
       
看门狗定时器控制寄存器-WDTCR
    Bit 4 – WDTOE: 看门狗修改使能
        清零WDE 时必须置位WDTOE,否则不能禁止看门狗。
        一旦置位,硬件将在紧接的4个时钟周期之后将其清零。请参考有关WDE 的说明来禁止看门狗。
    Bit 3 – WDE: 使能看门狗
        WDE为"1“ 时,看门狗使能,否则看门狗将被禁止。
        只有在WDTOE为"1“ 时WDE 才能清零。以下为关闭看门狗的步骤:
        1. 在同一个指令内对WDTOE 和WDE 写"1“,即使WDE 已经为"1“
        2. 在紧接的4 个时钟周期之内对WDE 写"0”
    Bits 2..0 – WDP2, WDP1, WDP0: 看门狗定时器预分频器2, 1 和 0
        WDP2、WDP1 和WDP0 决定看门狗定时器的预分频器
 
   WDP2 WDP1 WDP0   看门狗振荡器周期  VCC=3.0V时典型的溢出周期  VCC=5.0V时典型的溢出周期
    0    0     0      16K   (16384)       17.1ms                   16.3ms
    0    0     1      32K   (32768)       34.3ms                   32.5ms
    0    1     0      64K   (65536)       68.5ms                     65ms
    0    1     1     128K  (131072)       0.14s                    0.13s
    1    0     0     256K  (262144)       0.27s                    0.26s
    1    0     1     512K  (524288)       0.55s                    0.52s
    1    1     0    1024K (1048576)       1.1 s                    1.0 s
    1    1     1    2048K (2097152)       2.2 s                    2.1 s
   
   
掉电检测BOD的误解
        AVR自带的BOD(Brown-out Detection)电路,作用是在电压过低(低于设定值)时产生复位信号,防止CPU意外动作.
        对EEPROM的保护作用是当电压过低时保持RESET信号为低,防止CPU意外动作,错误修改了EEPROM的内容
       
        而我们所理解的掉电检测功能是指 具有预测功能的可以进行软件处理的功能。
        例如,用户想在电源掉电时把SRAM数据转存到EEPROM,可行的方法是
           外接一个在4.5V翻转的电压比较器(VCC=5.0V,BOD=2.7V),输出接到外部中断引脚(或其他中断)
           一但电压低于4.5V,马上触发中断,在中断服务程序中把数据写到EEPROM中保护起来
    注意: 写一个字节的EEPROM时间长达8mS,所以不能写入太多数据,电源滤波电容也要选大一些
*/


上一篇: 标准串口定义-9转25的串口线接法图
下一篇: 华为前高管讲述:华为为什么不上市

发表评论