通过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);
} http://cache.amobbs.com/bbs_upload782111/files_17/ourdev_474828.jpg
flash存储 (原文件名:QQ截图未命名.jpg)
我用以上代码试了试,从上图可以看出,地址00-3f数据已经更新,说明上面的代码可是实现flash写页操作,但是怎么才能用程序读取flash地址的数据呢? 刚才试了下,写入的flash地址不能改,怎么改还是从00开始写入,这是为什么??? 这么多人看,怎么就没有指点指点呢,难道这问题太低级了不成?? 可以正确的写入了,原来是我地址设的不对。可是怎么样才能将flash一页的数据读出来呢?? 记号先,我也想用此功能,前段时间没调也来,看看大家有没有什么好的方法呀! 我怎么就是写不了,熔丝要配置吗? 用指针的方法:
// ***********************************************************************
// 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);
}
另外,写入的地址必须是页的起始地址,而不能设成任意的地址。 我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代码写在同一个文件里,一起编译,不知道这样行不行,要怎么做。我用过的编译器是iccavr+avrstudio+jtag_ice,请高人指点啊。 谢谢参考你的了 我也是参考别人的,再自己修改修改的。 继续 很不错!!!!!!!!!!!! 是啊,有谁能解答一下8楼的问题啊. boot区和用户区的代码写在同一个文件里可能不行。但可以把写FLASH代码放在bootloader区,代码用汇编编写。在AAP区调用。 回复【4楼】tong7127
-----------------------------------------------------------------------
我想请问一下你的页地址是什么格式的?
0 1 2 3这样的
还是0x00 0x10?
或者0x00000x0010? 还是没有解决--怎么样才能将flash一页的数据读出来呢? 楼主你好,看看这个吧,我也是看了别的帖子,不晓得对不,但应该有所启发吧~~
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}; 这两个定义是什么意思呢? LZ,加下QQ937928439,有问题请教下 tong7127 发表于 2009-9-10 08:27 static/image/common/back.gif
我读写时没问题了。但是又出现了另一个问题,这个读写程序时必须在boot区的,但是我想将boot区和用户区的代 ...
一起编译可以,但估计需要改链接脚本了 z_zt 发表于 2009-9-5 23:47 static/image/common/back.gif
我怎么就是写不了,熔丝要配置吗?
熔丝肯定要配置的,因为首先要让处理器复位是从boot区还是从app区开始 zkczy99999 发表于 2010-11-17 21:05 static/image/common/back.gif
回复【4楼】tong7127
-----------------------------------------------------------------------
页地址还有什么格式啊?地址就是一个字节一个字节的里面装二进制数啊
页:
[1]