freeelectron 发表于 2022-7-16 18:07

【N32L43x评测】8、Flash读\写\擦除——使用内部Flash存储数据

<h1 title="【GD32L233C-START评测】5、Flash读写——使用内部Flash存储数据">1、flash规格</h1>

<p> &nbsp;</p>

<p>本文使用的主芯片为N32L436RBL7,flash大小为128k</p>

<p>flash分为64个page,编号0-63,每个page为2k。</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:24px;">2、flash操作注意事项</span></strong></p>

<p> &nbsp; &nbsp;</p>

<p>(1)写、擦除操作必须打开HSI时钟;</p>

<p>(2)写操作仅支持32位,擦除至少以1个page位单位进行;</p>

<p>(3)等待周期,本文配置的HCLK为108MHZ,所以设置等待周期为3。</p>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;">3、代码实现</span></strong></p>

<pre>
<code>//PAGE 0-63   0x0800 0000 - 0x0801 FFFF

#define FLASH_PAGE_SIZE                                          0x800 //2k

void FlashWrite(uint16_t len,uint8_t*data,uint32_t addr_start)
{       
        uint16_t i=0;
        uint32_t temp=0;
        uint32_t addr=addr_start;
        FLASH_STS status = FLASH_COMPL;

    while(FLASH_HSICLOCK_ENABLE != FLASH_ClockInit());
       
    FLASH_Unlock();
       
        for(i=0;i&lt;len/4;i++)
        {               
                temp = (data&lt;&lt;0)+(data&lt;&lt;8)+(data&lt;&lt;16)+(data&lt;&lt;24);

                status=FLASH_ProgramWord(addr, temp);
               
                if(status!=FLASH_COMPL)
                {
                        return;
                }
                               
                data += 4;
                addr += 4;
        }
       
        if((len % 4)==3)
        {
                temp = (data&lt;&lt;0)+(data&lt;&lt;8)+(data&lt;&lt;16);
                temp = temp | 0xff000000;
                status=FLASH_ProgramWord(addr,temp);
                if(status!=FLASH_COMPL)
                {
                        return;
                }
        }
        else
        {
                if((len % 4)==2)
                {
                        temp = (data&lt;&lt;0)+(data&lt;&lt;8);
                        temp = temp | 0xffff0000;
                  status=FLASH_ProgramWord(addr,temp);
                }
                else
                {
                        if((len % 4)==1)
                        {
                                temp = (data&lt;&lt;0);
                                temp = temp |0xffffff00 ;
                                status=FLASH_ProgramWord(addr,temp);
                                if(status!=FLASH_COMPL)
                                {
                                        return;
                                }
                        }
                }
        }

        FLASH_Lock();
}


void FlashRead(uint16_t len,uint8_t *outdata,uint32_t addr_start)
{       
        uint32_t addr;
        uint16_t i;
       
        addr = addr_start;
       
        for(i=0;i&lt;len;i++)
        {
                *outdata = *(uint8_t*) addr;
                addr = addr + 1;
                outdata++;
        }
}


void FlashErase(uint32_t start, uint32_t end)
{
        uint8_t index;
        FLASH_STS status = FLASH_COMPL;

    while(FLASH_HSICLOCK_ENABLE != FLASH_ClockInit()) {};
       
        FLASH_Unlock();
       
        /* erase the flash pages */
    while(start &lt; end)
        {
                index = start/FLASH_PAGE_SIZE;
      status=FLASH_EraseOnePage(index*FLASH_PAGE_SIZE);
                if(status!=FLASH_COMPL)
                {
                        return;
                }
                start += FLASH_PAGE_SIZE;
    }
       
        FLASH_Lock();
}
</code></pre>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;">4、测试</span></strong></p>

<p><span style="font-size:16px;">flash测试空间为最后一个page</span></p>

<pre>
<code class="language-cs">#define APP_DATA_SATRT_ADDR                                          0x0801F800 //2k

#define TEST_DATA_LEN    11
uint8_t WriteData={1,2,3,4,5,6,7,8,9,10,11};
uint8_tReadData={0,0,0,0,0,0,0,0,0, 0,0};

void FlashTest(void)
{
        FLASH_SetLatency(FLASH_LATENCY_3);

        FlashErase(APP_DATA_SATRT_ADDR, APP_DATA_SATRT_ADDR+FLASH_PAGE_SIZE);
        FlashWrite(TEST_DATA_LEN,WriteData,APP_DATA_SATRT_ADDR);
        FlashRead(TEST_DATA_LEN,ReadData, APP_DATA_SATRT_ADDR);
       
        printf("Write Data[");
        for(uint8_t i=0;i&lt;TEST_DATA_LEN;i++)
        {
                printf(" %d",WriteData);
        }
        printf("]\r\n");

       
        printf("Read Data[");
        for(uint8_t i=0;i&lt;TEST_DATA_LEN;i++)
        {
                printf(" %d",ReadData);
        }
        printf("]\r\n");
}</code></pre>

<p>&nbsp;</p>

<p><strong><span style="font-size:22px;">5、现象</span></strong></p>

<p>&nbsp;可以看出,写进去的和读出来的一致。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

Jacktang 发表于 2022-7-16 22:04

<p>关于flash操作注意事项的学习了</p>

秦天qintian0303 发表于 2022-7-16 22:16

<p>操作FLASH必须打开HSI吗?要是使用外部高速时钟呢</p>

freeelectron 发表于 2022-7-16 22:44

秦天qintian0303 发表于 2022-7-16 22:16
操作FLASH必须打开HSI吗?要是使用外部高速时钟呢

<p>必须hsi</p>
页: [1]
查看完整版本: 【N32L43x评测】8、Flash读\写\擦除——使用内部Flash存储数据