OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2037|回复: 4

单片机内存中变量出错问题

[复制链接]

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
139
金钱
139
注册时间
2015-11-10
在线时间
34 小时
发表于 2019-10-22 15:14:05 | 显示全部楼层 |阅读模式
1金钱
今天敲代码发现一个奇葩问题:在用内部flash做eeprom保存数据时发现:
u8  Set_dev_ID[12]={0}; //全局变量
void usartPacketRecv(void)
{
        u8 Get_DevId_Buf[12]={0};

      if(GetId_Flag) //获取唯一ID
        {
                GetId_Flag=0;
          memcpy(Get_DevId_Buf,PackRecvData,strlen((char *)PackRecvData));

         EEPROM_write_str_change(DEV_ID_ADD,Get_DevId_Buf,12);//保存
         memcpy(Set_dev_ID,Get_DevId_Buf,12);       

    }
}

以上是代码,发现:memcpy(Set_dev_ID,Get_DevId_Buf,12); Get_DevId_Buf有数据,但Set_dev_ID全是0XFF。不知道为什么?
其实我本来是EEPROM_write_str_change(DEV_ID_ADD,Set_dev_ID,12);直接通过Set_dev_ID保存的,但发现Set_dev_ID全是0XFF,也保存不进去,才采用局部变量的,
不知道有没有遇到同样问题的???


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-4-14
在线时间
9 小时
发表于 2019-10-23 09:03:42 | 显示全部楼层
1.Set_dev_ID全是0XFF,可能是EEPROM_write_str_change函数改变了Get_DevId_Buf[]的内容。你调试看下EEPROM_write_str_change执行完之后Get_DevId_Buf[]的内容。
2.对变量Set_dev_ID添加volitate修饰。
回复

使用道具 举报

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
139
金钱
139
注册时间
2015-11-10
在线时间
34 小时
 楼主| 发表于 2019-10-23 11:17:59 | 显示全部楼层
凯旋门的煞气 发表于 2019-10-23 09:03
1.Set_dev_ID全是0XFF,可能是EEPROM_write_str_change函数改变了Get_DevId_Buf[]的内容。你调试看下EEPROM ...

我测试了,是EEPROM_write_str_change函数改变了Get_DevId_Buf[]的内容;但是函数EEPROM_write_str_change只是读取Get_DevId_Buf[]的内容啊,怎么会让他的内容改变;
还有添加volitate我也试了,没有作用
回复

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2015-4-14
在线时间
9 小时
发表于 2019-10-23 12:58:05 | 显示全部楼层
kzero9 发表于 2019-10-23 11:17
我测试了,是EEPROM_write_str_change函数改变了Get_DevId_Buf[]的内容;但是函数EEPROM_write_str_chang ...

说明这个函数写的有bug,不妨贴出来
回复

使用道具 举报

14

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
139
金钱
139
注册时间
2015-11-10
在线时间
34 小时
 楼主| 发表于 2019-10-23 15:05:30 | 显示全部楼层
凯旋门的煞气 发表于 2019-10-23 12:58
说明这个函数写的有bug,不妨贴出来

这是我操作flash的代码:
void EEPROM_write_str_change(u32 Writeadd,u8 *writebuf,u16 write_num)
{  
        u16 count = 0;
        u16 New_p;
        u16 count_max;
        u32  PageAddr;
        u16  writetemp;
        u16  temp[512];
  
        if(write_num%2) write_num++; //
        if(Writeadd%2)  Writeadd++;               
                             //0xfffffc00
        PageAddr = Writeadd&EEPOM_MASK_PAGE_SIZE;
        //=============保存原数====================
       
        for(count=0;count<512;count++)
    {
                 temp[count]=*(u16 *)(PageAddr);
                 PageAddr+=2;
        }
        //填充新数=================================
        New_p=0;
        count_max=(Writeadd%1024)/2;
        for(count=count_max;count<512;count++)
        {
                        writetemp=writebuf[New_p+1];
                        writetemp<<=8;
                        writetemp+=writebuf[New_p];
                        temp[count]=writetemp;
                        New_p+=2;
                        if(New_p>=write_num)//数据已完
                                break;
        }
        //擦除当前页=================================
        PageAddr = Writeadd&EEPOM_MASK_PAGE_SIZE;
        EEPROM_erasepage(PageAddr);
        //更新页内新内容                 
        FLASH_Unlock();//解锁
        FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
        count = 0;
        for(count=0;count<512;count++)
        {     
                FLASH_ProgramHalfWord((PageAddr+(count*2)),temp[count]);
        }
        //=====没有写完但已跨页=======================================  
        writetemp=1024-(Writeadd%1024);
        if(writetemp<write_num)
        { //剩余字节数
                write_num-=writetemp;//减去已写入的字节数
                PageAddr+=0x400;
                for(count=0;count<(write_num/2);count++)
                {
                        writetemp=writebuf[New_p+1];
                        writetemp<<=8;
                        writetemp+=writebuf[New_p];
                        temp[count]=writetemp;
                        New_p+=2;
                }
                for(;count<512;count++)
                {
                        temp[count]=*(u16 *)(PageAddr+(count*2));
                }
                EEPROM_erasepage(PageAddr);
                FLASH_Unlock();//解锁
                FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
                count = 0;
                while(count<512)
                {     
                        FLASH_ProgramHalfWord((PageAddr+(count*2)),temp[count]);
                        count++;
                }
        }               
        FLASH_Lock();
}
读flash的代码就是提问的代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表