请求Spansion NOR Flash基地址与偏移量读写解析及C/C++代码示例
我完全理解你在啃Spansion/Cypress NOR Flash基地址和偏移量读写时的困惑——这些内存映射式的操作一开始确实容易绕晕。下面我给你一套简化的C示例代码,专门针对这类NOR Flash的基础读写逻辑,每一步都加了注释,帮你把概念落地。
先理清楚核心概念
- 基地址:NOR Flash会被映射到MCU的地址空间里,这个起始地址就是基地址(比如
0x08000000,具体要看你的硬件配置)。你可以直接通过这个地址访问Flash,就像操作普通内存一样。 - 偏移量:从基地址往后的地址偏移量,比如要访问第2个扇区,就用
基地址 + 扇区偏移来计算目标地址。
简化版NOR Flash读写示例代码
#include <stdint.h> // 定义你的Spansion/Cypress NOR Flash的基地址(根据硬件实际配置修改) #define NOR_FLASH_BASE_ADDR ((volatile uint8_t *)0x08000000) // 假设扇区大小为4KB(不同型号Flash扇区大小可能不同,查 datasheet!) #define SECTOR_SIZE 4096 // 读取Flash状态寄存器(用于检查操作是否完成) static uint8_t nor_flash_read_status(void) { // 发送读状态寄存器指令(Spansion/Cypress标准指令0x05) *((volatile uint8_t *)NOR_FLASH_BASE_ADDR) = 0x05; return *((volatile uint8_t *)NOR_FLASH_BASE_ADDR); } // 等待Flash操作完成(检查BUSY位) static void nor_flash_wait_ready(void) { while ((nor_flash_read_status() & 0x01) != 0) { // 等待BUSY位清零,表示操作完成 } } // 擦除指定扇区(NOR Flash必须先擦除才能写入) void nor_flash_erase_sector(uint32_t sector_offset) { // 计算扇区起始地址:基地址 + 扇区偏移量 volatile uint8_t *sector_addr = NOR_FLASH_BASE_ADDR + (sector_offset * SECTOR_SIZE); // 发送扇区擦除指令序列(Spansion/Cypress标准:0x20) *((volatile uint8_t *)NOR_FLASH_BASE_ADDR) = 0x60; // 进入擦除模式 *sector_addr = 0x20; // 发送扇区擦除指令 *sector_addr = (sector_offset * SECTOR_SIZE) >> 16; // 发送地址高位(32位地址分字节发送) *sector_addr = (sector_offset * SECTOR_SIZE) >> 8; // 发送地址中位 *sector_addr = (sector_offset * SECTOR_SIZE) & 0xFF;// 发送地址低位 nor_flash_wait_ready(); // 等待擦除完成 } // 向指定偏移地址写入一个字节 void nor_flash_write_byte(uint32_t offset, uint8_t data) { // 计算目标地址:基地址 + 偏移量 volatile uint8_t *target_addr = NOR_FLASH_BASE_ADDR + offset; // 发送字节编程指令序列(Spansion/Cypress标准:0x02) *((volatile uint8_t *)NOR_FLASH_BASE_ADDR) = 0x02; // 进入编程模式 *target_addr = data; // 写入数据 nor_flash_wait_ready(); // 等待写入完成 } // 从指定偏移地址读取一个字节 uint8_t nor_flash_read_byte(uint32_t offset) { // 直接读取目标地址(NOR Flash支持随机读取,像读内存一样简单) return *(NOR_FLASH_BASE_ADDR + offset); } // 测试函数:擦除第0扇区,写入数据再读出验证 void nor_flash_test(void) { uint32_t test_offset = 0x100; // 从基地址往后0x100偏移处写入 uint8_t test_data = 0xAB; // 1. 擦除第0扇区(必须先擦除,否则写入无效) nor_flash_erase_sector(0); // 2. 写入测试数据 nor_flash_write_byte(test_offset, test_data); // 3. 读取数据并验证 uint8_t read_data = nor_flash_read_byte(test_offset); if (read_data == test_data) { // 读写成功 } else { // 读写失败,检查硬件或指令 } }
代码关键部分解释
- 基地址定义:
NOR_FLASH_BASE_ADDR是Flash映射到MCU内存的起始地址,必须根据你的硬件原理图或MCU手册修改。 - 擦除操作:NOR Flash的特性是只能把1改成0,所以写入前必须先擦除(把整个扇区恢复为0xFF),代码里的扇区擦除指令是Spansion/Cypress的标准指令,不同型号可能有细微差别,一定要查对应型号的datasheet。
- 写入操作:写入前需要发送编程指令,然后直接往目标地址写数据,写完要等状态寄存器的BUSY位清零。
- 读取操作:这是最简单的,因为NOR Flash是内存映射的,直接读取对应地址的值就行,不需要额外指令。
内容的提问来源于stack exchange,提问作者binnie
相关产品推荐
相关产品推荐

