这个是一个硬件看门狗和用at24c02保存掉电数据的程序,希望对大家有所帮助已经测试通过的.
#include<reg51.h>
#include "IIC.h"
#define ADDR 0x20 //存储地址
sbit led1=P2^7; //掉电现象
sbit led2=P2^6; //看门狗复位现象
sbit WDI=P2^5; //喂狗位
uint watch=100; //喂狗次数
uchar wbuf,rbuf; //写数据读数据变量
bit flag=0; //掉电标志
/*******外部中断,下降沿触发**************/
void intinit()
{
EA=1;
EX0=1;
IT0=1;
}
/****************掉电中断*****************/
void int0() interrupt 0 //掉电数据保护,灯亮了表示进入中断一次
{
led1=0;
wbuf=0x01;
write1char(wbuf,ADDR); //掉电标志
wbuf=PSW;
write1char(wbuf,ADDR+1); //数据保护
wbuf=ACC;
write1char(wbuf,ADDR+2);
led1=1;
}
/*************watch dog处理******************/
void feeddog()
{
if(watch>0)
{
WDI=~WDI; //喂狗;
watch--;
led2=0; //判断是否重启;正常喂狗后灯亮;若是超过1.6s后则复位灯灭;
}
else
watch=0;
}
/////////////////////////////////////////
main()
{
watch=100;
led1=1;led2=1;
delay(10000);
/* rbuf=read1char(ADDR); //判断是否为掉电
if(rbuf)
{
PSW=read1char(ADDR+1); //恢复重要数据
ACC=read1char(ADDR+2);
}
wbuf=0;
write1char(wbuf,ADDR); //读出数据后把该次的状态清零;防止下次再读;
*/
intinit();
while(1)
{
feeddog();
}
}
/*******************************************IIC***********************************************************/
#ifndef _IIC_H
#define _IIC_H_
/***************************************************/
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SLAVE 0xa0 //IIC器件地址 注意全部接地
#define Rslave SLAVE+1
sbit SDA=P2^0;
sbit SCL=P2^1;
////////////////////////////////////////////////////////
void delay(uint time)
{
for(time;time>0;time--);
}
///////////////////////////////////////
void start_iic()
{
SDA=1;
SCL=1;
delay(10);
SDA=0;
delay(10);
SCL=0;
}
void stop_iic()
{
SDA=0;
SCL=1;
delay(10);
SDA=1;
delay(10);
SCL=0;
}
void ack_iic()
{
SDA=0;
SCL=1;
delay(10);
SCL=0;
SDA=1;
}
void nack_iic()
{
SDA=1;
SCL=1;
delay(10);
SCL=0;
SDA=0;
}
////////////////////////* write 1 byte *//////////////////////
void write_byte(uchar ch)
{
uchar i;
for(i=0;i<8;i++)
{
if(ch&0x80)
SDA=1;
else
SDA=0;
SCL=1;
delay(10);
SCL=0;
ch=ch<<1;
}
SDA=1;
SCL=1;
delay(10);
if(SDA==1)
F0=0;
else
F0=1;
SCL=0;
}
///////////////////////////* read 1 byte *////////////////////////
uchar read_byte()
{
uchar i;
uchar r=0;
SDA=1;
for(i=0;i<8;i++)
{
r=r<<1;
SCL=1;
delay(10);
if(SDA==1)
r++;
SCL=0;
}
return r;
}
/////////////////////////* write n byte *////////////////////////////
bit write_nbyte(uchar slave,uint addr,uchar *str,uchar numb)
{
uchar i;
start_iic();
write_byte(slave); //write iic addr
if(F0==0)
return 0;
write_byte(addr); //write data addr
if(F0==0)
return 0;
for(i=0;i<numb;i++) //write data
{
write_byte(*str);
if(F0==0)
return 0;
str++;
}
stop_iic(); //stop iic
return(1);
}
//////////////////*写一个字节*//////////////////////////////
bit write1char(uchar ch,uint addr)
{
start_iic(); //产生起始信号
write_byte(SLAVE); //发送从器件地址
if(F0==0) return 0; //检查应答位
write_byte(addr); //发送目的地址
if(F0==0) return 0;
write_byte(ch); //发送8为数据
if(F0==0) return 0;
stop_iic(); //停止信号
return 1;
}
////////////////////*读一个字节*////////////////////////////////
uchar read1char(uint addr)
{
uchar ch;
start_iic();
write_byte(SLAVE);
if(F0==0)return 0;
write_byte(addr);
if(F0==0)return 0;
start_iic(); //再次产生起始信号,不能少
write_byte(Rslave); //送读控制字
if(F0==0)return 0;
ch=read_byte(); //读出指定单元的内容
nack_iic(); //非应答信号
stop_iic();
return (ch);
}
////////////////////////////////////////////////////////////
//////////////////////* read n byte *//////////////////////////////////
bit read_nbyte(uchar slave,uint addr,uchar *str,uchar numb)
{
uchar i;
start_iic();
write_byte(slave); //write iic addr
if(F0==0)
return 0;
write_byte(addr); //write data addr
if(F0==0)
return 0;
start_iic(); //再次产生起始信号,不能少
write_byte(Rslave); //送读控制字
if(F0==0)
return 0;
for(i=0;i<numb-1;i++) //
{
*str=read_byte();
ack_iic();
str++;
}
*str=read_byte();
nack_iic();
stop_iic();
return(1);
}
/************************************************************/
#endif
