打印
[PIC®/AVR®/dsPIC®产品]

合理使用AVR D系列芯片的USERROW、BOOTROW

[复制链接]
306|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lcczg|  楼主 | 2024-10-12 09:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lcczg 于 2024-10-12 09:39 编辑

在AVR D系列芯片中有一个非易失存储区是USERROW,BOOTROW, 可以用来存放终端产品的一些信息,例如校准数据,密钥串码之类的。芯片擦除(erase)时它不受影响,不会被擦。
在调试的时候耗费了一些时间,所以这里和大家分享一下,用到的话可以做一个参考。

我用的硬件是AVR64DU32 Cnano板(https://www.microchip.com/en-us/development-tool/ev59f82a),

IDE是MPLABX 6.20, 编译器XC8 v2.50.

程序里对USERROW操作,先擦再写,再读出来,调试时可以看到写入读出的数据是一致的。
USERROW大小512字节,测试时写入了32字节做验证。工程在附件里,这里直接贴一下代码

#include <xc.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

#define USER_ROW_START_ADDRESS 0x1200
#define USER_ROW_SIZE 32

uint8_t read_buf[USER_ROW_SIZE];

uint8_t read_user_row(uint16_t address)
{
    return *(uint8_t *) address;
}

void erase_user_row(void) {
    while (NVMCTRL.STATUS & (NVMCTRL_EEBUSY_bm | NVMCTRL_FLBUSY_bm));
    _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_FLPER_gc);  // Enter erase mode
    USERROW_USERROW = 0;                                       // trigger page(512byte) Erase
    while (NVMCTRL.STATUS & NVMCTRL_FLBUSY_bm);
    _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_NONE_gc);   // Leave erase mode
}

void write_user_row(uint8_t *data, uint8_t length) {

    // Set up the NVMCTRL to write to the user row
    NVMCTRL.ADDR = USER_ROW_START_ADDRESS;

    // Write data to the user row
    for (uint8_t i = 0; i < length; i++) {
        while (NVMCTRL.STATUS & (NVMCTRL_EEBUSY_bm | NVMCTRL_FLBUSY_bm));
        CCP = CCP_SPM_gc ;
        NVMCTRL.CTRLA = 0x02;
        *((uint8_t *)(USER_ROW_START_ADDRESS + i)) = data;
    }

}

int main(void) {
    uint8_t user_data[USER_ROW_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
    0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20};

    // Erase USERROW
    erase_user_row();
   
    // Write the user data to the user row
    write_user_row(user_data, USER_ROW_SIZE);

    // Read data from the user row
    for (uint8_t i = 0; i < USER_ROW_SIZE; i++) {
        read_buf = read_user_row(USER_ROW_START_ADDRESS + i);
    }

    while (1) {
    // Main loop
        NOP();
    }

    return 0;
}


烧录运行后,可以读出memory 内容到一个文件,

读出后打开文件,可以看到写入的数据



AVR64DU32-USERROW.X.zip

129.36 KB

使用特权

评论回复
沙发
micoccd| | 2024-10-12 16:39 | 只看该作者
这个是不是像FLASH一样啊

使用特权

评论回复
板凳
lcczg|  楼主 | 2024-10-16 10:53 | 只看该作者
micoccd 发表于 2024-10-12 16:39
这个是不是像FLASH一样啊

是的,本质上是FLASH。

使用特权

评论回复
地板
yellow555| | 2024-10-31 13:33 | 只看该作者
基本都要先擦再写,再读出来,调试时可以看到写入读出的数据是一致的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:滴水可穿石,众志更成城 http://my.21ic.com/static/image/smiley/comcom/2.gif

31

主题

876

帖子

4

粉丝