jinglixixi 发表于 2024-11-17 11:31

【翌创ET6001测评】W25X读写测试

<p>翌创ET6001开发板提供了对NorFlash存储器件的读写功能,所支持的芯片为W25X40。</p>

<p >由资料可知,W25X40是一款4M的flash,其工作电压为2.7-3.6V,存储容量4M-bit。具有双向SPI输出功能,是普通SPI接口的2倍速度。</p>

<p >&nbsp;</p>

<p >该芯片与开发板的连接关系为:</p>

<p >CLK---GPIO2_0</p>

<p >MISO---GPIO2_1</p>

<p >MOSI---GPIO2_2</p>

<p >CS----GPIO2_3</p>

<p >&nbsp;</p>

<p >由于在开发板上并没有配置该芯片,故在完成程序编译和运行的情况下,其运行结果如图1所示。</p>

<p > &nbsp;</p>

<p>图1 无芯片测试</p>

<p >&nbsp;</p>

<p >由此可知,测试程序的基本功能为:</p>

<ol>
        <li >读取芯片ID</li>
        <li >擦除芯片</li>
        <li >写入数据</li>
        <li >读取数据</li>
</ol>

<p align="justify" >&nbsp;</p>

<p >手头有一款W25Q16的存储模块,由资料可知W25Q16是一款16M-bit的存储芯片,工作电压为2.7V到3.6V,正常工作时电流小于5mA。</p>

<p >W25Q16的每一页有256个字节,共有8192页,每16页是一个扇区。每页的256个字节用一次页编程指令接口完成。每次擦除128页(32KB块)或全片擦除。</p>

<p >&nbsp;</p>

<p >这里用该存储模块来进行读写测试,相应的引脚连接关系为:</p>

<p >CLK---GPIO2_0</p>

<p >DO&nbsp;---GPIO2_1</p>

<p >DI---GPIO2_2</p>

<p >CS----GPIO2_3</p>

<p >&nbsp;</p>

<p >读取芯片ID的函数为:</p>

<pre>
<code class="language-cpp">static void SPI_ReadDeviceID(void)
{
    uint8_t sendData = {0};
    uint8_t receiveData = {0};
    SPI_InitType init;
    SPI_DeInit(SPI0);
    SPI_StructInit(&amp;init);
    init.dataFrameSize = 0x7;
    init.transferMode = SPI_EEPROM_READ;
    init.clkDiv = 2;
    init.rxSampleDly = 2;
    init.readDataNum = 2;
    SPI_Init(SPI0, &amp;init);
    SPI_Enable(SPI0);
    sendData = FLASHCMD_READ_DEVICE_ID;
    sendData = 0x0;
    sendData = 0x0;
    sendData = 0x0;
    SPI_Transmit(SPI0, (uint8_t *)(&amp;sendData), 4, MAX_TIMEOUT);
    SPI_Receive(SPI0, receiveData, 2, MAX_TIMEOUT);
    printf("read w25x40 device identification \n", receiveData, receiveData);
}</code></pre>

<p>&nbsp;</p>

<p>进行芯片整体擦除的函数为:</p>

<pre>
<code class="language-cpp">static void SPI_DeviceChipErase(void)
{
    SPI_DeviceWriteEnable();
    uint8_t sendData;
    sendData = FLASHCMD_CHIP_ERASE;
    SPI_Transmit(SPI0, (uint8_t *)(&amp;sendData), 1, MAX_TIMEOUT);
    while (!SPI_IsDeviceReady());
}</code></pre>

<p>&nbsp;</p>

<p>读取数据的函数为:</p>

<pre>
<code class="language-cpp">static void SPI_DeviceRead(void)
{
    uint32_t i;
    uint32_t addr = 0;
    uint8_t data = {0};
    uint8_t sendData = {0};
    while(SPI_STATE_READY != SPI_GetState(SPI0));
    while (!SPI_IsDeviceReady());
    while(SPI_STATE_READY != SPI_GetState(SPI0));
    SPI_ConfigTransMode(SPI0, SPI_EEPROM_READ);
    SPI_ConfigFrameNum(SPI0, 4);
    sendData = FLASHCMD_READ_DATA;
    sendData = (addr &amp; 0xFF0000) &gt;&gt; 16;
    sendData = (addr &amp; 0xFF00) &gt;&gt; 8;
    sendData = addr &amp; 0xFF;
    SPI_Transmit(SPI0, (uint8_t *)(&amp;sendData), 4, MAX_TIMEOUT);
    SPI_Receive(SPI0, data, 4, MAX_TIMEOUT);
    for (i = 0;i &lt; 4;i++) {
      printf("read data = 0x%x\n",data);
    }
}</code></pre>

<p>&nbsp;</p>

<p>写入数据的函数为:</p>

<pre>
<code class="language-cpp">static void SPI_DeviceWrite(void)
{
    bool state;
    uint32_t addr = 0x0;
    uint8_t data = {0};
    state = SPI_DeviceWriteEnable();
    if (state == false)
      return ;
    data = FLASHCMD_PAGE_PROGRAM;
    while(SPI_STATE_READY != SPI_GetState(SPI0));
    data = (uint8_t)((addr &amp; 0xFF0000) &gt;&gt; 16);
    data = (uint8_t)((addr &amp; 0xFF00) &gt;&gt; 8);
    data = (uint8_t)(addr &amp; 0xFF);
    data = 0x12;
    data = 0x34;
    data = 0x56;
    data = 0x78;
    SPI_Transmit(SPI0, data, 8, MAX_TIMEOUT);
    while(SPI_STATE_READY != SPI_GetState(SPI0));
    while (!SPI_IsDeviceReady());
    printf("write data 0x12,0x34,0x56,0x78\n");
}</code></pre>

<p>&nbsp;</p>

<p>需注意的是,无论是读取函数还是是写入函数,其操作地址都是在函数内通过变量addr来指定的,这样就不如以参数的方式来指定地址更为方便。</p>

<p >&nbsp;</p>

<p >在连接后,其工作状态如图2及运行结果见图3所示,说明尽管所提供的例程是为W25X40所准备的,但对于W25Q16来说依然有效。</p>

<p > &nbsp;</p>

<p>图2 运行状态</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>图3 &nbsp;运行结果</p>

<p>&nbsp;</p>

<p>有了W25Q16存储模块的支持,就可为开发板提供更大的数据存储空间以放置常用的相对固定数据,如字库和图片库等,作用还是很强的。</p>

Jacktang 发表于 2024-11-18 07:34

<p>W25Q16存储模块的支持,对字库和图片库等,作用确实是很强的。</p>
页: [1]
查看完整版本: 【翌创ET6001测评】W25X读写测试