標(biāo)題: 單片機(jī)定時(shí)工作4000個(gè)小時(shí)自動(dòng)損壞的程序 [打印本頁]

作者: zhangxinchun    時(shí)間: 2019-10-7 23:42
標(biāo)題: 單片機(jī)定時(shí)工作4000個(gè)小時(shí)自動(dòng)損壞的程序
//實(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; //對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; //對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é)束
*********************************************************************/


作者: sh1900    時(shí)間: 2023-7-15 11:20
有沒有計(jì)算開機(jī)次數(shù)損壞的?
作者: 量子工業(yè)    時(shí)間: 2023-7-15 11:32
sh1900 發(fā)表于 2023-7-15 11:20
有沒有計(jì)算開機(jī)次數(shù)損壞的?

應(yīng)該也能設(shè)置吧,開機(jī)多少次或復(fù)位多少次就損壞;
也可以設(shè)置成,逐漸的讓運(yùn)行速度降低(intel是不是這樣操作的?)變卡,逼著用戶升級(jí)
作者: 量子工業(yè)    時(shí)間: 2023-7-15 11:35
記得以前日本的S尼就弄過這種操作,DVD機(jī)質(zhì)保1年,從第5次通電開始計(jì)算時(shí)間,到12個(gè)月時(shí)候加大激光頭輸出功率,然后15個(gè)月左右全部歇菜,后來維修換上后,激光頭只能用3個(gè)月,然后被人發(fā)現(xiàn)后弄出來一場風(fēng)暴,從此S尼在國內(nèi)逐漸勢微
作者: timeo    時(shí)間: 2023-7-17 22:41
某米,某想,是不是你設(shè)計(jì)的?老實(shí)交待
作者: n0si9na1    時(shí)間: 2023-7-17 23:06
計(jì)劃性報(bào)廢,美其名曰:新技術(shù),新環(huán)保,新理念
作者: Q__Q    時(shí)間: 2023-7-19 09:57
不應(yīng)該自毀,應(yīng)該限制功能,對于工程完成沒付 的可以用
作者: wulin    時(shí)間: 2023-7-19 16:57
sh1900 發(fā)表于 2023-7-15 11:20
有沒有計(jì)算開機(jī)次數(shù)損壞的?

不論用開機(jī)次數(shù)或開機(jī)累計(jì)時(shí)間自毀都很容易實(shí)現(xiàn)。
作者: xianfajushi    時(shí)間: 2023-7-20 08:09
生產(chǎn)垃圾?!可恥的浪費(fèi)和。
作者: 760656130    時(shí)間: 2023-7-21 10:39
量子工業(yè) 發(fā)表于 2023-7-15 11:32
應(yīng)該也能設(shè)置吧,開機(jī)多少次或復(fù)位多少次就損壞;
也可以設(shè)置成,逐漸的讓運(yùn)行速度降低(intel是不是這 ...

這個(gè)可以 開機(jī)一次循環(huán)中delay增加一點(diǎn)點(diǎn) 直到最后卡的不要不要的
作者: 劉佑紅    時(shí)間: 2023-7-21 11:07
       看都樓主的方法我也在想采用類似的方法,就是開機(jī)計(jì)時(shí),到一個(gè)小時(shí)寫入EEPROM,在程序中執(zhí)行一個(gè)不到總時(shí)間的條件判斷,使程序正常運(yùn)行,總時(shí)間到了不執(zhí)行某個(gè)動(dòng)作以達(dá)到保護(hù)的目的。但考慮會(huì)有一個(gè)問題,就是在程序正常運(yùn)行中隨時(shí)寫入EEPROM,整個(gè)寫的過程會(huì)有幾十ms,這幾十ms過程中要關(guān)總中斷,這幾十秒很有可能會(huì)影響程序的正常運(yùn)行。我考慮的解決方式是在寫EEPROM時(shí)再加一個(gè)判斷條件,這個(gè)條件成立時(shí)容許幾十毫秒的延時(shí),不影響程序正常運(yùn)行,比如在計(jì)數(shù)時(shí),正常計(jì)數(shù)狀態(tài)下即使該寫入了也不寫入,只有當(dāng)計(jì)數(shù)清零后再寫入。不知朋友是否有更好的方法。
作者: 李冬    時(shí)間: 2023-7-21 16:07
如果硬改電路呢
作者: man1234567    時(shí)間: 2023-7-21 17:22
當(dāng)年電視臺(tái)用的肩扛的錄相機(jī)中就有個(gè)硬件,按時(shí)長自動(dòng)報(bào)廢,有可視進(jìn)度條。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1