89S51、89S52系列单片机自带有看门狗功能,片内数据区A6H寄存器具有看门狗功能,使用很简单:
#include<reg51.h>
...
sfr WDTRST = 0xA6
...
void main()
{
WDTRST=0x1E//初始化看门狗
WDTRST=0xE1//初始化看门狗
for()
{
WDTRST=0x1E//喂狗指令
WDTRST=0xE1//喂狗指令
}
}
可见,你只要在程序的大循环体内加一条喂狗指令就行。但这种看门狗功能有限,不是很可靠的,它依靠晶振工作,一旦晶振不起振,就无效了。
实践中多采用外部看门狗的方法,可以选用的芯片很多:MAX708、MAX813
、X25045.....具体编程就要看芯片的参考资料了。
例如:X25045是SPI总线的看门狗芯片,复位端和单片机复位端连接,SPI数据输入你可以选择合适的IO接口。
WREN0x06 设置写允许位
WRDI 0x04 复位写允许位
RDSR0x05 读状态寄存器
WRSR 0x01写状态寄存器
READ0x03/0x0b 读 *** 作时内部EEPROM页地址
WRITE 0x02/0x0a 写 *** 作时内部EEPROM页地址
#include <reg51.h>
sbit CS= P2^7
sbit SO= P2^6
sbit SCK= P2^5
sbit SI= P2^4
#define WREN 0x06 //
#define WRDI 0x04 //
#define RDSR 0x05 //
#define WRSR 0x01//
#define READ0 0x03 //
#define READ1 0x0b //
#define WRITE0 0x02 //
#define WRITE1 0x0a //
#define uchar unsigned char
uchar ReadByte() //read a byte from device
{
bit bData
uchar ucLoop
uchar ucData
for(ucLoop=0ucLoop<8ucLoop++)
{
SCK=1
SCK=0
bData=SO
ucData<<=1
if(bData)
{ ucData|=0x01}
}
return ucData
}
void WriteByte(uchar ucData)//write a byte to device
{
uchar ucLoop
for(ucLoop=0ucLoop<8ucLoop++)
{
if((ucData&0x80)==0)//the MSB send first
{SI=0}
else
{SI=1}
SCK=0
SCK=1
ucData<<=1
}
}
uchar ReadReg() //read register
{
uchar ucData
CS=0
WriteByte(RDSR)
ucData=ReadByte()
CS=1
return ucData
}
uchar WriteReg(uchar ucData) //write register
{
uchar ucTemp
ucTemp=ReadReg()
if((ucTemp&0x01)==1) //the device is busy
return 0
CS=0
WriteByte(WREN)//when write the WREN, the cs must have a high level
CS=1
CS=0
WriteByte(WRSR)
WriteByte(ucData)
CS=1
return 1
}
void WriteEpm(uchar cData,uchar cAddress,bit bRegion)
/* 写入一个字节,cData为写入的数,cAddress为写入地址,bRegion为页 */
{
while((ReadReg()&0x01)==1) //the device is busy
CS=0
WriteByte(WREN)//when write the wren , the cs must have a high level
CS=1
CS=0
if(bRegion==0)
{ WriteByte(WRITE0)} //write the page addr
else
{WriteByte(WRITE1)}
WriteByte(cAddress)
WriteByte(cData)
SCK=0 //
CS=1
}
uchar ReadEpm(uchar cAddress,bit bRegion)
/* 读入一个字节,cAddress为读入地址,bRegion为页 */
{
uchar cData
while((ReadReg()&0x01)==1)//the device is busy
CS=0
if(bRegion==0)
{WriteByte(READ0)}
else
{WriteByte(READ1)}
WriteByte(cAddress)
cData=ReadByte()
CS=1
return cData
}
main()
{
WriteReg(0x00)//set the watchdog time as 1.4s
CS=1
CS=0 //reset the watchdog
}
回复: xuzhimin9514
所有的89S系列都带狗,所有的80C系列都不带狗。
所以89S51 89S52都带狗,80C51、80C52都不带狗。
标题写错了,MAX232是常用的232驱动芯片,和MAX1232完全不搭界。MAX1232的看门狗复位信号取自ST信号的下降沿,要复位MAX1232的看门狗,需要把ST信号接到任意的CPU管脚,然后写程序在管脚上输出一个脉冲就可以了,程序很简单。
sbit wdt_clr = P1^0
void cleanWDT( void )
{
wdt_clr = 0
_nop()
_nop()
wdt_clr = 1
}
需要注意的就是在程序执行过程中,要严格的保证最小的调用间隔,比如每隔100ms就要调用一次cleanWDT,否则一旦超时,看门狗就会复位CPU。
对于裸奔的程序,最理想的看门狗是程序只在主循环中加一个喂狗,计算主循环执行一个循环的最长时间的1.5倍作为看门狗定时器的时间,这样只要程序超出了预计的时间未回到主循环,就会自动复位。这样的程序尽量不要让中断服务函数占用太多的处理器资源,将耗费处理器资源的工作放在程序的主循环中,可以更有效的利用看门狗。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)