tong7127 发表于 2009-8-26 11:12:18

通过bootloader 写一页 flash

我参考网上的一些实例,用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 = {0X01};
uchar data1 = {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;
uchar j;
    boot_page_ew(address,0x03);                  //擦除一个Flash页
    wait_page_rw_ok();                            //等待擦除完成
    for(i=0,j=0;i<PAGESIZE;i+=2,j++)                //将数据填入Flash缓冲页中
    {   
    da = data;
da = data+ (da <<8 );
      boot_page_fill(i,da);
    }
    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);
}

tong7127 发表于 2009-8-26 13:02:56

http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_474828.jpg
flash存储 (原文件名:QQ截图未命名.jpg)

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

tong7127 发表于 2009-8-26 13:13:27

刚才试了下,写入的flash地址不能改,怎么改还是从00开始写入,这是为什么???

tong7127 发表于 2009-8-28 08:27:05

这么多人看,怎么就没有指点指点呢,难道这问题太低级了不成??

tong7127 发表于 2009-8-29 09:06:56

可以正确的写入了,原来是我地址设的不对。可是怎么样才能将flash一页的数据读出来呢??

z_zt 发表于 2009-9-5 21:40:11

记号先,我也想用此功能,前段时间没调也来,看看大家有没有什么好的方法呀!

z_zt 发表于 2009-9-5 23:47:39

我怎么就是写不了,熔丝要配置吗?

jackiegao 发表于 2009-9-10 00:11:55

用指针的方法:

    // ***********************************************************************
    // Read the existing page of flash and save in a temporary buffer.
    // ***********************************************************************   
    ......
    ......
    pbuf = &page_buffer;    // 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);
    }

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

tong7127 发表于 2009-9-10 08:27:56

我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代码写在同一个文件里,一起编译,不知道这样行不行,要怎么做。我用过的编译器是iccavr+avrstudio+jtag_ice,请高人指点啊。

huang__hzl 发表于 2009-9-29 10:59:39

谢谢参考你的了

tong7127 发表于 2009-9-29 13:10:07

我也是参考别人的,再自己修改修改的。

wodetianmyday 发表于 2009-10-23 16:34:25

继续

hpdell 发表于 2010-3-20 16:10:04

很不错!!!!!!!!!!!!

221008 发表于 2010-9-9 14:02:32

是啊,有谁能解答一下8楼的问题啊.

uc-can-m3 发表于 2010-9-11 00:06:02

boot区和用户区的代码写在同一个文件里可能不行。但可以把写FLASH代码放在bootloader区,代码用汇编编写。在AAP区调用。

zkczy99999 发表于 2010-11-17 21:05:48

回复【4楼】tong7127
-----------------------------------------------------------------------

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

MCUEL_21 发表于 2011-1-18 19:10:06

还是没有解决--怎么样才能将flash一页的数据读出来呢?

poipoi09876 发表于 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 = {0X01};
uchar data1 = {0x00}; 这两个定义是什么意思呢?

qinglianyoumeng 发表于 2013-4-24 21:44:58

LZ,加下QQ937928439,有问题请教下

huangshuyi 发表于 2013-4-25 13:17:07

tong7127 发表于 2009-9-10 08:27 static/image/common/back.gif
我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代 ...

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

huangshuyi 发表于 2013-4-25 13:21:09

z_zt 发表于 2009-9-5 23:47 static/image/common/back.gif
我怎么就是写不了,熔丝要配置吗?

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

huangshuyi 发表于 2013-4-25 14:41:25

zkczy99999 发表于 2010-11-17 21:05 static/image/common/back.gif
回复【4楼】tong7127
-----------------------------------------------------------------------



页地址还有什么格式啊?地址就是一个字节一个字节的里面装二进制数啊
页: [1]
查看完整版本: 通过bootloader 写一页 flash