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 熟练掌握互联网技术:大学生们在成长过程中接受到更多的互联网知识和技术培训,能够更好地利用网络资源开展电商创业项目。2 具备创意意识:大学生们常常有着敏锐的创意意识,能够思考出一些新颖的商

    2024-04-15
    61100
  • 我花了1w,给你找出了最好用的精华

    八月爱用分享没有准时和大家见面。因为最近刚好空了几瓶护肤品,那么就干脆来个空瓶合集好了~以后我也会定期整理空瓶分享。 经验都是一整瓶用下来体验出来的,也跟风入手了不少人气好口碑的护肤产品,但真正能用到见底的可真不多。每次看

    2024-04-15
    51500
  • 香奈儿的产品怎么样?哪些值得买?

    香奈儿品牌产品线这么多,我个人觉得有的好用,有的性价比不高。护肤线的话,感觉不是他们家的主打,印象中美妆博主们也都比较少提到香奈尔家的护肤品。我用过他们家的山茶花系列,保湿效果还可以,但是同等价位还有更多的选择。不过香奈儿讨人喜欢的一点是:

    2024-04-15
    27200
  • 精华液精华水先用哪个

    先用精华水再用精华液,精华水和精华液虽然都属于精华,但二者的功效是不一样的,要说效果还是精华液的效果比较好一些,精华水是不能够代替精华液使用的。精华水比普通化妆水和爽肤水营养成分要高一些,它能够改善干燥的皮肤状态,让肌肤变得更加细腻,充满活

    2024-04-15
    40300
  • 天气丹水云系列好用吗

    好用。天气丹套盒里的乳液对于皮肤的维稳效果相当不错,天气丹乳液的质地不厚重,使用起来不会让肌肤产生负担感,保湿力度也很高,适合全肤质所有人群使用。天气丹套盒中还有一盒面霜,天气丹面霜质地比较绵密,可以牢牢锁住之前所使用护肤品中的营养成分。有

    2024-04-15
    47500
  • 用什么化妆脸会发亮

    用什么化妆脸会发亮  用什么化妆脸会发亮,爱美是人的天性,在这个看脸的时代,很多女生都会通过化妆来修饰自己,而正是因为如此市面上的化妆品种类非常多,那么用什么化妆脸会发亮呢?用什么化妆脸会发亮1  化妆

    2024-04-15
    44800
  • 最温和的洗面奶有哪些

    1、迪蕾氨基酸洁面泡泡 100ml线下销量第一洗颜专科洁面泡泡配方极度温和,采用目前最温和的日本进口氨基酸成分。不含皂基,不含表面活性剂,pH值接近人体的弱酸性,一挤出来就是绵密的泡泡,能清洁毛孔深处的污垢,脸上粗大的毛孔也变得细致,用完一

    2024-04-15
    39400

发表评论

登录后才能评论
保存