美文网首页物联网loT从业者
NRF52832学习笔记(27)——非易失性存储器控制器NVMC

NRF52832学习笔记(27)——非易失性存储器控制器NVMC

作者: Leung_ManWah | 来源:发表于2020-09-24 10:54 被阅读0次

    一、简介

    1.1 NVMC

    nRF52832 的非易失性存储器是通过 NVMC 来管理的,NVMC 是 Non-volatile memory controller(非易失性存储器控制器)的缩写,NVMC 提供了写或擦除 Flash 区域和 UICR(用户信息配置寄存器)的功能。

    写 Flash 之前必须通过写寄存器 CONFIG.WEN 来使能 Flash 的写操作,同样,擦除 Flash 之前必须通过写寄存器 CONFIG.WEN 来使能 Flash 的擦除操作。并且,对 Flash 进行操作的时候要特别注意,不能同时使能 Flash 的写和擦除,否则将导致无法预测的后果。

    1.2 片内 Flash 分布

    nRF52832-QFAA 片内 Flash 大小如下:


    nRF52832 的 Flash 地址范围是:0x0000 0000 ~ 0x0008 0000,共 512k 字节。Flash 区域分为 128 个 4k 字节大小的页面, 每个页面包含 8 个 512 字节大小的块,需要注意的是 Flash 分布的最小单位是块,但是擦除操作最小的单位是页。

    Flash 是有使用寿命的,nRF52832 片内 Flash 可擦除/写的次数是 10000 次。写和擦除所需的时间如下:

    二、SDK配置

    2.1 添加文件

    读写 Flash 需要加入的文件如下:

    文件名 SDK中的目录 描述
    nrf_nvmc.c ...\modules\nrfx\hal NVMC 驱动文件

    2.2 添加及引用头文件

    #include "nrf_nvmc.h"

    三、API

    3.1 擦除页

    函数原型 void nrf_nvmc_page_erase(uint32_t address)
    函数功能 擦除页
    参数 address:页起始地铁
    返回值
    • 示例:擦除第 127 页(第 127 页的起始地址是:127 * 4 * 1024 = 0x0007F000)。
      nrf_nvmc_page_erase(0x0007F000);

    3.2 写

    函数原型 void nrf_nvmc_write_word(uint32_t address, uint32_t value)
    函数功能 向 Flash 指定地址写入一个字。注意 Flash 写之前必须擦除。
    参数 address:写入的地址
    value:写入的 Flash 的数据
    返回值
    • 示例:向 Flash 地址 0x0007F000 写入数据“0x12345678”。
      nrf_nvmc_write_word(0x0007F000, 0x12345678);
    函数原型 void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words)
    函数功能 向 Flash 指定地址连续写入多个字。注意 Flash 写之前必须擦除。
    参数 address:写入的地址
    src:写入的 Flash 的数据
    num_words:写入字的数量
    返回值
    函数原型 void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
    函数功能 向 Flash 指定地址写入一字节数据。注意 Flash 写之前必须擦除。由于写 Flash 的最小单位是字,将自动补齐剩余3字节。
    参数 address:写入的地址
    value:写入的 Flash 的数据
    返回值
    函数原型 void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes)
    函数功能 向 Flash 指定地址写入一字节数据。注意 Flash 写之前必须擦除。由于写 Flash 的最小单位是字,不够部分将自动补齐。
    参数 address:写入的地址
    src:写入的 Flash 的数据
    num_bytes:写入字节的数量
    返回值

    3.3 读

    Flash 中的数据需要通过指针来读取。读取的过程是先定义指针变量,然后将该指针指向数据存放的地址,这样就可以获取 Flash 中该地址上的数据。

    • 示例:从地址 0x0007F000 读取一个字。
    uint32_t *pdat; // 定义指针变量
    pdat = (uint32_t *)0x0007F000; // 指针指向地址0x0007F000
    printf("%x", *pdat); // 打印出读取的数据
    

    上述代码中,因为 pdat 是指针变量,0x0007F000 是一个常数,所以要将 0x0007F000 强制转换为指针类型后赋值给 pdat。

    四、读写示例(仅限于没有协议栈的工程或协议栈工作以前)


    执行 Flash 写操作时,首先要规划写入数据的 Flash 空间,如第 127 页(第 127 页的起始地址是:127 * 4 * 1024 = 0x0007F000),0x0007F000 就是第 127 页的起始地址。

    #include "nrf_nvmc.h"
    
    int main(void)
    {
        uint32_t addr = 0x0007F000;
        uint32_t *pdat;
    
        nrf_nvmc_page_erase(addr);
        nrf_nvmc_write_word(addr, 0x12345678);
        pdat = (uint32_t *)addr;
        printf("0x%x", *pdat);
    }
    

    五、读写示例(对于有softdevice协议栈的工程)

    使用 sd_flash_page_erasesd_flash_write 两个函数,并且每次操作需要延时,等待协议栈有空时才执行 Flash 操作。

    int main(void)
    {
        uint32_t *addr;
        addr = (uint32_t *)0x7F000;
        uint32_t value = 0x12345678;
        sd_flash_page_erase(127); // 擦除第 127 页
        nrf_delay_ms(100);
        sd_flash_write(addr, (uint32_t *)&value, 1);
        nrf_delay_ms(100);
        uint32_t *pdat;
        pdat = (uint32_t *)0x7F000;
        printf("0x%x", *pdat);
    }
    

    • 由 Leung 写于 2020 年 9 月 24 日

    • 参考:[艾克姆科技]

    相关文章

      网友评论

        本文标题:NRF52832学习笔记(27)——非易失性存储器控制器NVMC

        本文链接:https://www.haomeiwen.com/subject/afroyktx.html