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

求助:如何在MPLAB X IDE V6中实现PIC24FJ128GL305的Flash写入?

PIC24FJ128GL305 Flash 读写实现方案(含浮点数据处理)

核心前提说明

PIC24系列Flash是块擦除型存储器,写入前必须先擦除目标扇区(擦除后所有位为1);浮点数可通过强制类型转换为字节数组存储,读取时再转回浮点型;操作Flash时必须关闭中断,防止干扰。

可直接使用的库文件实现

创建flash_utils.h和flash_utils.c两个文件,直接添加到你的MPLAB X工程中:

flash_utils.h

#ifndef FLASH_UTILS_H
#define FLASH_UTILS_H

#include <p24FJ128GL305.h>
#include <stdint.h>
#include <float.h>

// 定义Flash存储起始地址(需选未被程序占用的扇区,查 datasheet 确认)
#define FLASH_STORAGE_ADDR 0x10000

// 擦除指定Flash扇区
void flash_erase_sector(uint32_t addr);

// 写入32位整数到Flash
void flash_write_int32(uint32_t addr, int32_t data);

// 从Flash读取32位整数
int32_t flash_read_int32(uint32_t addr);

// 写入单精度浮点数到Flash
void flash_write_float(uint32_t addr, float data);

// 从Flash读取单精度浮点数
float flash_read_float(uint32_t addr);

#endif // FLASH_UTILS_H

flash_utils.c

#include "flash_utils.h"

void flash_erase_sector(uint32_t addr) {
    // 关闭中断,避免Flash操作被打断
    __builtin_disi(0x3FFF);
    
    NVMCON = 0x4042; // 设置为扇区擦除模式
    NVMADRU = (addr >> 16) & 0x0007; // 高地址字节(PIC24地址为24位)
    NVMADR = addr & 0xFFFF; // 低地址字节
    
    // 执行擦除
    __builtin_write_NVM();
    
    // 恢复中断
    __builtin_disi(0x0000);
}

void flash_write_int32(uint32_t addr, int32_t data) {
    __builtin_disi(0x3FFF);
    
    NVMCON = 0x4001; // 字写入模式(每次写16位,分两次写32位)
    NVMADRU = (addr >> 16) & 0x0007;
    NVMADR = addr & 0xFFFF;
    
    // 写入低16位
    NVMDAT = (uint16_t)(data & 0xFFFF);
    __builtin_write_NVM();
    
    // 写入高16位
    addr += 2;
    NVMADRU = (addr >> 16) & 0x0007;
    NVMADR = addr & 0xFFFF;
    NVMDAT = (uint16_t)((data >> 16) & 0xFFFF);
    __builtin_write_NVM();
    
    __builtin_disi(0x0000);
}

int32_t flash_read_int32(uint32_t addr) {
    uint16_t low = *(uint16_t*)addr;
    uint16_t high = *(uint16_t*)(addr + 2);
    return (int32_t)((high << 16) | low);
}

void flash_write_float(uint32_t addr, float data) {
    // 把浮点数转成32位整数存储
    int32_t float_as_int = *(int32_t*)&data;
    flash_write_int32(addr, float_as_int);
}

float flash_read_float(uint32_t addr) {
    int32_t int_data = flash_read_int32(addr);
    return *(float*)&int_data;
}

使用示例代码

#include "flash_utils.h"

int main(void) {
    int32_t test_int = 123456;
    float test_float = -733.5847f;
    
    // 1. 先擦除目标扇区(同一扇区多次写入只需擦除一次)
    flash_erase_sector(FLASH_STORAGE_ADDR);
    
    // 2. 写入整数和浮点数(偏移4字节避免覆盖)
    flash_write_int32(FLASH_STORAGE_ADDR, test_int);
    flash_write_float(FLASH_STORAGE_ADDR + 4, test_float);
    
    // 3. 读取验证
    int32_t read_int = flash_read_int32(FLASH_STORAGE_ADDR);
    float read_float = flash_read_float(FLASH_STORAGE_ADDR + 4);
    
    while(1);
    return 0;
}

关键注意事项

  • 地址选择:FLASH_STORAGE_ADDR必须选未被程序占用的扇区,可通过MPLAB X的「Memory View」或芯片 datasheet 确认可用区域
  • 擦写寿命:Flash擦写寿命约10000次,避免频繁擦写同一扇区
  • 中断控制:Flash操作期间必须关闭中断,否则会导致操作失败或系统异常
  • 浮点精度:单精度浮点数存储会有微小精度损失,若需更高精度可改用双精度(占用8字节Flash)

内容的提问来源于stack exchange,提问作者WalterPH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:50:22