stm32怎样将数组存到flash?存到flash中的数组怎样读取出来?

stm32怎样将数组存到flash?存到flash中的数组怎样读取出来?,第1张

先初始化FSMC

void FSMC_NAND_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

FSMC_NANDInitTypeDef FSMC_NANDInitStructure;

FSMC_NAND_PCCARDTimingInitTypeDef p;

/ Enable FSMC, GPIOD, GPIOE and AFIO clocks /

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |

RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO , ENABLE);

/-- GPIO Configuration ------------------------------------------------------/

/ CLE, ALE, D0->D3, NOE, NWE and NCE2 NAND pin configuration /

GPIO_InitStructureGPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |

GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructureGPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructureGPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/ D4->D7 NAND pin configuration /

GPIO_InitStructureGPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;

GPIO_Init(GPIOE, &GPIO_InitStructure);

/ CS NAND pin configuration /

GPIO_InitStructureGPIO_Pin = GPIO_Pin_9;

GPIO_Init(GPIOG, &GPIO_InitStructure);

/ NWAIT NAND pin configuration /

GPIO_InitStructureGPIO_Pin = GPIO_Pin_6;

GPIO_InitStructureGPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructureGPIO_Mode = GPIO_Mode_IPU;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/-- FSMC Configuration ------------------------------------------------------/

pFSMC_SetupTime = 0x1;

pFSMC_WaitSetupTime = 0x3;

pFSMC_HoldSetupTime = 0x2;

pFSMC_HiZSetupTime = 0x1;

FSMC_NANDInitStructureFSMC_Bank = FSMC_Bank3_NAND;

FSMC_NANDInitStructureFSMC_Waitfeature = FSMC_Waitfeature_Enable;

FSMC_NANDInitStructureFSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;

FSMC_NANDInitStructureFSMC_ECC = FSMC_ECC_Enable;

FSMC_NANDInitStructureFSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;

FSMC_NANDInitStructureFSMC_TCLRSetupTime = 0x00;

FSMC_NANDInitStructureFSMC_TARSetupTime = 0x00;

FSMC_NANDInitStructureFSMC_CommonSpaceTimingStruct = &p;

FSMC_NANDInitStructureFSMC_AttributeSpaceTimingStruct = &p;

FSMC_NANDInit(&FSMC_NANDInitStructure);

/ FSMC NAND Bank Cmd Test /

FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);

}

定义一个写函数

uint32_t FSMC_NAND_WriteSmallPage(uint8_t pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)

{

uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;

uint32_t status = NAND_READY, size = 0x00;

uint8_t Page = 0x37;

while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))

{

/ Page write command and address /

(vu8 )(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = 0X00;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);

/ Calculate the size /

size = Page + (Page numpagewritten);

/ Write data /

for(; index < size; index++)

{

(vu8 )(NAND_FLASH_START_ADDR | DATA_AREA) = pBuffer[index];

}

(vu8 )(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM_TRUE;

/ 读忙脚 /

// while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );

// while( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == 0 );

/ Check status for successful operation /

status = FSMC_NAND_GetStatus();

if(status == NAND_READY)

{

numpagewritten++;

NumPageToWrite--;

/ Calculate Next small page Address /

addressstatus = FSMC_NAND_AddressIncrement(&Address);

}

}

return (status | addressstatus);

}

定义一个数组TxBuffer,然后将数组写入flash

FSMC_NAND_WriteSmallPage(TxBuffer, WriteAddr, 1);

读的过程相反,定义读取函数

uint32_t FSMC_NAND_ReadSmallPage(uint8_t pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead)

{

uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;

uint32_t status = NAND_READY, size = 0x00;

uint8_t Page = 0x37;

while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))

{

/ Page Read command and page address /

(vu8 )(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_1;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = 0X00;

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);

(vu8 )(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);

(vu8 )(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_TRUE;

/ 读忙脚 /

// while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );

// while( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == 0 );

/ Calculate the size /

size = Page + (Page numpageread);

/ Get Data into Buffer /

for(; index < size; index++)

{

pBuffer[index]= (vu8 )(NAND_FLASH_START_ADDR | DATA_AREA);

}

numpageread++;

NumPageToRead--;

/ Calculate page address /

addressstatus = FSMC_NAND_AddressIncrement(&Address);

}

status = FSMC_NAND_GetStatus();

return (status | addressstatus);

}

首先调用erase,将NAND全部擦除一遍,然后执行如下检测操作,

如果页大于512字节,

badblockpos = 0;

badblockbytes = 2;

如果页小于512字节,

badblockpos = 5;

badblockbytes = 1;

读取每个block的前两页OOB区域的第badblockpos开始的后badblockbytes字节是否为0xff,

如果是,那么说明该block是好的,否则该block是坏块[gliethttp_20080523]!

UINT_T create_bbt(FlashBootType_T fbt)

{

UINT_T Retval;

P_FlashProperties_T pFlashP = GetFlashProperties(fbt);

UINT_T BlkSize,BlkNum;

UINT_T flash_addr;

#define page_size (2048)

#define page_spare_size (64)

#define block_size (64page_size)

#define tmp_buffer_addr (0x80200000 - page_size - page_spare_size)

#define tmp_spare_buffer_addr (tmp_buffer_addr + page_size)

int i,j;

char bbpos;

bbpos = (char)(tmp_spare_buffer_addr + 0);

BlkSize = pFlashP->BlockSize;

BlkNum = pFlashP->NumBlocks;

for(i = 0;i < BlkNum;i++)

{

flash_addr = i BlkSize;

for(j = 0;j < 2;j++)

{

Retval = xdfc_read((UINT_T )tmp_buffer_addr, flash_addr + jpage_size, page_size, (UINT_T )tmp_spare_buffer_addr, GetNANDProperties());

if(Retval)

{

goto __create_bbt_mark;

}

if(bbpos[0] != 0xff)goto __create_bbt_mark;

if(bbpos[1] != 0xff)goto __create_bbt_mark;

}

continue;

__create_bbt_mark:

RelocateBlock( i, &GetFMProperties()->BBT, fbt );

}

}

欢迎分享,转载请注明来源:品搜搜测评网

原文地址:https://pinsoso.cn/meirong/1718554.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-10-13
下一篇2023-10-13

随机推荐

  • 美白精华液哪个牌子好

    1、sk2小银瓶2sk面部淡斑精华露富含光蕴海藻精粹能够使肌肤变得匀净透白,能够淡化肌肤可见的斑点,使肌肤变得亮泽净白光采。是护肤品祛斑排行榜10强之一,这款产品是一款明星护肤产品,价格有点小贵但是效果还是不错的。2、资生堂新透白美肌集光祛

    2024-04-15
    42400
  • 全球排行前3的化妆品牌,女生应该都应该知道!

    没有女生能抵抗的了化妆品的诱惑吧,那么在你的心里排名前三的是什么呢?雅诗兰黛这个品牌相信大家也不会陌生,我知道他家品牌卖的东西多(化妆品、护肤品、香水),都具有创新性,技术先进性并且被证明为有效,我是比较喜欢他家的dw粉底液,在涂之前一定要

    2024-04-15
    39500
  • 精华露的正确使用步骤

    精华液和精华液本质上是一样的,所以用的顺序是一样的,爽肤水之后,乳液之前。但也有一些品牌的精华比较特殊,在爽肤水之前使用,也就是洁面后的第一步,比如:秘密美白柔滑精华、雪花秀保湿精华。1洗脸:洗面奶、面霜或慕思是最常用的洗脸方法。2涂抹爽肤

    2024-04-15
    42600
  • 精华露和精华液的区别

    精华露和精华液的区别在于质地不同、使用方法不同、适合人群不同。1、质地不同精华露是高浓缩后的护肤品,例如著名品牌SK神仙水就是这类型的产品,质地较为粘稠,更适合干性皮肤使用。但对于油性肌肤,因为油脂分泌旺盛的缘故,不太适合多种精华类的护肤品

    2024-04-15
    42500
  • 娇韵诗双萃赋活精华

    娇韵诗双萃赋活修护精华露好用吗?评价怎么样啊?娇韵诗娇韵诗双萃赋活修护精华露获得过很多的护肤奖项,大部分人用这款精华都会给好评,使用感也是很不错的,以下是个人使用感受: 精华露刚开始用会感觉有点油,但真的不会闷痘,也不怕油光满面,皮

    2024-04-15
    35200
  • 妮维雅夜间美白保湿精华乳!一款可以在夜间保湿的精华乳

    这款精华乳用起来比较方便,挤压式的设计很干净卫生,而且还含有能防止黑色素的成分妮维雅夜间美白保湿精华乳夏天的时候很多姐妹都被晒黑了,现在是时候要做好美白工作了,偷偷美白才可以超过别的美少女,给大家分享一款我觉得好用的身体精华乳就是妮维雅夜间

    2024-04-15
    26000
  • 韩国护肤品十大排名品牌

    韩国十大品牌护肤品如下:1、whoo后在韩国十大护肤品品牌中,whoo荣登榜首,这个品牌将宫廷的美容秘笈与现代的东方医学相互结合,让广大的亚洲女性为之倾心。2、呼吸37度在韩国十大护肤品品牌中,起着重要的地位,它一直坚持自然美丽的概念,致力

    2024-04-15
    38000

发表评论

登录后才能评论
保存