You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:20:01