打印
[STM32]

亲们,怎么在AT24C08里存储结构体数据呢,

[复制链接]
5571|9
手机看帖
扫描二维码
随时随地手机跟帖
沙发
peter_wjp| | 2014-8-11 22:02 | 只看该作者
上代码:)

使用特权

评论回复
板凳
wang12zhe|  楼主 | 2014-8-12 07:47 | 只看该作者
peter_wjp 发表于 2014-8-11 22:02
上代码

我调用STM32F4库函数里的EEPROM读写函数向EEPROM里写数据

当写入u8型数组的时候
for(i=0;i<30;i++)ReadTmp=i+1;

  sEE_WriteBuffer(ReadTmp, FRMODVAILD标志寄存器ADDR, 30); //写信息区
tmp=30;
for(i=0;i<30;i++)ReadTmp=0;
sEE_ReadBuffer(ReadTmp, FRMODVAILD标志寄存器ADDR, &tmp);  
   
写入和读出的数据相同,

但是当我写入结构体的时候,发现读出的数据不是我写入的,全部是0,应该是没读正确,
根据u8型数组的测试,可以断定读写函数没错

下面是我结构体的定义
typedef struct
{
union ASSEMBLY_TEST_CMD cmd; //输出 控制命令
union ASSEMBLY_TEST_INPUT input; //输入 控制命令
          u8 StartTest:1;//开始测试标志
    struct   //需要掉电保存的数据
    {
u8 TestMethod:2;//1—方式一,2-方式二  
u8   res         :5; //保留
u16 OpenTime;//门开齐后延时的时间
u16 CloseTime;//门关齐后延时的时间
u16 TestCNT; //测试次数上限
u16 Stallcnt; //堵转次数上限
    }Method;
u16 u16_OpenCnt; //开门次数
u16 u16_OpenFullCnt;//开门到位次数
u16 u16_CloseCnt;//关门次数
u16 u16_CloseFullCnt;//关门到位次数
u16 u16_Close23cnt;//关门2/3次数
u16 u16_uStallCnt;  //堵转次数
u8  uTestResault;
u16 Step;            //测试步骤

u16 ControllerNum;   //控制器号
u8 tmp_cdfull;       //关门到位标志
u8 tmp_odfull;        //开门到位标志
u16 TestTimeCnt;      //测试时间变量                                           // };
u16 DelayCheckTime;
u16 CmdSwTimeCnt;
u16 uSeqTimeCnt;
u8 cSeqStep;

}ASSEMBLY_TEST_STRUCT;
//===============================================================================


#define ASSEMBLY_TEST_STRUCT_DEFAULTS {\
        0,\
         0,\
         0,\
         0,\
         0,\
         5000,\
         5000,\
         1000,\
         20,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         0,\
         5000,\
         5000,\
         5000,\
         5000,\
         0,\
        }

ASSEMBLY_TEST_STRUCT g_hAssemblyTestVar[2] = {ASSEMBLY_TEST_STRUCT_DEFAULTS,ASSEMBLY_TEST_STRUCT_DEFAULTS};
  

下面是我的读写操作

sEE_WriteBuffer((uint8_t*)&(g_hAssemblyTestVar[0].Method), FRMODADDR,sizeof(g_hAssemblyTestVar[0].Method));   
sEE_ReadBuffer((uint8_t*)&(g_hAssemblyTe.Method), FRMODADDR, &tmp);

g_hAssemblyTe.Method的值和g_hAssemblyTestVar[0].Method不一样, g_hAssemblyTe.Method全是0,

我使用的读写函数是库里的函数,路径是STM32F4xx_DSP_StdPeriph_Lib_V1.0.1\Utilities\STM32_EVAL\STM3240_41_G_EVAL里的stm324xg_eval_i2c_ee.c
请问这是哪里问题

记得以前使用51的时候直接读写结构体是可以的啊

使用特权

评论回复
地板
ayb_ice| | 2014-8-12 07:59 | 只看该作者
把结构体按字节顺序存起来就可以了

使用特权

评论回复
5
wang12zhe|  楼主 | 2014-8-12 20:03 | 只看该作者
ayb_ice 发表于 2014-8-12 07:59
把结构体按字节顺序存起来就可以了

但是我试了好几种办法不是编译不正确 就是读出不正确,
你有相关的例子吗,能参考一下吗?

使用特权

评论回复
6
zhaoyu2005| | 2014-8-12 20:17 | 只看该作者
wang12zhe 发表于 2014-8-12 20:03
但是我试了好几种办法不是编译不正确 就是读出不正确,
你有相关的例子吗,能参考一下吗? ...

将结构体的指针进行强制类型转换后,就可以一个字节一个自己存了,当然读取也一样,用sizeof取下结构体的长度

使用特权

评论回复
7
coody| | 2014-8-12 20:32 | 只看该作者
用指针啊。。。

使用特权

评论回复
8
luxianyou527| | 2014-8-12 23:25 | 只看该作者
只是大概看了楼主的结构体声明,可能是由于字节不对齐的原因,可以试试结构体声明时强制字节对齐,GCC环境可以试试__attribute__ ((packed)),MDK环境可以试试 __packed

使用特权

评论回复
9
ayb_ice| | 2014-8-13 05:09 | 只看该作者
根本就不用对齐,
按字节顺序存,按字节顺序读就可以了
大小用sizof

使用特权

评论回复
10
wang12zhe|  楼主 | 2014-8-18 19:14 | 只看该作者
ayb_ice 发表于 2014-8-13 05:09
根本就不用对齐,
按字节顺序存,按字节顺序读就可以了
大小用sizof

我将结构体定义改成这样,

#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐

typedef struct
{
union ASSEMBLY_TEST_CMD cmd; //输出 控制命令
union ASSEMBLY_TEST_INPUT input; //输入 控制命令
u8 StartTest:1;//开始测试标志
u8 TestMethod:2;//1—方式一,2-方式二  
u8   res         :5; //保留
u16 OpenTime;//门开齐后延时的时间
u16 CloseTime;//门关齐后延时的时间

u16 TestCNT; //测试次数上限
u16 Stallcnt; //堵转次数上限
u16 u16_OpenCnt; //开门次数
u16 u16_OpenFullCnt;//开门到位次数
u16 u16_CloseCnt;//关门次数
u16 u16_CloseFullCnt;//关门到位次数
u16 u16_Close23cnt;//关门2/3次数
u16 u16_uStallCnt;  //堵转次数

u16 Step;            //测试步骤

u16 ControllerNum;   //控制器号
u8 tmp_cdfull;       //关门到位标志
u8 tmp_odfull;        //开门到位标志
u16 TestTimeCnt;      //测试时间变量                                           // };
u16 DelayCheckTime;
u16 CmdSwTimeCnt;
u16 uSeqTimeCnt;
u8 cSeqStep;
u8 uTestResault;
}ASSEMBLY_TEST_STRUCT;
#pragma pack(pop)//恢复对齐状态



ASSEMBLY_TEST_STRUCT g_hAssemblyTestVar[2]; //定义结构体数组

  
我这样调用:  
   sEE_WriteBuffer(g_hAssemblyTestVar, 0, sizeof(g_hAssemblyTestVar[0]));
  编译报错:
   Error[Pe167]: argument of type "struct <unnamed> *" is incompatible with parameter of type "uint8_t *" E:\road\OTISTest201408_3\user\src\main.c 26

我这样调用:
  sEE_WriteBuffer((uint8_t)g_hAssemblyTestVar, 0, sizeof(g_hAssemblyTestVar[0]));
编译报错:
Error[Pe167]: argument of type "uint8_t" is incompatible with parameter of type "uint8_t *" E:\road\OTISTest201408_3\user\src\main.c 26


我这样调用:编译通过了,
  sEE_WriteBuffer((uint8_t*)g_hAssemblyTestVar, 0, sizeof(g_hAssemblyTestVar[0]));
  
但是我有疑问:
g_hAssemblyTestVar本身就代表地址

那么再强制转换成(uint8_t*)  这是得到的是什么,
我试过,读出的不正确 全部是0
  
  
  
  其中  sEE_WriteBuffer((uint8_t*)g_hAssemblyTestVar, 0, sizeof(g_hAssemblyTestVar[0]));函数的定义如下
  /**
  * @brief  Writes buffer of data to the I2C EEPROM.
  * @param  pBuffer : pointer to the buffer  containing the data to be written
  *         to the EEPROM.
  * @param  WriteAddr : EEPROM's internal address to write to.
  * @param  NumByteToWrite : number of bytes to write to the EEPROM.
  * @retval None
  */
void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{

}

我用的是IAR

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

101

主题

205

帖子

1

粉丝