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、收缩毛孔护

    2024-04-15
    64500
  • 全套海蓝之谜使用顺序是什么,海蓝之谜具体使用步骤是什么?

    在我们的日常生活中,经常可以看到有人在使用海蓝之谜护肤品,海蓝之谜护肤品的美誉度很高。很多人进了一整套海蓝之谜护肤品,却不知道怎么用。全套海军神秘使用令海蓝之谜全套的使用顺序:洁面后先用醒肤水,再用浓缩精华,再用各种精华。精华的使用顺序:活

    2024-04-15
    58100
  • 韩国一部电影中和一个红衣女子做完去找纸巾的电影

    1描写女人漂亮的诗句描写女人漂亮的诗句有班姬续史之姿,谢庭咏雪之态巴东有巫山,窈窕神女颜黛眉开娇横远岫,绿鬓淳浓染春烟澄妆影于歌扇,散衣香于舞风,拭珠沥于罗袂,传金翠杯于素手 隔户杨柳弱袅袅,恰似十五女儿腰花

    2024-04-15
    46600
  • 珀莱雅精华液的功效 珀莱雅精华液的使用方法

    珀莱雅精华液的好评是很多的,很多人都觉得这款精华液好用,那么珀莱雅精华液的功效是什么呢,珀莱雅精华液的使用方法是什么呢。珀莱雅精华液的功效 这款精华采用了海洋深层水,循环于600米深海领域,可以提供多种肌肤所需要的营养,而且这款精华

    2024-04-15
    56700
  • pmpm玫瑰和白松露哪个好用

    pmpm玫瑰和白松露各有优势,具体选择取决于个人需求和偏好。pmpm千叶玫瑰精油含有千叶玫瑰精准定位提取,具有抗初老、强韧肌肤屏障以及双重vc成分,抗氧化、提亮肤色,可以改善肤色暗沉,抵御自由基,使肌肤饱满有光泽。白松露具有保湿、补水、抗初

    2024-04-15
    52700
  • 妮维雅洗面奶臭臭的正常吗

    妮维雅洗面奶有臭味是正常的吗?这是一个关于妮维雅洗面奶的疑问。我想强调的是,产品是否有臭味可以因个人感知而异。每个人的嗅觉敏感度和对气味的接受程度都不同。所以,我们不能一概而论地说妮维雅洗面奶有臭味就是正常的或者异常的。每个人都可能对同一种

    2024-04-15
    47900
  • 婷美美肌黑金抗皱紧致套盒咋用

    晚上厚涂之后。第2天早上皮肤真的能感觉到软软的嫩嫩的。质地满足不同肌肤所需,油皮或混油皮挚爱清润轻盈型,干皮心水绵密滋润型,极致肤感一抹入坑,这款升级香调体验,灵感源自莫奈花园,想要解锁同款女神颜的姐妹,入它准没错。点线面三维紧塑年轻,硬核

    2024-04-15
    51800

发表评论

登录后才能评论
保存