找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4563|回復(fù): 11
打印 上一主題 下一主題
收起左側(cè)

請教stc12C5A60S2單片機內(nèi)部E2PROM不保存的問題

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:617813 發(fā)表于 2021-5-5 11:10 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
100黑幣
我使用的是12C5A60S2,郭天祥的單片機開發(fā)板,網(wǎng)上找的驅(qū)動,num1就是沒有保存進EEPROM里去,不知道是哪出的問題,感謝大神們幫幫忙。文件如下:#include <reg52.H>
#include <intrins.h>
#define  uchar unsigned char
#define  uint unsigned int
#define         RdCommand 0x01                //定義ISP的操作命令
#define         prgCommand 0x02
#define         EraseCommand        0x03
#define         Error 1
#define         Ok 0
#define         WaitTime 0x01                //定義CPU的等待時間

sfr  ISP_DATA = 0xE2;
sfr ISP_ADDRH = 0xE3;
sfr ISP_ADDRL = 0xE4 ;

sfr ISP_CMD = 0xE5;
sfr ISP_TRIG = 0xE6;
sfr ISP_CONTR = 0xE7;

sbit duan=P2^6;
sbit wei=P2^7;
sbit key1=P3^4;

uchar code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };
uchar num;
void delayms(uint xms)         //毫秒延時
{
  uint i,j;
  for(i=xms;i>0;i--)
                  for(j=110;j>0;j--);
}
void display(uchar shi,uchar ge)  //數(shù)碼管顯示子函數(shù)
{
   duan=1;
   P0=table[shi];                 //送位選數(shù)據(jù)前關(guān)閉所有顯示,防止打開位選鎖存時
   duan=0;
   P0=0xff;
   wei=1;
   P0=0xfe;
   wei=0;
   delayms(5);         

   duan=1;
   P0=table[ge];                 //送位選數(shù)據(jù)前關(guān)閉所有顯示,防止打開位選鎖存時
   duan=0;
   P0=0xff;
   wei=1;
   P0=0xfd;
   wei=0;
   delayms(5);
}
/*======================打開 ISP,IAP 功能=====================*/
void ISP_IAP_enable(void)
{
         EA=0;                                                           //關(guān)中斷
         ISP_CONTR=ISP_CONTR & 0x18        ;                //0001,1000
         ISP_CONTR=        ISP_CONTR| 0x01;//WaitTime;         //寫入硬件延時
         ISP_CONTR=ISP_CONTR| 0x80;                         //ISPEN=1
}
/*=======================關(guān)閉 ISP,IAP==========================*/
void ISP_IAP_disable(void)
{
          ISP_CONTR= ISP_CONTR & 0x7f;       //ISPEN=0
          ISP_TRIG=0x00;
          EA=1;                            //開中斷
}
/*=======================公共的觸發(fā)代碼=========================*/
void ISPgoon(void)
{
         ISP_IAP_enable();                   //打開ISP,IAP功能
         ISP_TRIG=0x46;                           //觸發(fā)ISP_IAP命令字節(jié)1
         ISP_TRIG=0xb9;                                //觸發(fā)ISP_IAP命令字節(jié)2
         _nop_();
}
/*=======================字節(jié)讀=================================*/
unsigned char byte_read(unsigned int byte_addr)
{
        ISP_ADDRH=(unsigned char)(byte_addr >>8);                //地址賦值
        ISP_ADDRL=(unsigned char)(byte_addr &0x00ff);
        ISP_CMD=ISP_CMD &0xf8;                                 //清除低3位
        ISP_CMD=ISP_CMD | RdCommand;                                                         //寫讀命令
        ISPgoon();                                                                                           //觸發(fā)執(zhí)行
        ISP_IAP_disable();                                     //關(guān)閉ISP,IAP功能
        return(ISP_DATA);                                                                         //返回讀到的數(shù)據(jù)
}
/*========================扇區(qū)擦除================================*/
void SectorErase(unsigned int sector_addr)
{
  unsigned int iSectorAddr;
  iSectorAddr=(sector_addr &0xfe00);                                          //取扇區(qū)地址
  ISP_ADDRH=(unsigned char )(iSectorAddr>>8);
  ISP_ADDRL=0x00;
  ISP_CMD=ISP_CMD &0xf8;                                  //清空低3位
  ISP_CMD=ISP_CMD|EraseCommand;                            //擦除命令3
  ISPgoon();                                              //觸發(fā)執(zhí)行
  ISP_IAP_disable();                                       //關(guān)閉ISP,IAP功能
}
/*=========================字節(jié)寫====================================*/
void byte_write(unsigned int byte_addr,unsigned char original_data)
{
  ISP_ADDRH=(unsigned char)(byte_addr>>8);                                  //取地址
  ISP_ADDRL=(unsigned char)(byte_addr & 0xff00);
  ISP_CMD =ISP_CMD & 0xf8;                                 //清低3位
  ISP_CMD =ISP_CMD | prgCommand;                                                    //寫命令2
  ISP_DATA =original_data;                                 //寫入數(shù)據(jù)準(zhǔn)備
  ISPgoon();                                               //觸發(fā)執(zhí)行
  ISP_IAP_disable();                                      //關(guān)閉IAP功能
}
/*========================main========================================*/
void main()
{
  uchar a,b,num1;
  TMOD=0x01 ;                //設(shè)定定時器0為工作方式1
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  EA=1;
  ET0=1;
  TR0=1;
  num1=byte_read(0x2000);     // 程序開始時讀取EEPROM中數(shù)據(jù)
  if(num1>=60)                                   //防止首次上電時讀取出錯
                  num1=0;

                while(1)
                {
                  if(num>=20)
        //        if(key1==0)                   //調(diào)試用按鍵
                  {
               num=0;
                   num1++;
                   SectorErase(0x2000);
                   byte_write(0x2000,num1);
                   if(num1==60)
                  {
                           num1=0;  
                   }
                   a=num1/10;
                  b=num1%10;
               
                }
                 display(a,b);

         }

}

void timer0() interrupt 1
{
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  num++;
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:853162 發(fā)表于 2021-5-5 14:17 | 只看該作者
把unsigned char byte_read(unsigned int byte_addr)的unsigned char改成void
回復(fù)

使用道具 舉報

板凳
ID:617813 發(fā)表于 2021-5-5 18:20 | 只看該作者
GLP800 發(fā)表于 2021-5-5 14:17
把unsigned char byte_read(unsigned int byte_addr)的unsigned char改成void

改成void就提示出錯沒法執(zhí)行下去,再幫我看看是哪錯了
回復(fù)

使用道具 舉報

地板
ID:213173 發(fā)表于 2021-5-5 20:59 | 只看該作者
樓主用的程序適合STC89C52,STC12C5A60S2的ISP寄存器地址和EEPROM地址與STC89C52不一樣。
sfr ISP_DATA  = 0xC2;
sfr ISP_ADDRH = 0xC3;
sfr ISP_ADDRL = 0xC4;
sfr ISP_CMD   = 0xC5;
sfr ISP_TRIG  = 0xC6;
sfr ISP_CONTR = 0xC7;
EEPROM地址范圍0x0000~0x03ff,第一扇區(qū)首地址0x0000,第二扇區(qū)首地址0x0200。
回復(fù)

使用道具 舉報

5#
ID:853162 發(fā)表于 2021-5-6 17:24 | 只看該作者
lujuguo 發(fā)表于 2021-5-5 18:20
改成void就提示出錯沒法執(zhí)行下去,再幫我看看是哪錯了

看看大佬的回復(fù),STC12C5A60S2的ISP寄存器地址和EEPROM地址與STC89C52不一樣,你用的是STC89C52的例程,你把頭文件#include <reg52.H>改成#include <STC12C5A.H>,把EEPROM地址都改成0x0200看看行不行,你買的板子應(yīng)該有STC12C5A60S2的配套資源,我這里只有51的,我改頭文件后就會報錯,你可以試試看。
回復(fù)

使用道具 舉報

6#
ID:889094 發(fā)表于 2021-5-6 21:31 | 只看該作者
4樓地板正解,用前看手冊,用什么芯片看什么手冊
回復(fù)

使用道具 舉報

7#
ID:922247 發(fā)表于 2021-5-16 20:44 | 只看該作者
E2P讀寫時要確保電源電壓穩(wěn)定。 上電時電壓不穩(wěn),容易出現(xiàn)意外。在初始化中加1秒的延遲后,再進行E2P操作。如果應(yīng)用條件允許延遲可以更長些。要確保上電后啟動大負(fù)載時,電壓波動不影響MCU電源。除了讀寫時電源不穩(wěn),沒有什么情況會導(dǎo)致E2P異常。如果你這些都注意了,就沒問題。 外界干擾問題這完全靠你的經(jīng)驗了,電路設(shè)計是否合理,現(xiàn)場假設(shè)情況能模擬的話,最好研發(fā)時模擬一下,最終達到測試故障率為零在投產(chǎn),包括模擬一下突然斷電,乎斷乎通的情況,這個好模擬,不斷插拔電源即可,看看能都通過考驗。
回復(fù)

使用道具 舉報

8#
ID:220936 發(fā)表于 2021-12-15 10:26 | 只看該作者
還有就是stc12c5a60s2擦除需要時間, SectorErase(0x2000);byte_write(0x2000,num1);中間要加delay,我也遇到了這個情況,在壇里找了半天,終于找到原因
回復(fù)

使用道具 舉報

9#
ID:399179 發(fā)表于 2022-5-7 10:56 來自手機 | 只看該作者
我也遇到這個問題了,按地板的方法改一下就可以了
回復(fù)

使用道具 舉報

10#
ID:1026496 發(fā)表于 2022-5-15 22:39 | 只看該作者
unsigned char byte_read(unsigned int byte_addr) 這個函數(shù)返回值應(yīng)該位int ,  int byte_read(unsigned int byte_addr)
回復(fù)

使用道具 舉報

11#
ID:963509 發(fā)表于 2023-7-29 14:42 | 只看該作者
內(nèi)部的eeprom在使用前刪除當(dāng)前扇區(qū)的數(shù)據(jù),只能扇區(qū)擦除,刪除后再按字節(jié)寫入數(shù)據(jù)就可以了
回復(fù)

使用道具 舉報

12#
ID:1010970 發(fā)表于 2024-1-1 21:58 | 只看該作者
ISP_TRIG=0x46;                           //觸發(fā)ISP_IAP命令字節(jié)1
         ISP_TRIG=0xb9;                                //觸發(fā)ISP_IAP命令字節(jié)2

這兩行命令錯了 46和b9是89c52的命令字節(jié),手冊上5a 和a5才是12單片機的命令字節(jié)
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表