久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3740|回復: 9
收起左側

單片機+EEPROM讀出保存的變量部都是255

[復制鏈接]
ID:608872 發表于 2021-10-19 17:06 | 顯示全部樓層 |閱讀模式
      共6個變量,前面4個數據類型unsigned char的變量都能正常讀出,說明寄存器設置應該沒有問題,但1個數據類型unsigned int和一個unsigned long的變量寫入任何數值,讀出都是255 是不是因為這兩個變量占用4個字節,應該分4次寫入,然后4次讀出在組合處理呢?如果是這樣的話,程序應該怎么改寫。

單片機源程序如下:
/**********************************
描  述:寫數據到EEPROM保存
功  能:寫一字節數據到ISP/IAP/EEPROM區域
**********************************/
void IapProgramByte(u32 addr, u32 dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //設置IAP命令
    IAP_ADDRL = addr;               //設置IAP低地址
    IAP_ADDRH = addr >> 8;          //設置IAP高地址
    IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數據
    IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();                      //關閉IAP功能
}

/**********************************
描  述:讀取EEPROM數據
功  能:從ISP/IAP/EEPROM區域讀取一字節
**********************************/
u8 IapReadByte(u32 addr)
{
    u32 dat;                       //數據緩沖區
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //設置IAP命令
    IAP_ADDRL = addr;               //設置IAP低地址
    IAP_ADDRH = addr >> 8;          //設置IAP高地址
    IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //讀ISP/IAP/EEPROM數據
    IapIdle();                      //關閉IAP功能
    return dat;                     //返回
}

/**********************************
描  述:保存關機前已設置參數
功  能:寫入數據到EEPROM
**********************************/
void EEPROM_Data()
{
                IapEraseSector(0);         //ISP/IAP/EEPROM扇區擦除
                IapProgramByte(0,mc1);     //扇區0,數據類型unsigned char 變量范圍0-25        
                IapProgramByte(1,mc_jg);   //扇區1,數據類型unsigned char 變量范圍0-10
                IapProgramByte(2,mc2);     //扇區2,數據類型unsigned char 變量范圍0-25
                IapProgramByte(3,zd_cf);   //扇區3,數據類型unsigned char 變量范圍0-10
                IapProgramByte(4,MOS_JS);  //扇區4-7,數據類型unsigned int 變量范圍0-99999
                IapProgramByte(8,MCU_V);   //扇區8-11,數據類型unsigned long 變量范圍0-1500        
}


/**********************************
描  述:讀取EEPROM
功  能:讀取上次關機前設置的數據
**********************************/
void EEPROM_init()
{
    mc1=IapReadByte(0);    //扇區0,從ISP/IAP/EEPROM區域讀取一字節
    mc_jg=IapReadByte(1);  //扇區1,從ISP/IAP/EEPROM區域讀取一字節
    mc2=IapReadByte(2);    //扇區2,從ISP/IAP/EEPROM區域讀取一字節
    zd_cf=IapReadByte(3);  //扇區3,從ISP/IAP/EEPROM區域讀取一字節
    MOS_JS=IapReadByte(4); //扇區4-7,從ISP/IAP/EEPROM區域讀取四字節
    MCU_V=IapReadByte(8);  //扇區8-11從ISP/IAP/EEPROM區域讀取四字節         
}
回復

使用道具 舉報

ID:883242 發表于 2021-10-19 18:02 | 顯示全部樓層
unsigned char *p;
*p=&(unsigned char)MOS_JS; //扇區4-7,數據類型unsigned int 變量范圍0-99999
IapProgramByte(4,*p++);
IapProgramByte(4,*p++);
IapProgramByte(4,*p++);
IapProgramByte(4,*p++);
回復

使用道具 舉報

ID:130230 發表于 2021-10-19 18:04 | 顯示全部樓層
讀出255證明沒有寫成功
回復

使用道具 舉報

ID:624769 發表于 2021-10-19 19:39 | 顯示全部樓層
Eeprom 讀寫都只能單字節。

你要對 LONG 讀寫的話要如下這樣做子函數

void IapProgramLong(u16 addr, u32 dat)
{
    u8  i;
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //設置IAP命令
    addr+=3;
    for(i=0;i<4;i++)
    {
    IAP_ADDRL = addr;               //設置IAP低地址
    IAP_ADDRH = addr >> 8;          //設置IAP高地址
    IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數據
    IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
    dat >>=8;
    addr--;
    }
}


u32 IapReadLong(u16 addr)
{
    u8  i;
    u32 dat;                       //數據緩沖區
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //設置IAP命令
    for(i=0;i<4;i++)
    {
    IAP_ADDRL = addr;               //設置IAP低地址
    IAP_ADDRH = addr >> 8;          //設置IAP高地址
    IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
    dat <<=8;
    dat |= IAP_DATA;                 //讀ISP/IAP/EEPROM數據

    addr++;
    }
    return dat;                     //返回
}

回復

使用道具 舉報

ID:261025 發表于 2021-10-19 20:13 | 顯示全部樓層
我也遇到過讀寫錯誤  用的是12c5a60s2  第一個數據讀寫正確  第二個數據就錯誤  不管怎么換地址和給讀出寫入加延時都沒用  換個新的單片機也沒用  然后我就放棄了   
回復

使用道具 舉報

ID:213173 發表于 2021-10-19 21:01 | 顯示全部樓層
EEPROM只能逐個字節寫讀,unsigned int和unsigned long型數據要按字節分解后寫入,讀取后再合并使用。
//共6個變量,前面4個數據類型unsigned char
unsigned char a,b,c,d;
//1個數據類型unsigned int
unsigned int  e;
//1個數據類型unsigned long
unsigned long f;

unsigned char dis_buf[10];//寫入緩存
unsigned char dis_buf1[10];//讀出緩存

        dis_buf[0]=a;
        dis_buf[1]=b;
        dis_buf[2]=c;
        dis_buf[3]=d;
        dis_buf[4]=e>>8;
        dis_buf[5]=e;
        dis_buf[6]=f>>24;
        dis_buf[7]=f>>16;
        dis_buf[8]=f>>8;
        dis_buf[9]=f;

        IapEraseSector(0x0000);//擦除EEPROM扇區中的數據
        for(i=0;i<10;i++)
        {
                IapProgramByte(0x0000+i,dis_buf[i ]);//重新寫入數據
        }
        for(i=0;i<10;i++)
        {
                dis_buf1[i ]=IapReadByte(0x0000+i);//讀取EEPROM中數據保存在dis_buf1
        }

以下是多字節讀寫的示例
  1. //使用芯片 IAP15W4K58S4 測試EEPROM多字節讀寫,串口發送數據。
  2. #include <STC15F2K60S2.H>
  3. #include <intrins.h>
  4. #define uint unsigned int                                 //宏定義無符號整型數據
  5. #define uchar unsigned char                        //宏定義無符號字符型數據
  6. //----------宏定義ISP的操作命令---------------------
  7. #define CMD_IDLE    0               //空閑模式
  8. #define CMD_READ    1               //IAP字節讀命令
  9. #define CMD_PROGRAM 2               //IAP字節編程命令
  10. #define CMD_ERASE   3               //IAP扇區擦除命令
  11. //----------宏定義定時器2作為波特率發生器------------------
  12. #define     URMD    1               //0:使用定時器2作為波特率發生器
  13.                                     //1:使用定時器1的模式0(16位自動重載模式)作為波特率發生器
  14.                                     //2:使用定時器1的模式2(8位自動重載模式)作為波特率發生器                             
  15. /***************CPU的等待時間******************/
  16. //#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
  17. //#define ENABLE_IAP 0x81           //if SYSCLK<24MHz
  18. #define ENABLE_IAP  0x82            //if SYSCLK<20MHz
  19. //#define ENABLE_IAP 0x83           //if SYSCLK<12MHz
  20. //#define ENABLE_IAP 0x84           //if SYSCLK<6MHz
  21. //#define ENABLE_IAP 0x85           //if SYSCLK<3MHz
  22. //#define ENABLE_IAP 0x86           //if SYSCLK<2MHz
  23. //#define ENABLE_IAP 0x87           //if SYSCLK<1MHz

  24. sbit key=P3^4;                                                                //按鍵1端口定義        
  25. uchar table1[12]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C};
  26. uchar table2[12];                                        //讀取EEPROM數據緩存
  27. uchar a=0;
  28. /*********************子函數聲明********************/
  29. void IapIdle();                                                                        //關閉IAP功能
  30. uchar IapReadByte(uint addr);                                        //讀取一個字節
  31. void IapProgramByte(uint addr, uchar dat);                //寫一個字節
  32. void IapEraseSector(uint addr);                                        //扇區擦除
  33. void InitUart();                                                                //初始化串口
  34. void SendData(uchar dat);                                                //發送串口數據
  35. void keyscan();
  36. void delayms(uint k);

  37. void main()                                                                                //主函數
  38. {                                                                        
  39.         uchar j;
  40.         P0M0 = 0x00;
  41.         P0M1 = 0x00;
  42.         P1M0 = 0x00;
  43.         P1M1 = 0x00;
  44.         P2M0 = 0x00;
  45.         P2M1 = 0x00;
  46.         P3M0 = 0x00;
  47.         P3M1 = 0x00;
  48.         P4M0 = 0x00;
  49.         P4M1 = 0x00;
  50.         P5M0 = 0x00;
  51.         P5M1 = 0x00;
  52.         P6M0 = 0x00;
  53.         P6M1 = 0x00;
  54.         P7M0 = 0x00;
  55.         P7M1 = 0x00;
  56.         InitUart();                                //初始化串口
  57.         while(1)
  58.         {
  59.                 keyscan();                                //按鍵程序
  60.                 if(a==1)
  61.                 {
  62.                         for(j=0;j<12;j++)
  63.                         {
  64.                                 SendData(table2[j]);//串口發送
  65.                         }
  66.                         a=0;
  67.                 }
  68.         }
  69. }

  70. void keyscan()                                        //按鍵掃描程序
  71. {
  72.         uchar i;                                                //臨時變量
  73.         if(key==0)
  74.         {
  75.                 delayms(20);
  76.                 if(key==0)
  77.                 {
  78.                         IapEraseSector(0x0000);//擦除EEPROM扇區中的數據
  79.                         for(i=0;i<12;i++)
  80.                         {
  81.                                 IapProgramByte(0x0000+i,table1[i]);//重新寫入數據
  82.                         }
  83.                         for(i=0;i<12;i++)
  84.                         {
  85.                                 table2[i]=IapReadByte(0x0000+i);//讀取EEPROM中數據保存在table2
  86.                         }
  87.                         while(!key)//等待按鍵抬起
  88.                         a=1;
  89.                 }
  90.         }
  91. }
  92. /*----------------------------
  93.         關閉IAP功能
  94. ----------------------------*/
  95. void IapIdle()
  96. {
  97.     IAP_CONTR = 0;                  //關閉IAP功能
  98.     IAP_CMD = 0;                    //清除命令寄存器
  99.     IAP_TRIG = 0;                   //清除觸發寄存器
  100.     IAP_ADDRH = 0x80;               //將地址設置到非IAP區域
  101.     IAP_ADDRL = 0;
  102. }
  103. /*----------------------------
  104. 從ISP/IAP/EEPROM區域讀取一字節
  105. ----------------------------*/
  106. uchar IapReadByte(uint addr)
  107. {
  108.     uchar dat;                       //數據緩沖區

  109.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  110.     IAP_CMD = CMD_READ;             //設置IAP命令
  111.     IAP_ADDRL = addr;               //設置IAP低地址
  112.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  113.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  114.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  115.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  116.     dat = IAP_DATA;                 //讀ISP/IAP/EEPROM數據
  117.     IapIdle();                      //關閉IAP功能

  118.     return dat;                     //返回
  119. }
  120. /*-------------------------------
  121. 寫一字節數據到ISP/IAP/EEPROM區域
  122. -------------------------------*/
  123. void IapProgramByte(uint addr, uchar dat)
  124. {
  125.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  126.     IAP_CMD = CMD_PROGRAM;          //設置IAP命令
  127.     IAP_ADDRL = addr;               //設置IAP低地址
  128.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  129.     IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數據
  130.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  131.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  132.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  133.     IapIdle();                      //關閉IAP功能
  134. }
  135. /*----------------------------
  136. ISP/IAP/EEPROM扇區擦除
  137. ----------------------------*/
  138. void IapEraseSector(uint addr)
  139. {
  140.     IAP_CONTR = ENABLE_IAP;         //使能IAP
  141.     IAP_CMD = CMD_ERASE;            //設置IAP命令
  142.     IAP_ADDRL = addr;               //設置IAP低地址
  143.     IAP_ADDRH = addr >> 8;          //設置IAP高地址
  144.     IAP_TRIG = 0x5a;                //寫觸發命令(0x5a)
  145.     IAP_TRIG = 0xa5;                //寫觸發命令(0xa5)
  146.     _nop_();                        //等待ISP/IAP/EEPROM操作完成
  147.     IapIdle();                      //關閉IAP功能
  148. }
  149. /*-------------------------------------
  150. 初始化串口 晶振18.432MHz 波特率115200
  151. --------------------------------------*/
  152. void InitUart()
  153. {
  154.         SCON = 0x5a;                //設置串口為8位可變波特率
  155. #if URMD == 0
  156.         T2L = 0xd8;                 //設置波特率重裝值
  157.         T2H = 0xff;                 //115200 bps(65536-18432000/4/115200)
  158.         AUXR = 0x14;                //T2為1T模式, 并啟動定時器2
  159.         AUXR |= 0x01;               //選擇定時器2為串口1的波特率發生器
  160. #elif URMD == 1
  161.         AUXR = 0x40;                //定時器1為1T模式
  162.         TMOD = 0x00;                //定時器1為模式0(16位自動重載)
  163.         TL1 = 0xd8;                 //設置波特率重裝值
  164.         TH1 = 0xff;                 //115200 bps(65536-18432000/4/115200)
  165.         TR1 = 1;                    //定時器1開始啟動
  166. #else
  167.         TMOD = 0x20;                //設置定時器1為8位自動重裝載模式
  168.         AUXR = 0x40;                //定時器1為1T模式
  169.         TH1 = TL1 = 0xfb;           //115200 bps(256 - 18432000/32/115200)
  170.         TR1 = 1;
  171. #endif
  172. }
  173. /*----------------------------
  174. 發送串口數據
  175. ----------------------------*/

  176. void SendData(uchar dat)
  177. {
  178.     while (!TI);                 //等待前一個數據發送完成
  179.     TI = 0;                      //清除發送標志
  180.     SBUF = dat;                  //發送當前數據
  181. }
  182. /*-------------------------------
  183.   1ms延時子程序(11.0592MHz 12T)
  184. -------------------------------*/
  185. void delayms(uint k)
  186. {
  187.         uint i,j;
  188.         for(i=k;i>0;i--)
  189.                 for(j=829;j>0;j--);
  190. }



復制代碼

回復

使用道具 舉報

ID:592807 發表于 2021-10-20 08:30 | 顯示全部樓層
0xff = 255.那是沒寫成功
回復

使用道具 舉報

ID:608872 發表于 2021-10-20 11:33 | 顯示全部樓層
188610329 發表于 2021-10-19 19:39
Eeprom 讀寫都只能單字節。

你要對 LONG 讀寫的話要如下這樣做子函數

請問你這個程序,讀寫單字節和多字節變量通用嗎,還是單字節用我原來的程序
回復

使用道具 舉報

ID:624769 發表于 2021-10-20 11:36 來自觸屏版 | 顯示全部樓層
yinnan128 發表于 2021-10-20 11:33
請問你這個程序,讀寫單字節和多字節變量通用嗎,還是單字節用我原來的程序

不通用,單字節用你原來的。這個讀出來就是4字節,寫進去也是4字節。
回復

使用道具 舉報

ID:139866 發表于 2021-10-21 13:14 | 顯示全部樓層
用示波器看一下時序,很明顯就可以看出來的,根據數據手冊調整時序
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 理伦毛片| 国产精品区二区三区日本 | 久久国产美女视频 | 日韩精品在线免费观看 | 97免费在线观看视频 | 欧美一区精品 | 成人免费淫片aa视频免费 | 亚洲一区二区三区国产 | 97福利在线| 久操伊人 | 国产999精品久久久 精品三级在线观看 | 中文字幕国产精品 | 亚洲国产精品区 | 亚洲国产一区二区视频 | 青青久草 | 最新日韩欧美 | 久久人人网| 91av在线免费观看 | 亚洲欧美日韩精品 | 亚洲五码久久 | 在线观看午夜视频 | 91在线视频网址 | 亚洲男人的天堂网站 | 免费av播放 | avmans最新导航地址 | av国产精品毛片一区二区小说 | 中文字幕1区 | 国产精品日韩在线观看 | 午夜久久久久 | 欧美综合色| 国产精品久久久久久久久动漫 | 久草青青 | 91在线网站 | 久久久久久亚洲精品 | 亚洲精品国产一区 | 成人午夜精品 | 成人免费视频网站在线看 | 人妖无码 | 欧美一区不卡 | 7777在线| www.久久久久久久久久久久 |