打印
[活动专区]

【杰发科技AC7802x测评】9. DFLASH擦写试验

[复制链接]
253|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hehung|  楼主 | 2023-6-28 21:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#技术资源# #申请原创#

前言

本文测试了AC7802X的EFLASH功能,实现了向DFLASH的page0,1,2,3写入数据和读取数据,并且擦除page0的数据。

1 EFLASH介绍

查看官方提供的用户手册《ATC_AC7802x_ReferenceManual_CH.pdf》19 片内Flash(Embedded Flash)。

下图为EFLASH的介绍,说明了EFLASH包含了两部分:

- PFLASH:用来保存用户程序
- DFLASH:用来保存不需要经常更新的标定数据

PFLASH一般只用来保存用户程序,因为一般情况下,擦除次数小于DFLASH,所以不要对PFLASH进行频繁擦写操作,也为了防止对PFLASH的操作损坏用户代码,所以一般数据的写入都放在DFLASH中,而DFLASH一般也只用来保存不会频繁擦写的数据,因为其寿命远小于EEPROM。

从下面的介绍还可以知道DFLASH一页为8Bytes,大小为2KBytes,一个块为16Bytes。



2 DFLASH地址划分

因为本文主要测试对DFLASH的擦写,所以需要先了解DFLASH的地址划分,如下:

- 起始地址: 0x08020000,即page0
- page1:0x08020008
- page2:0x08020010
- page3:0x08020018



3 代码实现

知道了DFLASH的地址划分以及原理之后,我们可以开始实现代码编写,如下:

- eflash_DataInit(): 初始化要写入到DFLASH的数据
- eflash_DFlashAllErase(): 擦除整个DFLASH区域的功能,如果是第一次使用,可以调用该函数擦除整个DFLASH区域
- eflash_DFlashPageErase(): 擦除指定页,即8Bytes区域
- eflash_DFlashPageWrite(): 向指定page地址写入数据,最小写入单位为4Bytes。
- eflash_DemoRuning(): 测试演示,在主函数while(1)之前调用,用于验证DFLASH擦写是否成功。该函数主要实现向DFLASH的page0和page2写入16Bytes的数据,然后在擦除page0的数据。

下面说一下注意事项:

- g_WriteBuff为要写入的数组变量,这个变量不能直接赋初值,直接赋初值会导致写入不成功,我也不清楚为什么
- 需要先调用eflash_DataInit初始化要写入的数据(原因见上一条)
- 不能使用函数EFLASH_PageEraseVerify来验证DFLASH是否擦除成功,因为该函数只支持PFLASH,不支持DFLASH。

/*
@hehung
2023-6-15
email: 1398660197@qq.com
wechat: hehung95
reproduced and please indicate the source @hehung
*/

#include "ac780x_eflash.h"
#include "stdbool.h"
#include "app_eflash.h"
#include <stdio.h>


#define WRITE_LENGTH             16U                                  /*! 写入数据长度,最小写入长度为4字节, 所以WRITE_LENGTH 需要大于等于4 */

#define DFLASH_PAGE0_ADRESS      0x08020000U                           /*! Dflash Page0 0x0802_0000 ~ 0x0802_000F   size 16B - 2pages */
#define DFLASH_PAGE2_ADRESS      0x08020010U                           /*! Dflash Page0 0x0802_0010 ~ 0x0802_001F   size 16B - 2pages*/
#define DFLASH_PAGE255_ADRESS    0x080207F8U                           /*! Dflash Page0 0x0802_07F8 ~ 0x0802_07FF   size 8B */

uint8_t g_WriteBuff[WRITE_LENGTH] = {0};                               /*! 写入数据BUFF */
uint8_t g_ReadBuff[WRITE_LENGTH] = {0};                                /*! 读取数据BUFF */



static void eflash_DataInit(void)
{
    uint16_t i = 0;
    for (i = 0; i < WRITE_LENGTH; i++)
    {
        g_WriteBuff[i] = i;
    }
}

static void eflash_DFlashAllErase(void)
{
    EFLASH_UnlockCtrl();                                                                          /*! Flash 写入/擦除前需要先解锁 */

    EFLASH_DFMassErase();                                                                         /*!  D-flash  全片擦除,因为Code 存放在P-flash中, 不建议对P-flash进行全片擦除 */
    if (EFLASH_STATUS_SUCCESS != EFLASH_DFMassEraseVerify())                                      /*! 验证相应位置是否擦除成功 */
    {
        printf("[LINE %d] ERROR :Erase Dflash  failue.\r\n", __LINE__);                           /*! 若擦除失败,则打印相应错误警告 */
    }
    EFLASH_LockCtrl();                                                                            /*! 完成flash操作后重新上锁, 上锁与解锁要配套使用 */
}

static void eflash_DFlashPageErase(uint32_t page)
{
    EFLASH_UnlockCtrl();                                                                          /*! Flash 写入/擦除前需要先解锁 */
    EFLASH_PageErase(page);                                                                       /*! 擦除D-flash page0 */
//    if (EFLASH_STATUS_SUCCESS != EFLASH_PageEraseVerify(page, WRITE_LENGTH / 4U)) /*! 验证相应位置是否擦除成功 */
//    {
//        printf("[LINE %d] ERROR :Erase [0x%08X] failue.\r\n", __LINE__, page);    /*! 若擦除失败,则打印相应错误警告 */
//    }
    EFLASH_LockCtrl();                                                                            /*! 完成flash操作后重新上锁, 上锁与解锁要配套使用 */
}


static void eflash_DFlashPageWrite(uint32_t page)
{
    uint16_t i = 0;

    EFLASH_UnlockCtrl();                                                                 /*! Flash 写入/擦除前需要先解锁 */

    EFLASH_PageProgram(page, (uint32_t*)g_WriteBuff, WRITE_LENGTH / 4);   /*!  将数据写入D-Flash, 最小写入单位为4字节  */
    printf("\r\nWrite g_WriteBuff[WRITE_LENGTH] to D-Flash ...\r\n");
    EFLASH_Read(page, (uint32_t*)g_ReadBuff, WRITE_LENGTH / 4);           /*! 读取D-Flash数据 */
    printf("Read D-Flash [0x%X] : ", page);                               /*!  打印相关信息 */
    for (i = 0; i < WRITE_LENGTH; i++)
    {
          printf("%02X  ", g_ReadBuff[i]);
    }
    printf("\r\n");
    EFLASH_LockCtrl();                                                                   /*! 完成flash操作后重新上锁, 上锁与解锁要配套使用 */
}

void eflash_DemoRuning(void)
{
    eflash_DataInit();

    // 等待输入要写入到DFLASH的数据

    // 擦除全部DFLASH
    eflash_DFlashAllErase();
    printf ("Erase DFlash finished\r\n");

    //写入数据到DFLASH的page0和page1
    eflash_DFlashPageWrite(DFLASH_PAGE0_ADRESS);
    printf ("Write page0 of  DFlash finished\r\n");
    eflash_DFlashPageWrite(DFLASH_PAGE2_ADRESS);
    printf ("Write page2 of  DFlash finished\r\n");

    // 擦除page0,保留page1
    eflash_DFlashPageErase(DFLASH_PAGE0_ADRESS);
    printf ("Erase page0 of  DFlash finished\r\n");
                                 
}



4 试验结果

试验结果如下:

1. 进入Debug界面
2. 在两个page写入结束处打上断点,用于观察数据是否写入成功,见下图,可以数据写入成功。



3. 在函数结尾处打一个断点,观察page0是否擦除成功,见下图,page0被擦除,只剩下page1~page3的数据。



4. 下面是串口打印的结果





使用特权

评论回复

相关帖子

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

本版积分规则

10

主题

66

帖子

1

粉丝