找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 4616|回復(fù): 3
收起左側(cè)

求助STC8A8K64S4A12單片機寫EEPROM,重啟后讀EEPROM數(shù)據(jù)錯誤

[復(fù)制鏈接]
ID:343304 發(fā)表于 2020-2-21 20:45 | 顯示全部樓層 |閱讀模式
內(nèi)部晶振22.1184M,想實現(xiàn)啟動計數(shù)器,保存在EEPROM中(0x0000和0x0001中),測試數(shù)據(jù)初始值為605,通過szx變量保存,使用了共同體切分兩字節(jié)。
首次運行帶賦值時,TB燈亮,證明變量szx是正常的610以下值(應(yīng)該為604).再重新寫入程序后(去除賦值部分,直接讀取EEPROM)TB燈滅,證明數(shù)值有錯誤,請問程序中哪個部分出了問題呢?難道還沒寫進EEPROM?



#define WT_24M 0x81    //EEPROM 24M晶振延時

sbit RR = P2^1;
sbit GG = P2^2;
sbit BB = P2^3;

sbit TA = P2^4;      
sbit TB = P2^5;      
sbit TC = P2^6;


unsigned int szx;        //EEPROM的計數(shù)器變量

void IapIdle()             //EEPROM 結(jié)束復(fù)位
{
  IAP_CONTR = 0;     //EEPROM 關(guān)閉IAP功能
  IAP_CMD = 0;                  //EEPROM 清除命令寄存器
  IAP_TRIG = 0;                  //EEPROM 清除觸發(fā)寄存器
  IAP_ADDRH = 0x80;         //EEPROM 將地址設(shè)置到非IAP區(qū)域
  IAP_ADDRL = 0;         //EEPROM
}





char IapRead(unsigned int addr) //EEPROM 讀取EEPROM數(shù)據(jù) 返回整個IapRead函數(shù)
{

  unsigned char dat;  

  IAP_CONTR = WT_24M;  //EEPROM 設(shè)定延時
  IAP_CMD = 1;                   //EEPROM 設(shè)定1讀取命令
  IAP_ADDRL = addr;           //EEPROM 指定要讀取的低地址
  IAP_ADDRH = addr>>8; //EEPROM 指定要讀取的高地址
  IAP_TRIG = 0x5a;           //EEPROM 執(zhí)行的觸發(fā)命令
  IAP_TRIG = 0xa5;           //EEPROM 執(zhí)行的觸發(fā)命令
  _nop_();
  dat = IAP_DATA;           //EEPROM 讀取IAP賦值
  IapIdle();                   //EEPROM 關(guān)閉IAP功能

  return  dat;                   //EEPROM 返回整個IapRead函數(shù)
}



void IapProgram(unsigned int addr, unsigned char dat)         //EEPROM 把addr地址的資料寫成dat的內(nèi)
{
  IAP_CONTR = WT_24M;  //EEPROM 設(shè)定延時
  IAP_CMD = 2;                   //EEPROM 設(shè)定2寫命令
  IAP_ADDRL = addr;           //EEPROM 指定要寫的低地址
  IAP_ADDRH = addr>>8; //EEPROM 指定要寫的高地址
  IAP_DATA = dat;           //EEPROM 寫IAP數(shù)據(jù)
  IAP_TRIG = 0x5a;           //EEPROM 執(zhí)行的觸發(fā)命令
  IAP_TRIG = 0xa5;           //EEPROM 執(zhí)行的觸發(fā)命令
  _nop_();
  IapIdle();                   //EEPROM 關(guān)閉IAP功能
}


void IapErase(unsigned int addr)          //EEPROM 擦除EEPROM數(shù)據(jù)     
{
  IAP_CONTR = WT_24M;  //EEPROM 設(shè)定延時
  IAP_CMD = 3;                   //EEPROM 設(shè)定3擦除命令
  IAP_ADDRL = addr;           //EEPROM 指定要擦除的低地址
  IAP_ADDRH = addr>>8; //EEPROM 指定要擦除的高地址
  IAP_TRIG = 0x5a;           //EEPROM 執(zhí)行的觸發(fā)命令
  IAP_TRIG = 0xa5;           //EEPROM 執(zhí)行的觸發(fā)命令
  _nop_();
  IapIdle();                   //EEPROM 關(guān)閉IAP功能
}



void main()
{

  union hecheng                         //EEPROM 定義一個共同體
   {
    unsigned char qw[2];        //EEPROM qw有2個char           加入了unsigned
        unsigned int er;                  //EEPROM er是無字符整型
   }hc;                                  //EEPROM 共同體名稱為hc




  hc.qw[0]=IapRead(0x0000);         //EEPROM  讀0x0000到hc[0]
  hc.qw[1]=IapRead(0x0001);         //EEPROM  讀0x0002到hc[1]

  szx = hc.er;
//  szx = 605;    //首次編譯預(yù)賦值,保存在EEPROM中,下次重新編譯去除,并且不清除EEPROM中數(shù)據(jù)


  if(szx <= 585)
   {
    TC = 0x0;                                //EEPROM R38(LED)
        while(1);                                //EEPROM 判斷次數(shù)為,停止操作
   }

  szx--;
  hc.er = szx;


   IapErase(0x0000);                         //EEPROM  先擦除0x0000扇區(qū)
   IapProgram(0x0000,hc.qw[0]);         //EEPROM  寫hc[0]到0x0000
   IapProgram(0x0001,hc.qw[1]);         //EEPROM  寫hc[1]到0x0002

  hc.qw[0]=IapRead(0x0000);         //EEPROM  讀0x0000到hc[0]
  hc.qw[1]=IapRead(0x0001);         //EEPROM  讀0x0002到hc[1]

  if(szx == hc.er)
   {
    TA = 0x0;                                //EEPROM R34(LED)   }

  if(szx >= 610)
   {
    TB = 0x0;                                //EEPROM R36(LED)   }

}
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2020-2-21 23:06 | 顯示全部樓層
STC單片機空白EEPROM的寄存器都是0xFF,上電讀EEPROM的數(shù)據(jù)不在特定范圍就認為是首次上電,寫初始數(shù)據(jù)到EEPROM。以后上電讀EEPROM的數(shù)據(jù)在特定范圍就不會改寫。這樣就不必分兩次下載程序。
樓主這個程序好像寫入的數(shù)據(jù)雖然是605,但最終得到的數(shù)據(jù)是未必是604。因為main()內(nèi)沒有約束,執(zhí)行完跳出后再入,直到滿足if(szx <= 585)條件程序才會停留在while(1);。
回復(fù)

使用道具 舉報

ID:343304 發(fā)表于 2020-2-22 09:03 | 顯示全部樓層
wulin 發(fā)表于 2020-2-21 23:06
STC單片機空白EEPROM的寄存器都是0xFF,上電讀EEPROM的數(shù)據(jù)不在特定范圍就認為是首次上電,寫初始數(shù)據(jù)到EEP ...

很好的建議,已經(jīng)使用,并且程序通過了~謝謝你!
回復(fù)

使用道具 舉報

ID:537245 發(fā)表于 2021-7-30 16:26 | 顯示全部樓層
wulin 發(fā)表于 2020-2-21 23:06
STC單片機空白EEPROM的寄存器都是0xFF,上電讀EEPROM的數(shù)據(jù)不在特定范圍就認為是首次上電,寫初始數(shù)據(jù)到EEP ...

感謝,看了一下就明白了,剛開始一直下載2次,第二次下載后讀數(shù)據(jù)總是不對
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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