lovewwy 发表于 2011-2-21 19:14:08

请假各位一个430写FLASH 的问题。

我采用按块批量写的方式。即:FCTL1 = FWKEY + WRT + BLKWRT;
此时写入最少是64字节。我如果往info Flash里写数据,比如 A段地址是1080h到10FFh。
我可不可以从 1090的地址开始写数据吗?这样的写2个Block,就会越过A段了。
还是必须64个字节一定要写到一个block里面?
谢谢了。

liuzq1981 发表于 2011-2-22 08:16:38

写是可以的,根据你的设计需要,只要数据指针正确就行。
就是擦除的时候麻烦点,应为info Flash是段擦除,一次擦除64个字节。
不过把存储区数据规划好了,没有问题。

Icyan 发表于 2011-2-22 08:23:15

回复【1楼】liuzq1981
-----------------------------------------------------------------------

没有问题么?
听说段写入的话,程序要在RAM里执行,况且,速度只提高了10%左右

xuanyusyj 发表于 2011-2-22 08:33:52

不是这样的,如果程序在flash中运行,执行flash的擦除写入操作时,CPU的控制权会交出不会继续执行程序;等flash的擦除写入完成时CPU才继续向下执行程序。如果程序在RAM运行时,执行flash的擦除写入操作时程序必须判断flash的擦除写入是否已经完成;要等到flash的擦除写入完成时才能执行下面的程序

lovewwy 发表于 2011-2-22 09:57:53

先谢谢楼上几位了。
那怎么知道程序是在flash中运行还是在ram中运行?需要设置什么吗?

weuser 发表于 2011-2-22 11:56:56

info 、ram、 flash,还有内置的loader是独立的区域。在一个区域可以擦、写另一个区域,所以在flash里写info可以,如果是写flash就必须到RAM里运行 写操作,或者用内置的LOADER了。

PC指向RAM地址,就说明在执行RAM中的代码,就是“在RAM里运行”。

weuser 发表于 2011-2-22 12:00:42

写最小可以是字节,但是擦除最小就是 段。

lovewwy 发表于 2011-2-22 13:27:56

回复【5楼】weuser 闪
info 、ram、 flash,还有内置的loader是独立的区域。在一个区域可以擦、写另一个区域,所以在flash里写info可以,如果是写flash就必须到ram里运行 写操作,或者用内置的loader了。
pc指向ram地址,就说明在执行ram中的代码,就是“在ram里运行”。
-----------------------------------------------------------------------

那写FLASH的话,怎么在RAM 里运行操作啊?在程序里,可以把变量用 局部变量表示,使它存在RAM里,但是代码不是都在FLASH里吗?
要先想办法把运行的代码复制到RAM里?

lovewwy 发表于 2011-2-22 19:14:41

回复【5楼】weuser 闪
info 、ram、 flash,还有内置的loader是独立的区域。在一个区域可以擦、写另一个区域,所以在flash里写info可以,如果是写flash就必须到ram里运行 写操作,或者用内置的loader了。
pc指向ram地址,就说明在执行ram中的代码,就是“在ram里运行”。
-----------------------------------------------------------------------

还有,我看用户手册里给的汇编程序,为啥我感觉从flash里和从ram里没啥区别啊?除了ram里进行了wait位跟busy位的判断。

lovewwy 发表于 2011-2-23 10:53:32

自己再顶一下

weuser 发表于 2011-2-28 09:42:31

我写的一个LOADER部分,你参考一下。


#pragma segment="RAMLOADER" 1
#pragma segment="ROMLOADER" 1

#pragma location="RAMLOADER"
void Loader(uint16_t BlockNum)
{
uint8_t *Flash_ptr;                        // Flash pointer
uint8_t *pData;                         //写入数据地址
uint16_t i;

Flash_ptr = (uint8_t *) (BlockNum);             // Initialize Flash Block pointer
pData=(uint8_t *)DATA_ADDR;
//FCTL1 = FWKEY + ERASE;                  // Set Erase bit
//FCTL3 = FWKEY;                            // Clear Lock bit
//*Flash_ptr = 0;                        // Dummy write to erase Flash segment D
while(FCTL3 & BUSY);
FCTL1 = FWKEY +WRT;                      // Set WRT bit for write operation
FCTL3 = FWKEY;
for (i=0; i<64; i++)
{
    *Flash_ptr++ = *pData++;          // copy value segment C to segment D
    while(!(FCTL3 & WAIT));               // WAIT until Flash is ready
}

FCTL1 = FWKEY;                            // Clear WRT bit
while(FCTL3 & BUSY);                      // Check Flash BUSY bit
FCTL3 = FWKEY + LOCK + LOCKA;                     // Set LOCK bit
}
//
#pragma location="ROMLOADER"
void write_Seg (uint16_t BlockNum)
{
uint8_t *Flash_ptr;                        // Flash pointer
uint8_t *pData;                         //写入数据地址
uint16_t i;

Flash_ptr = (uint8_t *) (BlockNum);             // Initialize Flash Block pointer
pData=(uint8_t *)DATA_ADDR;
//FCTL1 = FWKEY + ERASE;                  // Set Erase bit
//FCTL3 = FWKEY;                            // Clear Lock bit
//*Flash_ptr = 0;                        // Dummy write to erase Flash segment D
while(FCTL3 & BUSY);
FCTL1 = FWKEY +WRT;                      // Set WRT bit for write operation
FCTL3 = FWKEY;

for (i=0; i<64; i++)
{
    *Flash_ptr++ = *pData++;          // copy value segment C to segment D
    while(!(FCTL3 & WAIT));               // WAIT until Flash is ready
}

FCTL1 = FWKEY;                            // Clear WRT bit
while(FCTL3 & BUSY);                      // Check Flash BUSY bit
FCTL3 = FWKEY + LOCK + LOCKA;                      // Set LOCK bit
}

在工程选项里设置一下,在 options --> linker -->Extera options下面加上
-Z(DATA)RAMLOADER=200-27F
-Z(CODE)ROMLOADER,ROM_4=F000-FFDF,F000-FFDF


后面的是地址,你看看放在那里好。在IAR帮助里有,很详细。

#pragma location="ROM_4"
#pragma language=extended

void CopyLoaderToRAM(void)
{
void * ram_start = __sfb("RAMLOADER"); // start of RAMCODE
void * ram_end = __sfe("RAMLOADER"); // end of RAMCODE
void * rom_start = __sfb("ROMLOADER"); // start of ROMCODE
// compute the number of bytes to copy
unsigned long size = (unsigned long)(ram_end) - (unsigned long)(ram_start);
// copy the contents of ROMCODE to RAMCODE
memcopy( ram_start, rom_start, size );
}
#pragma language=default

上面的是拷贝函数,要在调用LOADER前调用。



Loader 和 write_Seg 两个函数是一样的,分别在RAM里和ROM里。当然可以只写一个函数

在链接选项里加上
-QRAMCODE=ROMCODE

我写成两个是为了,两个函数可以放在RAM和ROM里的任何地址。

我没贴擦除函数,写FLASH之前要先擦除。一个意思,好好看看IAR的帮助吧。

weuser 发表于 2011-2-28 09:57:51

RAM和ROM里面运行确实操作一样的,只是该一下连接器的设置,通知链接器在RAM预留空间,然后从FLASH里拷贝过去(因为RAM上电之前保存不了程序)。
RAM里运行省点电,就是自带的RAM太小了。

链接命令文件xcl也要修改一下,
// -------------------------------------------------------------------
// ROM memory (FLASH)
// -------------------------------------------------------------------

//Code
-Z(CODE)CSTART=E000-FFDF
-Z(CODE)CODE=E000-FFDF,200-27F//加上用到的RAM地址

CODE地址要包括 用到的RAM地址,不然链接不成功。

ringan865 发表于 2011-2-28 11:16:29

mark

lovewwy 发表于 2011-3-4 20:33:09

回复【11楼】weuser 闪
-----------------------------------------------------------------------

感谢 。

pidoo 发表于 2011-3-8 13:27:53

这个需要mark,仔细看

pan_bwxyz 发表于 2011-3-18 15:04:05

神贴...

mxtt 发表于 2011-4-4 20:20:00

酷贴...

lidongliping 发表于 2011-4-15 15:14:45

MARK,

charley 发表于 2011-4-22 09:48:19

mark,学习了,谢谢。

like0831 发表于 2011-4-27 09:28:08

这个要好好学学。

liuhongyu 发表于 2011-11-29 21:35:57

回复【10楼】weuser 闪
-----------------------------------------------------------------------

mark
页: [1]
查看完整版本: 请假各位一个430写FLASH 的问题。