//實(shí)現(xiàn)功能:定時(shí)自毀應(yīng)用程序
//使用芯片:STC15F104E
//晶振:12MHZ
//編譯環(huán)境:Keil
#include "reg52.h"
#include <intrins.H>
#define uchar unsigned char //宏定義字符型變量
#define uint unsigned int //宏定義整型變量
/********************************************************************
寄存器設(shè)置
*********************************************************************/
sfr IAP_DATA =0xc2; //數(shù)據(jù)寄存器
sfr IAP_ADDRH =0xc3; //地址寄存器
sfr IAP_ADDRL =0xc4; //地址寄存器
sfr IAP_CMD =0xc5; //命令寄存器
sfr IAP_TRIG =0xc6; //觸發(fā)寄存器
sfr IAP_CONTR =0xc7; //擦除寄存器
/********************************************************************
命令定義
*********************************************************************/
#define CMD_IDLE 0 //EEPROM無操作
#define CMD_READ 1 //讀取字節(jié)
#define CMD_PROGRAM 2 //寫入字節(jié)
#define CMD_ERASE 3 //擦除字節(jié)
/********************************************************************
編程周期由晶振決定
*********************************************************************/
//#define ENABLE_IAP 0X80 //編程周期由晶振決定(如果<30MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X81 //編程周期由晶振決定(如果<24MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X82 //編程周期由晶振決定(如果<20MHZ選用此項(xiàng))
#define ENABLE_IAP 0X83 //編程周期由晶振決定(如果<12MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X84 //編程周期由晶振決定(如果<6MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X85 //編程周期由晶振決定(如果<3MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X86 //編程周期由晶振決定(如果<2MHZ選用此項(xiàng))
//#define ENABLE_IAP 0X87 //編程周期由晶振決定(如果<1MHZ選用此項(xiàng))
#define IAP_ADDRESS1 0X0000 //內(nèi)部EEPROM地址
#define IAP_ADDRESS2 0X0200
/********************************************************************
最長時(shí)間定義
*********************************************************************/
#define T 4000 //定時(shí)時(shí)間(小時(shí))
/********************************************************************
初始定義
*********************************************************************/
uint fen,days;
uchar Count;
uchar Count1;
uint cnt;
bit write;
sbit OUT1=P3^3;
sbit IN0=P3^5;
//============================================================
//延時(shí)程序
void delayms(unsigned int x)
{
int i,j;
for(i=0;i<x;i++)
{
for(j=0;j<260;j++);
}
}
/********************************************************************
操作函數(shù)
*********************************************************************/
void IapIdle()
{
IAP_CONTR=0;
IAP_CMD=0;
IAP_TRIG=0;
IAP_ADDRH=0X80;
IAP_ADDRL=0;
}
/********************************************************************
讀取一個(gè)字節(jié)函數(shù)
*********************************************************************/
uchar IapReadByte(uint addr)
{
uchar dat;
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
dat=IAP_DATA;
IapIdle();
return dat;
}
/********************************************************************
寫入一個(gè)字節(jié)函數(shù)
*********************************************************************/
void IapProgramByte(uint addr,uchar dat)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
IapIdle();
}
/********************************************************************
擦除一個(gè)字節(jié)函數(shù)
*********************************************************************/
void IapEraseSector(uint addr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
IapIdle();
}
/********************************************************************
定時(shí)中斷服務(wù)函數(shù)
*********************************************************************/
void t0(void) interrupt 1 using 1 //定時(shí)中斷服務(wù)函數(shù)
{
TH0=(65536-50000)/256; //對(duì)TH0 TL0 賦值
TL0=(65536-50000)%256;
cnt++; //每過50ms tcnt 加一
if(cnt==1200) //計(jì)滿1200次1分鐘
{ cnt=0; //重新再計(jì)
fen++;
if(fen==60) //定時(shí)60分鐘,在從零開始計(jì)時(shí)
{
fen=0;
days++;
write=1;
}
}
}
/********************************************************************
主函數(shù)
*********************************************************************/
void main()
{
TMOD=0x01; //定時(shí)器工作在方式1
TH0=(65536-50000)/256; //對(duì)TH0 TL0 賦值
TL0=(65536-50000)%256;
ET0=1;
EA=1;
TR0=1; //定時(shí)器函數(shù)初始化
delayms(10); //開機(jī)延時(shí)
Count=IapReadByte(IAP_ADDRESS1); //讀取EEPROM數(shù)據(jù)
Count1=IapReadByte(IAP_ADDRESS1+1); //讀取EEPROM數(shù)據(jù)
days=(Count*100)+Count1; //從讀取數(shù)據(jù)中計(jì)算時(shí)間值
while(1)
{
if(days>=T) //判斷如果延時(shí)時(shí)間大于等于設(shè)置時(shí)間,繼電器斷開,模塊停止工作。否則繼電器吸合
{
OUT1=0;
TR0=0;
}
else
{
OUT1=1;
TR0=1;
}
if(write==1) // 記滿一個(gè)小時(shí),數(shù)據(jù)存儲(chǔ)一次
{
write=0;
Count=days/100;
Count1=days%100;;
IapEraseSector(IAP_ADDRESS1); //擦除0扇區(qū) //34us
IapEraseSector(IAP_ADDRESS1+1); //擦除0扇區(qū) //34us
IapProgramByte(IAP_ADDRESS1,Count); //寫入數(shù)據(jù)//38us
IapProgramByte(IAP_ADDRESS1+1,Count1); //寫入數(shù)據(jù)//38us
}
if(IN0==0)
{
delayms(10);
if(IN0==0)
{
while(!IN0);
days=0;
Count=0;
Count1=0;
IapEraseSector(IAP_ADDRESS1); //擦除0扇區(qū) //34us
IapEraseSector(IAP_ADDRESS1+1); //擦除0扇區(qū) //34us
IapProgramByte(IAP_ADDRESS1,Count); //寫入數(shù)據(jù)//38us
IapProgramByte(IAP_ADDRESS1+1,Count1); //寫入數(shù)據(jù)//38us
}
}
}
}
/********************************************************************
結(jié)束
*********************************************************************/
|