搜索
bottom↓
回复: 22

通过bootloader 写一页 flash

[复制链接]

出0入0汤圆

发表于 2009-8-26 11:12:18 | 显示全部楼层 |阅读模式
我参考网上的一些实例,用icc编了这一段写一页flash的代码,请高人帮我看看,这样的写法能不能实现flash写一页操作???
又该如何读取这一页的数据??????

#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>

#define uchar unsigned char  
#define uint unsigned int

#define PAGESIZE   128   //M16的一个Flash页为128字节(64字)
#define PAGESIZE1   64   //M16的一个Flash页为128字节(64字)

uint ADDRESS = 0x0000;
uchar DATA[128] = {0X01};
uchar data1[128] = {0x00};


//擦除(code=0x03)和写入(code=0x05)一个Flash页  
void boot_page_ew(uint p_address,uchar code)  
{
    asm("mov r30,r16\n"
        "mov r31,r17\n"  
        "out 0x3b,r18\n");            //将页地址放入Z寄存器和RAMPZ的Bit0中  
    SPMCR = code;                //寄存器SPMCSR中为操作码  
    asm("spm\n");                    //对指定Flash页进行操作  
}

//填充Flash缓冲页中的一个字  
void boot_page_fill(uint address,uint data)  
{  
    asm("mov r30,r16\n"  
        "mov r31,r17\n"             //Z寄存器中为填冲页内地址  
        "mov r0,r18\n"  
        "mov r1,r19\n");            //R0R1中为一个指令字
    SPMCR = 0x01;  
    asm("spm\n");  
}  

//等待一个Flash页的写完成  
void wait_page_rw_ok(void)  
{  
   while(SPMCR & 0x40)  
     {  
         while(SPMCR & 0x01);  
         SPMCR = 0x11;  
         asm("spm\n");  
     }  
}  
//更新一个Flash页的完整处理  
void write_one_page(uint address,uchar data[])  
{  
    uint i;
uint da[PAGESIZE1];
uchar j;
    boot_page_ew(address,0x03);                    //擦除一个Flash页  
    wait_page_rw_ok();                            //等待擦除完成  
    for(i=0,j=0;i<PAGESIZE;i+=2,j++)                //将数据填入Flash缓冲页中  
    {   
    da[j] = data[i+1];
da[j] = data+ (da[j] <<8 );
        boot_page_fill(i,da[j]);  
    }  
    boot_page_ew(address,0x05);                    //将缓冲页数据写入一个Flash页
    wait_page_rw_ok();                            //等待写入完成  
}

void main()
{
CLI();
MCUCR = 0x00;
TIMSK = 0x00;  
SEI();
write_one_page(0,DATA);
while(1);
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2009-8-26 13:02:56 | 显示全部楼层

flash存储 (原文件名:QQ截图未命名.jpg)

我用以上代码试了试,从上图可以看出,地址00-3f数据已经更新,说明上面的代码可是实现flash写页操作,但是怎么才能用程序读取flash地址的数据呢?

出0入0汤圆

 楼主| 发表于 2009-8-26 13:13:27 | 显示全部楼层
刚才试了下,写入的flash地址不能改,怎么改还是从00开始写入,这是为什么???

出0入0汤圆

 楼主| 发表于 2009-8-28 08:27:05 | 显示全部楼层
这么多人看,怎么就没有指点指点呢,难道这问题太低级了不成??

出0入0汤圆

 楼主| 发表于 2009-8-29 09:06:56 | 显示全部楼层
可以正确的写入了,原来是我地址设的不对。可是怎么样才能将flash一页的数据读出来呢??

出0入0汤圆

发表于 2009-9-5 21:40:11 | 显示全部楼层
记号先,我也想用此功能,前段时间没调也来,看看大家有没有什么好的方法呀!

出0入0汤圆

发表于 2009-9-5 23:47:39 | 显示全部楼层
我怎么就是写不了,熔丝要配置吗?

出0入0汤圆

发表于 2009-9-10 00:11:55 | 显示全部楼层
用指针的方法:

    // ***********************************************************************
    // Read the existing page of flash and save in a temporary buffer.
    // ***********************************************************************   
    ......
    ......
    pbuf = &page_buffer[0];    // buffer的指针
    for (address = pDevCfg; address < pDevCfg + (BLOCKSIZE); address++)
    {  
        // pDevCfg 是要读取的flash页的起始地址
        _WAIT_FOR_SPM();
        _ENABLE_RWW_SECTION();  // necessary to access the flash
        *pbuf++ = _LOAD_PROGRAM_MEMORY(address);
    }

另外,写入的地址必须是页的起始地址,而不能设成任意的地址。

出0入0汤圆

 楼主| 发表于 2009-9-10 08:27:56 | 显示全部楼层
我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代码写在同一个文件里,一起编译,不知道这样行不行,要怎么做。我用过的编译器是iccavr+avrstudio+jtag_ice,请高人指点啊。

出0入0汤圆

发表于 2009-9-29 10:59:39 | 显示全部楼层
谢谢参考你的了

出0入0汤圆

 楼主| 发表于 2009-9-29 13:10:07 | 显示全部楼层
我也是参考别人的,再自己修改修改的。

出0入0汤圆

发表于 2009-10-23 16:34:25 | 显示全部楼层
继续

出0入0汤圆

发表于 2010-3-20 16:10:04 | 显示全部楼层
很不错!!!!!!!!!!!!

出0入0汤圆

发表于 2010-9-9 14:02:32 | 显示全部楼层
是啊,有谁能解答一下8楼的问题啊.

出0入0汤圆

发表于 2010-9-11 00:06:02 | 显示全部楼层
boot区和用户区的代码写在同一个文件里可能不行。但可以把写FLASH代码放在bootloader区,代码用汇编编写。在AAP区调用。

出0入0汤圆

发表于 2010-11-17 21:05:48 | 显示全部楼层
回复【4楼】tong7127
-----------------------------------------------------------------------

我想请问一下  你的页地址是什么格式的?
0 1 2 3这样的
还是0x00   0x10?
或者0x0000  0x0010?

出0入0汤圆

发表于 2011-1-18 19:10:06 | 显示全部楼层
还是没有解决--怎么样才能将flash一页的数据读出来呢?

出0入0汤圆

发表于 2011-11-23 14:49:11 | 显示全部楼层
楼主你好,看看这个吧,我也是看了别的帖子,不晓得对不,但应该有所启发吧~~

winavr里可以用pgm_read_byte(0x1000)读

Bascom-AVR里 用 var = CPEEK( address ) 就可以了
                  address=0 就是读第一个字节了

var = *(__flash unsigned char *)address;通吃,ICC要用const代替__flash

如果要自己编程的话:

//_read_flash::
//unsigned char read_flash(unsigned int add);
unsigned char read_flash(unsigned int add)
{
  asm("mov r31,r17\n"
  "mov r30,r16\n"
  "lpm r16,z\n"
  "clr r17\n"
  "ret\n");
  return 0;
}


对了,我想请教一下,如果我想把数组写进flash,比如数字1,那么在数组里是要写成0x01么?uchar DATA[128] = {0X01};  
uchar data1[128] = {0x00}; 这两个定义是什么意思呢?

出0入0汤圆

发表于 2013-4-24 21:44:58 | 显示全部楼层
LZ,加下QQ937928439,有问题请教下

出0入0汤圆

发表于 2013-4-25 13:17:07 | 显示全部楼层
tong7127 发表于 2009-9-10 08:27
我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代 ...

一起编译可以,但估计需要改链接脚本了

出0入0汤圆

发表于 2013-4-25 13:21:09 | 显示全部楼层
z_zt 发表于 2009-9-5 23:47
我怎么就是写不了,熔丝要配置吗?

熔丝肯定要配置的,因为首先要让处理器复位是从boot区还是从app区开始

出0入0汤圆

发表于 2013-4-25 14:41:25 | 显示全部楼层
zkczy99999 发表于 2010-11-17 21:05
回复【4楼】tong7127
-----------------------------------------------------------------------

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

本版积分规则

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

GMT+8, 2024-7-24 03:27

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

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