搜索
bottom↓
回复: 30

S3F94C4嵌入式闪存操作之疑问

[复制链接]

出0入0汤圆

发表于 2012-3-28 09:11:29 | 显示全部楼层 |阅读模式
__no_init uchar read_datum@0x10;

//擦除EEPROM不能进中断,擦除flash时,CPU至少停止4ms
void EraseFlash(uint address)
{
        FMUSR=0xa5;
        //asm("LD FMSECH,R14");
        //asm("CLR  FMSECL");
  FMSECH=address>>8;
  FMSECL=0;
        FMCON=0XA1;
//        while(FMCON&0X01);        //等待擦除完成
        FMUSR=0X00;       
}

//start_address工作寄存器为R14,R15;datum工作寄存器的R12,R13;
//number的工作寄存器为R11。
void FlashWritBytes(uint start_address,uchar *datum,uchar number)
{       
  asm("PUSH R9");
        asm("LD  FMUSR,#0A5H");
  FMCON=0X50;       
        //asm("LD FMSECH,R14");
        //asm("CLR  FMSECL");
  FMSECH=start_address>>8;
  FMSECL=0;
        for(;number>0;number--)
        {
                asm("LD R9,@R13");
                asm("LDC @RR14,R9");
                asm("INC R15");
                asm("INC R13");
  }               
        asm("LD  FMUSR,#00H");          
        asm("POP R9");
}


uchar FlashReadByte(uint address)
{
  asm("PUSH R9");  
        asm("LDC R9,@RR14");
  asm("LD 0X10,R9");  
        asm("POP R9");  
        return(read_datum);
}

出0入0汤圆

 楼主| 发表于 2012-3-28 09:26:05 | 显示全部楼层
上面是我对嵌入式闪存(相当于Eeprom)的操作,使用编译环境为SAM IAR  1.3,在uchar FlashReadByte(uint address)函数中,我定义了一个绝对定位变量read_datum@0x10,才顺利的返回了读EEPROM返回的参数。如果我C语言指针时
uchar FlashReadByte(uint address)
{
unsigned char read_datum;
read_datum=*((uchar*)address);
return(read_datum);
}
在三星数据传送中有这两个指令
LD dst,src  传送数据
LDC dst,src  传送数据 ( 访问程序存储空间)
编译成功后,查看反汇编,
read_datum=*((uchar*)address);
被LD指令翻译过来了,应该是用LDC指令。

如何定义指针才会翻译成对应的指令用LDC

出0入0汤圆

发表于 2012-3-28 10:27:08 | 显示全部楼层
顶下!

出0入0汤圆

发表于 2012-3-29 23:35:46 | 显示全部楼层
是F9454吧

出0入0汤圆

 楼主| 发表于 2012-3-30 13:40:53 | 显示全部楼层
logicgreen 发表于 2012-3-29 23:35
是F9454吧

不是,就是S3F94C4。S3F9454没有EEPROM,S3F94C4跟S3F9454的区别就是:S3F94C4比S3F9454多一个EEPROM(实际上和STC的EEPROM相似,不是真正的EEPROM)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-11-23 21:17:45 | 显示全部楼层
楼主有没有解决问题,我也遇到跟你一样的问题

出0入0汤圆

 楼主| 发表于 2012-11-24 09:10:07 | 显示全部楼层
chenchunlin 发表于 2012-11-23 21:17
楼主有没有解决问题,我也遇到跟你一样的问题

我发的程序时可以用的,用汇编加C语言绝对定位变量!

出0入0汤圆

发表于 2012-11-24 14:01:56 | 显示全部楼层
第一次用三星的芯片,很多东西不懂
再请教你一下,我用的编译器是:
IAR C Compiler for Samsung SAM8  2.30C/W32 (2.30.3.3)

头文件没有ioS3F94C4.h  现在用的头文件是ioS3C9454.h 这个可以吗?

出0入0汤圆

 楼主| 发表于 2012-11-24 15:38:19 | 显示全部楼层
chenchunlin 发表于 2012-11-24 14:01
第一次用三星的芯片,很多东西不懂
再请教你一下,我用的编译器是:
IAR C Compiler for Samsung SAM8  2.3 ...

可以的。S3F9454是flash单片机,S3C9454是OTP的。编译器最新的IAR 3.1的,3.1的比2.3的好用,论坛里有3.1的。


出0入0汤圆

发表于 2012-11-24 16:35:01 | 显示全部楼层
zhikunWang 发表于 2012-11-24 15:38
可以的。S3F9454是flash单片机,S3C9454是OTP的。编译器最新的IAR 3.1的,3.1的比2.3的好用,论坛里有3.1 ...

IAR for SAM8  v3.10A 里面也没有ioS3F94C4头文件只有 ioS3C9454的头文件,现在只能自己做一个这样的文件,请问你也是这样吗?

出0入0汤圆

 楼主| 发表于 2012-11-24 16:40:37 | 显示全部楼层
chenchunlin 发表于 2012-11-24 16:35
IAR for SAM8  v3.10A 里面也没有ioS3F94C4头文件只有 ioS3C9454的头文件,现在只能自己做一个这样的文件 ...



安装好应该是有的!默认安装的情况下载在C:\Program Files\IAR Systems\Embedded Workbench 5.4 Evaluation\SAM8\inc文件下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-11-24 17:24:37 | 显示全部楼层
zhikunWang 发表于 2012-11-24 16:40
安装好应该是有的!默认安装的情况下载在C:\Program Files\IAR Systems\Embedded Workbench 5.4 Evalua ...

非常感谢你的热心帮助,再问一下,你上面的程序可以读写单字节flash 吗? 还是只能写指定扇区?

出0入0汤圆

 楼主| 发表于 2012-11-26 10:07:48 | 显示全部楼层
chenchunlin 发表于 2012-11-24 17:24
非常感谢你的热心帮助,再问一下,你上面的程序可以读写单字节flash 吗? 还是只能写指定扇区? ...

不知道你用的是S3F945单片机还是S3F94C4单片机?

出0入0汤圆

发表于 2012-11-28 14:53:44 | 显示全部楼层
我用S3F94C4的单片机

出0入0汤圆

 楼主| 发表于 2012-11-28 16:01:12 | 显示全部楼层
chenchunlin 发表于 2012-11-28 14:53
我用S3F94C4的单片机

1楼的程序完全可以使用,我目前就是这样操作的!C语言插入汇编!

出0入0汤圆

发表于 2012-11-28 20:38:50 | 显示全部楼层
谢谢,等过两天有烧录器试一下,

出0入0汤圆

发表于 2012-11-30 10:17:36 | 显示全部楼层
zhikunWang 发表于 2012-11-28 16:01
1楼的程序完全可以使用,我目前就是这样操作的!C语言插入汇编!

楼上的代码不能直接使用,但是下面的代码可以的
下面的代码也是网上找到的



void FLASH_WRITE(Uint addr,Uchar data) //对同一地址的写操作必须先做擦除操作
{ Uchar temp;
  FlashDt = data;
  FlashAddr = addr;
  temp = addr;
  if (temp<0x80)
  {
    addr -= temp;
  }
  else
  {
    temp -= 0x80;
    addr -= temp;
  }
         

  FMUSR = 0xa5; //使能用户模式(使能flash操作)
  FMSECL = addr; //7f80H为欲进行写操作扇区的第一个地址
  FMSECH = addr >>8;
  do //若擦除不成功则重新擦除
  { FMCON = 0xa1;
    __no_operation();
    __no_operation();
    while(FMCON & 1==1); //等待本次擦除完成后再继续操作
  }
  while (FMCON & 0x4 == 0x4);
   
//write the specific data to the specific address
  FMCON = 0x50; //定义操作类型为 写
  asm("PUSH R0");
  asm("PUSH R2");
  asm("PUSH R3");
  asm("LDW RR2,FlashAddr"); // 必须是全局变量
  asm("LD R0, FlashDt"); // 必须是全局变量
  asm("LDC @RR2,R0");
  asm("POP R0");
  asm("POP R2");
  asm("POP R3");
  __no_operation();
  FMUSR = 0; //关闭用户模式
   
}

出0入0汤圆

 楼主| 发表于 2012-11-30 12:03:05 | 显示全部楼层
chenchunlin 发表于 2012-11-30 10:17
楼上的代码不能直接使用,但是下面的代码可以的
下面的代码也是网上找到的

1楼程序时可以使用的,我把读、写、擦除程序分开了。先执行擦除,在写就可以了!
这些代码我一直在我的程序使用的!

出0入0汤圆

发表于 2012-11-30 20:11:39 | 显示全部楼层
zhikunWang 发表于 2012-11-30 12:03
1楼程序时可以使用的,我把读、写、擦除程序分开了。先执行擦除,在写就可以了!
这些代码我一直在我的程 ...


__no_init uchar read_datum@0x10;

//擦除EEPROM不能进中断,擦除flash时,CPU至少停止4ms
void EraseFlash(uint address)
{
        FMUSR=0xa5;
        //asm("LD FMSECH,R14");
        //asm("CLR  FMSECL");
  FMSECH=address>>8;
  FMSECL=0;
        FMCON=0XA1;
//        while(FMCON&0X01);        //等待擦除完成
        FMUSR=0X00;        
}


上面被注释掉的代码需要使用吗?
还是一摸一样拷贝楼上的代码?
谢谢!

出0入0汤圆

 楼主| 发表于 2012-11-30 21:10:03 | 显示全部楼层
chenchunlin 发表于 2012-11-30 20:11
__no_init uchar read_datum@0x10;

//擦除EEPROM不能进中断,擦除flash时,CPU至少停止4ms

//后的代码不需要! 还有就是操作EEPROM的时候要关闭全局中断

出0入0汤圆

发表于 2012-11-30 21:38:11 | 显示全部楼层
zhikunWang 发表于 2012-11-30 21:10
//后的代码不需要! 还有就是操作EEPROM的时候要关闭全局中断

明白, 楼上的程序是可以的,刚刚测试过
请问,IAR 中,如何得到定义在flash上的数组的地址,
比如:
__root const  U8 eep_data[4] @0x0040 = {0x0,0x0,0xe4,0x00};
unsigned intr address;


如果我想得到eep_data[0]在flash上的地址
address=@eep_data;  
这个好像不行的,

出0入0汤圆

发表于 2012-12-7 12:18:20 | 显示全部楼层
zhikunWang 发表于 2012-11-30 21:10
//后的代码不需要! 还有就是操作EEPROM的时候要关闭全局中断

你好,直接使用楼上的代码,擦除的时候会死机,
这个是我参考S3F94C4  datasheet编写的代码
有的时候可以用,但是不稳定,有的到时候不能用,断电后启动读取的数值为0
以下是部分程序

__root const  volatile U16 EEP_MOTORtime @0x0040= 4500;
__root const  volatile U16 EEP_VALEVtime  @0x0050= 980;

U16   MOTORtime=0;
U16   VALEVtime =0;

void Write_Flash_routine(U16 address,U8 data)
{
        asm("di");
    asm("PUSH R9");  
     asm("PUSH R10");
     asm("PUSH R11");
     flashDATA=data;
     flashADDL=(U8)address;
     flashADDH=(U8)(address>>8);
     FMUSR=0xa5;
     FMCON=0x50;
     FMSECH=0;
     FMSECL=flashADDL;
     asm("LD  R9, flashDATA");
     asm("LD  R10, flashADDH");
     asm("LD  R11, flashADDL");
     asm("LDC @RR10, R9");
     asm("LD  FMUSR, #00H");
     asm("POP R9");
     asm("POP R10");
     asm("POP R11");

     asm("ei");
}

void main()
{
     asm("DI");
     InitMCU();
     asm("EI");
     MOTORtime=EEP_MOTORtime ;
     VALEVtime =EEP_VALEVtime  ;
     while(1)
    {
          if(second_flag)       // 1秒钟定时标志
          {
                     second_flag=0;
                    Write_Flash_routine(0x0040,(U8)(MOTORtime_data>>8));
                    __delay_100us();
                     Write_Flash_routine(0x0041,(8)MOTORtime_data);
                   __delay_100us();
                    Write_Flash_routine(0x0040,(U8)(VALEVtime _data>>8));
                    __delay_100us();
                     Write_Flash_routine(0x0041,(8)VALEVtime _data);
         }
             。。。。。。。。。。。。。




   }



}


出0入0汤圆

 楼主| 发表于 2012-12-7 17:09:09 | 显示全部楼层
chenchunlin 发表于 2012-12-7 12:18
你好,直接使用楼上的代码,擦除的时候会死机,
这个是我参考S3F94C4  datasheet编写的代码
有的时候可以 ...

在擦除函数前加关总中断,擦除完开总中断,应该在擦除EEPROM的时候发生中断,会发生所谓的死机现象!
我的代码用了很久,不会有问题的!

出0入0汤圆

发表于 2015-9-16 11:52:00 | 显示全部楼层
楼主,你好!我按照你的代码,测试没有成功,能否指导一下

出0入0汤圆

 楼主| 发表于 2015-9-16 12:17:35 | 显示全部楼层
xiaoguo_nihao 发表于 2015-9-16 11:52
楼主,你好!我按照你的代码,测试没有成功,能否指导一下

首先你的单片机是S3F9454吗?然后注意的就是关总中断,再执行以下操作。

出0入0汤圆

发表于 2015-9-16 12:52:17 | 显示全部楼层
楼主,在线吗?
能否指导一下,谢谢

出0入0汤圆

发表于 2015-9-16 12:52:52 | 显示全部楼层
zhikunWang 发表于 2015-9-16 12:17
首先你的单片机是S3F9454吗?然后注意的就是关总中断,再执行以下操作。

我的芯片是 S3F94C4

出0入0汤圆

发表于 2015-9-16 12:53:33 | 显示全部楼层
我怕调用时,写错。

出0入0汤圆

发表于 2015-9-16 12:56:24 | 显示全部楼层
我按照上面,照抄进去。
FlashWritBytes(uint start_address,uchar *datum,uchar number)
FlashWritBytes(0x0100,数组名,数量)

FlashReadByte(uint address)
FlashReadByte(0x0100)
是不是 调用有问题

出0入0汤圆

 楼主| 发表于 2015-9-16 13:09:39 | 显示全部楼层
看看手册里的汇编示例。我已经很久不用这个单片机了。

出0入0汤圆

 楼主| 发表于 2015-9-16 13:16:52 | 显示全部楼层
EraseFlash(0x0000);     
FlashWritBytes(0x0000,save_setting_buffer,8);

eeprom的地址你看一下,我用的时候是从0X0000开始的,是成功的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 14:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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