這個是一個硬件看門狗和用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
