这个是一个硬件看门狗和用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