FLASH中sector、block、page的区别和联系

在FLASH存储介质中,sector(扇区)、block(块)和page(页)是三个重要的概念,它们代表了不同级别的逻辑分区或数据单元。

首先,page(页)是FLASH存储器中的最小可擦除单元,也称为擦除页或擦除单位。它适用于需要频繁读写且存储小量数据的场景,如缓存、寄存器、配置信息等。每个页在物理上都有自己的地址范围,通过页地址和页内偏移地址,可以唯一地标识存储器中的每个字节或位。

其次,sector(扇区)是存储器中的逻辑分区,也称为块或擦除块。它适用于中等大小的数据存储和操作,如文件系统、日志记录等。扇区由多个页组成,一个扇区包含多个页。

最后,block(块)是存储器中的逻辑分块,也称为存储块或逻辑块。它适用于大容量数据存储,如磁盘分区、应用程序和媒体文件等。块可以由多个扇区组成,因此,一个块可以有多个页。在某些情况下,块的大小可能根据擦除方式的不同而有所变化,比如,一个块可以是32KB,也可以是64KB。

以W25Q128为例,这是一个128Mbit的FLASH存储器。其每页大小为256字节,一共有65536页。每个扇区有16页,即4KB大小。块的大小则可能因擦除方式的不同而有所变化,可以是32KB或64KB。

综上所述,sector、block和page在FLASH中分别代表了不同级别的数据单元和逻辑分区,它们在大小和功能上都有所不同,以适应不同的数据存储和操作需求。

以下是使用STM32F031F6P6的HAL库进行Flash扇区读写的示例代码: ```c #include "main.h" #include "stm32f0xx_hal.h" #define FLASH_USER_START_ADDR ((uint32_t)0x08003800) // Flash用户区起始地址 #define FLASH_USER_END_ADDR ((uint32_t)0x08003FFF) // Flash用户区结束地址 #define FLASH_SECTOR_NUM FLASH_SECTOR_7 // Flash扇区7 #define DATA_SIZE 256 // 数据大小 uint32_t flash_address = FLASH_USER_START_ADDR; // Flash存储地址 uint32_t data_write[DATA_SIZE/4] = {0}; // 待写入的数据 uint32_t data_read[DATA_SIZE/4] = {0}; // 读出的数据 void SystemClock_Config(void); void MX_GPIO_Init(void); void MX_FLASH_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_FLASH_Init(); // 待写入数据初始化 for (int i = 0; i < DATA_SIZE/4; i++) { data_write[i] = i + 1; } // 扇区擦除 FLASH_Erase_Sector(FLASH_SECTOR_NUM, FLASH_VOLTAGE_RANGE_3); // 数据写入 for (int i = 0; i < DATA_SIZE/4; i++) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, flash_address, data_write[i]); flash_address += 4; } // 数据读出 flash_address = FLASH_USER_START_ADDR; for (int i = 0; i < DATA_SIZE/4; i++) { data_read[i] = *(__IO uint32_t*)flash_address; flash_address += 4; } while (1) { // 程序待处理 } } // 系统时钟配置 void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; /**Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } // GPIO初始化 void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; // PA5输出高电平,用于测试 GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); } // FLASH初始化 void MX_FLASH_Init(void) { HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR); } ``` 在以上代码,我们通过定义`FLASH_USER_START_ADDR`和`FLASH_USER_END_ADDR`来确定Flash用户区的起始地址和结束地址。在本例,我们使用了Flash扇区7。Flash扇区的起始地址在STM32F031F6P6的参考手册可以找到。 在程序的主要逻辑,我们首先使用`FLASH_Erase_Sector`函数对Flash扇区进行擦除,然后使用`HAL_FLASH_Program`函数将数据写入Flash。写入完成后,我们使用`*(__IO uint32_t*)flash_address`读取Flash的数据。最后,我们将读取的数据与写入的数据进行比较,以确保Flash扇区的读写正确。 需要注意的是,在进行Flash写操作时,需要先调用`HAL_FLASH_Unlock`函数解锁Flash。在对Flash进行操作完成后,需要调用`HAL_FLASH_Lock`函数重新锁定Flash。 另外,如果Flash写入操作失败,可以通过`FLASH_FLAG_WRPERR`和`FLASH_FLAG_PGERR`标志位来判断。如果出现错误,需要进行错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加载-ing

赏!大大的赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值