fangjikun 发表于 2015-5-20 15:19:47

将16位数据拆成两个8位存EEPROM,读出时数据变了


如题,将一个16位的数据(41396,0xa1af)存进EEPROM:
unsigned int i=41396;
WREN=1;//使能写
EEPROM_WRITE(244,i>>8);       / /高8位
      while(WR==1); //等待写完
EEPROM_WRITE(245,i);   //低8位
      while(WR==1);//等待写完
      WREN=0;//禁止写
//将i值送液晶屏显示,程序略
写进后读出:
i= (EEPROM_READ(244)<<8)|EEPROM_READ(245);
//将i值送液晶屏显示,程序略读出后数据成了44975,0xafaf
为什么?

fangjikun 发表于 2015-5-20 18:29:13

现在确认为读出的问题: i= (EEPROM_READ(244)<<8)|EEPROM_READ(245); 改为: i = EEPROM_READ(244); i = i <<8 | EEPROM_READ(245); 就可以了

mon51 发表于 2015-5-21 10:08:23

为何不做一个通用的数据块读取函数?每一次读写,只要制定长度+首地址就可以了。

mon51 发表于 2015-5-21 10:12:02

/*****************************************
定义菜单的默认值
*******************************************/
MP1 const P1Rom={
        0,                //地址
        9600,
        'A','S','5','0',//名字
        1,        //a
        0,        //b
        1,        //采集时间 1S,2S,3S,5S,10S,20S,30S,60S可选
        //------------------------------------- crc
        IDK,                //ID
        0,                        //crc 2009-2-20
};
MENUASC        const MenuAsc[]={
        Int,        //设备的地址
        Int,        //波特率
        //--------------------------------- 1#
        CHAR4,        //从机的名字
        Float,        //计算参数
        Float,        //计算参数
        Int,                //初始角度!
};
//******************************************************************************
//计算参数的地址
//******************************************************************************
unsigned char *GetAdr(unsigned char IndeX,unsigned char *Adr){
        unsigned char i,k=0;
        for(i=0;i<IndeX;i++) k +=MenuAsc.Type & 0x1f;//关闭负数的标志
        return (Adr+k);
}
/**********************************************************
校验字节
***********************************************************/
unsigned char GetJiaoData(unsigned char *pBuf,unsigned int Long){
        unsigned char j;
       
        j=0;
        while (Long--)        j += *pBuf++;
        return j;
}
//************************************************************
//M=0是常用菜单;=1是备用菜单
//************************************************************
void WriteToEexx(unsigned int adr){

        if(adr==rom_MP_ADR || adr==rom_MP_ADR_ghost){
                Mp1.ID=IDK;
                Mp1.crc=0;
                Mp1.crc=GetJiaoData((unsigned char *)&Mp1,sizeof(Mp1));
                WrFlash((unsigned int *)&Mp1,rom_MP_ADR,sizeof(Mp1));                        //全部写入一次!
                WrFlash((unsigned int *)&Mp1,rom_MP_ADR_ghost,sizeof(Mp1));                //全部写入一次!
        }
}
//**********************************************************************************
//初始化菜单参数到2个地址的ROM中
void Init_MP1(unsigned int adr){
       
        memcpy((unsigned char *)&Mp1,(unsigned char *)&P1Rom,sizeof(Mp1));
        WriteToEexx(adr);
        JB_Sn();
}

//**********************************************************************************
//返回=1 校验OK
//**********************************************************************************
//***********************************************************************************
//返回数据正确标志=0 ok;=1数据坏!
unsigned char Rd_MP_Dat(unsigned char *p,unsigned int adr){
   
        MP1 *pr;
        unsigned char sum;
        RdFlash(p,adr,sizeof(MP1));          //全部读出来!
        pr=(MP1 *)p;
        sum=pr->crc;
        pr->crc=0;
        if(sum==GetJiaoData(p,sizeof(MP1)) && pr->ID ==IDK){//继续读菜单
                pr->crc=sum;
                sum=0;
        }else{
                sum=1;
        }       
        return sum;
}
/***********************************************************************************
如果FIRST!=fIRST写入FLASHROM中
************************************************************************************/
void ReadMP(unsigned int adr){

        if(adr==rom_MP_ADR){
                if(Rd_MP_Dat((unsigned char *)&Mp1,adr)){
                        if(Rd_MP_Dat((unsigned char *)&Mp1,rom_MP_ADR_ghost))                Init_MP1(adr); //读取程序默认的参数表
                }
        }
}
//************************************************************************************/
void Jb_First(){
        ReadMP(rom_MP_ADR);
}







mon51 发表于 2015-5-21 10:13:13

                WrFlash((unsigned int *)&Mp1,rom_MP_ADR,sizeof(Mp1));                        //全部写入一次!
                Rd_MP_Dat((unsigned char *)&Mp1,adr);

mon51 发表于 2015-5-21 10:14:26

//**********************************************************************
typedef struct{
        unsigned int                Ar;                                                //地址
        unsigned int                Bps;                                        //波特率
        unsigned char                Name;                        //从机的名字!
        float                                                a;                                                //a风速的系数 V=b+a*F
        float                                                b;                                                //b系数
        unsigned int                t;                                           //采集时间 1S,2S,3S,5S,10S,20S,30S,60S可选
        unsigned int                ID;                                                //2009-2-20 添加一个特征值。
        unsigned int           crc;
}MP1;

lbhj310 发表于 2015-5-21 11:36:12

fangjikun 发表于 2015-5-20 18:29
现在确认为读出的问题: i= (EEPROM_READ(244)

是不是函数EEPROM_READ()返回值应该已定义为8位数据?
试试加入强制类型转换
i= (((unsigned int)EEPROM_READ(244))<<8)|EEPROM_READ(245)

yangsen 发表于 2015-5-21 11:44:22

估计是7楼说的问题,数据类型问题。

jxcrg_t35 发表于 2015-5-21 14:24:50

强制转换一下

zhugean 发表于 2015-5-21 14:41:26

lbhj310 发表于 2015-5-21 11:36
是不是函数EEPROM_READ()返回值应该已定义为8位数据?
试试加入强制类型转换
i= (((unsigned int)EEPROM_ ...

C语言有默认整型提升,所以不是这个问题

huarana 发表于 2015-5-23 22:50:05

zhugean 发表于 2015-5-21 14:41
C语言有默认整型提升,所以不是这个问题

根据楼主2楼的描述

应该就是那个问题

要强制转换,你说的自动提升是跟编译器有关的

zhugean 发表于 2015-5-25 08:18:26

huarana 发表于 2015-5-23 22:50
根据楼主2楼的描述

应该就是那个问题


大多数编译器都是默认整型提升的
而且如果没有提升的话结果也应该是高字节为零而不是LZ的结果
页: [1]
查看完整版本: 将16位数据拆成两个8位存EEPROM,读出时数据变了