【翌创ET6001测评】W25X读写测试
<p>翌创ET6001开发板提供了对NorFlash存储器件的读写功能,所支持的芯片为W25X40。</p><p >由资料可知,W25X40是一款4M的flash,其工作电压为2.7-3.6V,存储容量4M-bit。具有双向SPI输出功能,是普通SPI接口的2倍速度。</p>
<p > </p>
<p >该芯片与开发板的连接关系为:</p>
<p >CLK---GPIO2_0</p>
<p >MISO---GPIO2_1</p>
<p >MOSI---GPIO2_2</p>
<p >CS----GPIO2_3</p>
<p > </p>
<p >由于在开发板上并没有配置该芯片,故在完成程序编译和运行的情况下,其运行结果如图1所示。</p>
<p > </p>
<p>图1 无芯片测试</p>
<p > </p>
<p >由此可知,测试程序的基本功能为:</p>
<ol>
<li >读取芯片ID</li>
<li >擦除芯片</li>
<li >写入数据</li>
<li >读取数据</li>
</ol>
<p align="justify" > </p>
<p >手头有一款W25Q16的存储模块,由资料可知W25Q16是一款16M-bit的存储芯片,工作电压为2.7V到3.6V,正常工作时电流小于5mA。</p>
<p >W25Q16的每一页有256个字节,共有8192页,每16页是一个扇区。每页的256个字节用一次页编程指令接口完成。每次擦除128页(32KB块)或全片擦除。</p>
<p > </p>
<p >这里用该存储模块来进行读写测试,相应的引脚连接关系为:</p>
<p >CLK---GPIO2_0</p>
<p >DO ---GPIO2_1</p>
<p >DI---GPIO2_2</p>
<p >CS----GPIO2_3</p>
<p > </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(&init);
init.dataFrameSize = 0x7;
init.transferMode = SPI_EEPROM_READ;
init.clkDiv = 2;
init.rxSampleDly = 2;
init.readDataNum = 2;
SPI_Init(SPI0, &init);
SPI_Enable(SPI0);
sendData = FLASHCMD_READ_DEVICE_ID;
sendData = 0x0;
sendData = 0x0;
sendData = 0x0;
SPI_Transmit(SPI0, (uint8_t *)(&sendData), 4, MAX_TIMEOUT);
SPI_Receive(SPI0, receiveData, 2, MAX_TIMEOUT);
printf("read w25x40 device identification \n", receiveData, receiveData);
}</code></pre>
<p> </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 *)(&sendData), 1, MAX_TIMEOUT);
while (!SPI_IsDeviceReady());
}</code></pre>
<p> </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 & 0xFF0000) >> 16;
sendData = (addr & 0xFF00) >> 8;
sendData = addr & 0xFF;
SPI_Transmit(SPI0, (uint8_t *)(&sendData), 4, MAX_TIMEOUT);
SPI_Receive(SPI0, data, 4, MAX_TIMEOUT);
for (i = 0;i < 4;i++) {
printf("read data = 0x%x\n",data);
}
}</code></pre>
<p> </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 & 0xFF0000) >> 16);
data = (uint8_t)((addr & 0xFF00) >> 8);
data = (uint8_t)(addr & 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> </p>
<p>需注意的是,无论是读取函数还是是写入函数,其操作地址都是在函数内通过变量addr来指定的,这样就不如以参数的方式来指定地址更为方便。</p>
<p > </p>
<p >在连接后,其工作状态如图2及运行结果见图3所示,说明尽管所提供的例程是为W25X40所准备的,但对于W25Q16来说依然有效。</p>
<p > </p>
<p>图2 运行状态</p>
<p> </p>
<p> </p>
<p>图3 运行结果</p>
<p> </p>
<p>有了W25Q16存储模块的支持,就可为开发板提供更大的数据存储空间以放置常用的相对固定数据,如字库和图片库等,作用还是很强的。</p>
<p>W25Q16存储模块的支持,对字库和图片库等,作用确实是很强的。</p>
页:
[1]