這個是一個硬件看門狗和用at24c02保存掉電數(shù)據(jù)的程序,希望對大家有所幫助已經(jīng)測試通過的.
#include<reg51.h> #include "IIC.h" #define ADDR 0x20 //存儲地址 sbit led1=P2^7; //掉電現(xiàn)象 sbit led2=P2^6; //看門狗復(fù)位現(xiàn)象 sbit WDI=P2^5; //喂狗位 uint watch=100; //喂狗次數(shù) uchar wbuf,rbuf; //寫數(shù)據(jù)讀數(shù)據(jù)變量 bit flag=0; //掉電標(biāo)志 /*******外部中斷,下降沿觸發(fā)**************/ void intinit() { EA=1; EX0=1; IT0=1; } /****************掉電中斷*****************/ void int0() interrupt 0 //掉電數(shù)據(jù)保護(hù),燈亮了表示進(jìn)入中斷一次 { led1=0; wbuf=0x01; write1char(wbuf,ADDR); //掉電標(biāo)志 wbuf=PSW; write1char(wbuf,ADDR+1); //數(shù)據(jù)保護(hù) wbuf=ACC; write1char(wbuf,ADDR+2); led1=1; } /*************watch dog處理******************/ void feeddog() { if(watch>0) { WDI=~WDI; //喂狗; watch--; led2=0; //判斷是否重啟;正常喂狗后燈亮;若是超過1.6s后則復(fù)位燈滅; } else watch=0; } ///////////////////////////////////////// main() { watch=100; led1=1;led2=1; delay(10000); /* rbuf=read1char(ADDR); //判斷是否為掉電 if(rbuf) { PSW=read1char(ADDR+1); //恢復(fù)重要數(shù)據(jù) ACC=read1char(ADDR+2); } wbuf=0; write1char(wbuf,ADDR); //讀出數(shù)據(jù)后把該次的狀態(tài)清零;防止下次再讀; */ 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); } //////////////////*寫一個字節(jié)*////////////////////////////// bit write1char(uchar ch,uint addr) { start_iic(); //產(chǎn)生起始信號 write_byte(SLAVE); //發(fā)送從器件地址 if(F0==0) return 0; //檢查應(yīng)答位 write_byte(addr); //發(fā)送目的地址 if(F0==0) return 0; write_byte(ch); //發(fā)送8為數(shù)據(jù) if(F0==0) return 0; stop_iic(); //停止信號 return 1; } ////////////////////*讀一個字節(jié)*//////////////////////////////// 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(); //再次產(chǎn)生起始信號,不能少 write_byte(Rslave); //送讀控制字 if(F0==0)return 0; ch=read_byte(); //讀出指定單元的內(nèi)容 nack_iic(); //非應(yīng)答信號 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(); //再次產(chǎn)生起始信號,不能少 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