找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STC15W408AS寫內(nèi)部EEPROM后讀出來數(shù)據(jù)不一致

  [復(fù)制鏈接]
ID:146949 發(fā)表于 2017-2-21 22:03 | 顯示全部樓層 |閱讀模式
IMG_20170221_215131.jpg 單片機(jī):STC15W408AS
請問有人知道為什么我這個程序?qū)懭氲臄?shù)據(jù)與讀出的不一致嗎?
做了兩個按健P10和P11,每次按增加或減少數(shù)值寫入內(nèi)部EEPROM。但讀出來的總是不一樣。
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sfr P4          =   0xC0;   //1111,1111 端口4
sfr P5          =   0xC8;   //xxxx,1111 端口5
sfr P6          =   0xE8;   //0000,0000 端口6
sfr P7          =   0xF8;   //0000,0000 端口7
sfr P0M0        =   0x94;   //0000,0000 端口0模式寄存器0
sfr P0M1        =   0x93;   //0000,0000 端口0模式寄存器1
sfr P1M0        =   0x92;   //0000,0000 端口1模式寄存器0
sfr P1M1        =   0x91;   //0000,0000 端口1模式寄存器1
sfr P2M0        =   0x96;   //0000,0000 端口2模式寄存器0
sfr P2M1        =   0x95;   //0000,0000 端口2模式寄存器1
sfr P3M0        =   0xB2;   //0000,0000 端口3模式寄存器0
sfr P3M1        =   0xB1;   //0000,0000 端口3模式寄存器1
sfr P4M0        =   0xB4;   //0000,0000 端口4模式寄存器0
sfr P4M1        =   0xB3;   //0000,0000 端口4模式寄存器1
sfr P5M0        =   0xCA;   //0000,0000 端口5模式寄存器0
sfr P5M1        =   0xC9;   //0000,0000 端口5模式寄存器1
sfr P6M0        =   0xCC;   //0000,0000 端口6模式寄存器0
sfr P6M1        =   0xCB;   //0000,0000 端口6模式寄存器1
sfr P7M0        =   0xE2;   //0000,0000 端口7模式寄存器0
sfr P7M1        =   0xE1;   //0000,0000 端口7模式寄存器1
sfr   IE2       = 0xaf;               //中斷使能寄存器2
sfr   AUXR      = 0x8e;               //輔助寄存器
sfr   T2H       = 0xD6;               //定時器2高8位
sfr   T2L       = 0xD7;               //定時器2低8位
sfr ADC_CONTR   =   0xBC;           //ADC控制寄存器
sfr ADC_RES     =   0xBD;           //ADC高8位結(jié)果
sfr ADC_LOW2    =   0xBE;           //ADC低2位結(jié)果
sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER   0x80            //ADC power control bit
#define ADC_FLAG    0x10            //ADC complete flag
#define ADC_START   0x08            //ADC start control bit
#define ADC_SPEEDLL 0x00            //420 clocks
#define ADC_SPEEDL  0x20            //280 clocks
#define ADC_SPEEDH  0x40            //140 clocks
#define ADC_SPEEDHH 0x60            //70 clock
sfr IAP_DATA    =   0xC2;           //IAP數(shù)據(jù)寄存器
sfr IAP_ADDRH   =   0xC3;           //IAP地址寄存器高字節(jié)
sfr IAP_ADDRL   =   0xC4;           //IAP地址寄存器低字節(jié)
sfr IAP_CMD     =   0xC5;           //IAP命令寄存器
sfr IAP_TRIG    =   0xC6;           //IAP命令觸發(fā)寄存器
sfr IAP_CONTR   =   0xC7;           //IAP控制寄存器
#define CMD_IDLE    0               //空閑模式
#define CMD_READ    1               //IAP字節(jié)讀命令
#define CMD_PROGRAM 2               //IAP字節(jié)編程命令
#define CMD_ERASE   3               //IAP扇區(qū)擦除命令
#define ENABLE_IAP  0x82            //if SYSCLK<20MHz
#define IAP_ADDRESS 0x0400//測試地址
sbit    LCD5110_RES = P3^7;  //LCD5110 復(fù)位,0復(fù)位
sbit   LCD5110_SCLK = P3^6;  //LCD5110 時鐘
sbit   LCD5110_SDIN = P3^5;  //LCD5110 數(shù)據(jù)
sbit     LCD5110_DC = P3^4;  //LCD5110 1寫數(shù)據(jù),0寫指令
sbit     LCD5110_CE = P3^3;  //LCD5110 片選
sbit            P10 = P1^0;  //開關(guān)
sbit            P11 = P1^1;  //開關(guān)

const unsigned char code F6x8[][6] =
{
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // sp 0
    { 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 },   // ! 1
    { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 },   // " 2
    { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // # 3
    { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $ 4
    { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 },   // % 5
    { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 },   // & 6
    { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 },   // ' 7
    { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 },   // ( 8
    { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 },   // ) 9
    { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 },   // * 10
    { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 },   // + 11
    { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 },   // , 12
    { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 },   // - 13
    { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 },   // . 14
    { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 },   // / 15
    { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0 16
    { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1 17
    { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2 18
    { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3 19
    { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4 20
    { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5 21
    { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6 22
    { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7 23
    { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8 24
    { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9 25

};

void Delayms(uint ms) //1mS@12.000MHz
{
   unsigned char i, j;
   while(ms--)
   {i = 12;
                j = 169;
                do
                {
                        while (--j);
                } while (--i);
   }
}

void IapIdle()//關(guān)閉IAP
{
    IAP_CONTR = 0;                  //關(guān)閉IAP功能
    IAP_CMD = 0;                    //清除命令寄存器
    IAP_TRIG = 0;                   //清除觸發(fā)寄存器
    IAP_ADDRH = 0x80;               //將地址設(shè)置到非IAP區(qū)域
    IAP_ADDRL = 0;
}
uchar IapReadByte(uint addr)//從ISP/IAP/EEPROM區(qū)域讀取一字節(jié)
{
    uchar dat;                       //數(shù)據(jù)緩沖區(qū)
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //設(shè)置IAP命令
    IAP_ADDRL = addr;               //設(shè)置IAP低地址
    IAP_ADDRH = addr >> 8;          //設(shè)置IAP高地址
    IAP_TRIG = 0x5a;                //寫觸發(fā)命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發(fā)命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //讀ISP/IAP/EEPROM數(shù)據(jù)
    IapIdle();                      //關(guān)閉IAP功能
    return dat;                     //返回
}

void IapProgramByte(uint addr, uchar dat)//寫一字節(jié)數(shù)據(jù)到ISP/IAP/EEPROM區(qū)域
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //設(shè)置IAP命令
    IAP_ADDRL = addr;               //設(shè)置IAP低地址
    IAP_ADDRH = addr >> 8;          //設(shè)置IAP高地址
    IAP_DATA = dat;                 //寫ISP/IAP/EEPROM數(shù)據(jù)
    IAP_TRIG = 0x5a;                //寫觸發(fā)命令(0x5a)
    IAP_TRIG = 0xa5;                //寫觸發(fā)命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    IapIdle();
}
void LCD_write_byte(unsigned char dt, unsigned char command)//LCD5110寫入數(shù)據(jù)
{
     unsigned char i;
     LCD5110_CE=0;                       // 關(guān)閉LCD
     LCD5110_DC=command;     // 0是寫命令,1是寫數(shù)據(jù)
     for(i=0;i<8;i++)
     {
          if(dt&0x80)
             LCD5110_SDIN=1;
            else
             LCD5110_SDIN=0;
          dt=dt<<1;      //dt為暫存數(shù)據(jù)   
          LCD5110_SCLK=0;_nop_();                           
          LCD5110_SCLK=1;_nop_();
     }   
     LCD5110_DC=1;   
     LCD5110_CE=1;   
     LCD5110_SDIN=1;
}
void LCD_clear(void) //5110LCD清屏
{
        unsigned int i;
        LCD_write_byte(0x0c, 0);                       
        LCD_write_byte(0x80, 0);                       
        for (i=0; i<504; i++)
        LCD_write_byte(0, 1);                       
}
void LCD_set_XY(unsigned char X, unsigned char Y)  //x 左右共0~83列可移,Y由上至下共0~5行可移
{
                LCD_write_byte(0x40 | Y, 0);        // column         Y+=64
                LCD_write_byte(0x80 | X, 0);  // row                 X+=128
}
void LCD_init(void)        //5110LCD初始化LCD_init
{            
                LCD5110_RES=0;        // 產(chǎn)生一個讓LCD復(fù)位的低電平脈沖
                Delayms(10);
                LCD5110_RES=1;                
                LCD5110_CE = 0;         // 關(guān)閉LCD
                Delayms(10);
                LCD5110_CE = 1;// 使能LCD
                Delayms(10);
                LCD_write_byte(0x21, 0);        // 使用擴(kuò)展命令設(shè)置LCD模式
                LCD_write_byte(0xC2, 0);        // 設(shè)置偏置電壓//不同的屏須要微調(diào)此參數(shù)B9~C9
                LCD_write_byte(0x06, 0);        // 溫度校正
                LCD_write_byte(0x13, 0);        // 1:48
                LCD_write_byte(0x20, 0);        // 使用基本命令
                LCD_clear();                // 清屏
                LCD_write_byte(0x0C, 0);        // 設(shè)定顯示模式,正常顯示      
                LCD5110_CE = 0;  // 關(guān)閉LCD
}
void LCD_P6x8Str(unsigned char x,unsigned char y,unsigned char ch)
{
        unsigned char i;      
        LCD_set_XY(x,y);   
        for(i=0;i<6;i++){        LCD_write_byte(F6x8[ch],1);  }
}

void LCD_P6x8Str5wita(uchar x,uchar y,uchar i)
{
        LCD_P6x8Str(x,y,i%1000/100+16);
        LCD_P6x8Str(x+6,y,i%100/10+16);
        LCD_P6x8Str(x+12,y,i%10/1+16);
}
void main()
{
          uchar dat1,dat2;
                P1M0 = 0x00;
                P1M1 = 0x00;
                P3M0 = 0x00;
                P3M1 = 0x00;
                P5M0 = 0x00;
                P5M1 = 0x00;
    LCD_init();//LCD初始化

                dat2=IapReadByte(IAP_ADDRESS+1);
                LCD_P6x8Str5wita(0,1,dat2);
        while(1)
        {
                               
                        if(!P11)
                        {
                                Delayms(40);
                                if(!P11)
                                {
                                        while(!P11);
                                        dat1++;
                                        LCD_P6x8Str5wita(0,0,dat1);
                                        IapProgramByte(IAP_ADDRESS+1, dat1);
                                        Delayms(100);
                                        dat2=IapReadByte(IAP_ADDRESS+1);
                                        LCD_P6x8Str5wita(0,1,dat2);
                                }
                        }       
                        if(!P10)
                        {
                                Delayms(40);
                                if(!P10)
                                {
                                        while(!P10);
                                        dat1--;
                                        LCD_P6x8Str5wita(0,0,dat1);
                                        IapProgramByte(IAP_ADDRESS+1, dat1);
                                        Delayms(100);
                                        dat2=IapReadByte(IAP_ADDRESS+1);
                                        LCD_P6x8Str5wita(0,1,dat2);
                                }
                        }
        }
       
}

回復(fù)

使用道具 舉報

ID:162242 發(fā)表于 2017-2-22 12:49 | 顯示全部樓層
PS來處理相片 圖片等等
回復(fù)

使用道具 舉報

ID:33544 發(fā)表于 2018-2-26 14:34 | 顯示全部樓層
樓主問題解決了嗎,俺也遇到了同樣的問題,寫入的數(shù)據(jù)和讀出的數(shù)據(jù)不一至,用官方的程序測試的,不知問題出在那,板上的電源電壓正常(5V)。
回復(fù)

使用道具 舉報

ID:69072 發(fā)表于 2018-2-27 08:24 | 顯示全部樓層
如果STC 單片機(jī)內(nèi)部EEPROM某地址上已經(jīng)有數(shù)據(jù)    需要先擦除再寫入
如果本來已經(jīng)有數(shù)據(jù) 就需要 ①讀取內(nèi)部EEPROM并保存數(shù)據(jù)到數(shù)組 ②擦除eeprom數(shù)據(jù) ③再次將修改好的數(shù)據(jù)寫入。  
回復(fù)

使用道具 舉報

ID:213173 發(fā)表于 2018-2-27 20:55 | 顯示全部樓層
STC15W的EEPROM寫入數(shù)據(jù)前必須要把扇區(qū)擦除,沒有看到你程序中有相關(guān)語句!
回復(fù)

使用道具 舉報

ID:313791 發(fā)表于 2020-11-13 13:27 | 顯示全部樓層
可以試試讀取->擦除->寫入的思路
回復(fù)

使用道具 舉報

ID:47286 發(fā)表于 2020-11-13 23:31 | 顯示全部樓層
你這樣不行 這種內(nèi)部EEPROM需要把所有數(shù)據(jù)讀出來 在內(nèi)存里修改需要修改的位 然后擦除整個扇區(qū) 再一起寫進(jìn)去 否則就是你見到的情況 即便你要寫入的數(shù)據(jù)只有1位也要這么操作
回復(fù)

使用道具 舉報

ID:315110 發(fā)表于 2020-11-14 00:37 | 顯示全部樓層
dzbj 發(fā)表于 2020-11-13 23:31
你這樣不行 這種內(nèi)部EEPROM需要把所有數(shù)據(jù)讀出來 在內(nèi)存里修改需要修改的位 然后擦除整個扇區(qū) 再一起寫進(jìn)去 ...

漲姿勢了,居然要這么操作
回復(fù)

使用道具 舉報

ID:278840 發(fā)表于 2020-11-14 14:15 | 顯示全部樓層
看看讀取時間,和存儲的時間,會不會太短了,導(dǎo)致讀取異常
回復(fù)

使用道具 舉報

ID:497980 發(fā)表于 2021-3-24 13:48 | 顯示全部樓層
鳳姐438 發(fā)表于 2018-2-27 08:24
如果STC 單片機(jī)內(nèi)部EEPROM某地址上已經(jīng)有數(shù)據(jù)    需要先擦除再寫入
如果本來已經(jīng)有數(shù)據(jù) 就需要 ①讀取內(nèi)部 ...

very good
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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