jinglixixi 发表于 2020-6-15 09:57

【AutoChips 7801x MCU评测报告】+W25Q16数据存储模块的使用

本帖最后由 jinglixixi 于 2020-7-11 22:17 编辑

在官网的例程中,提供了W25Q16的读写程序,但在开发板上却并未配置该芯片。为对其加以验证,便在网上购置了一个基于W25Q16数据存储模块。工具开发板的原理图,可知该模块各引脚与MCU的连接关系为:CLK——PB15D0 ——PC0CS ——PC1DI ——PB14
开发板与数据存储模块的连接如图1所示图1 实物连接
例程经编译后,由再调试工具将程序下载到芯片中。重新上电后,若按下K7键,则对数据进行读取;若按下K6键,则对进行数据写入,其输出效果如图2所示。图2 读写输出效果
对于普通的显示屏,显然是不提供中文字库支持的,因此要显示中文信息就必须自行构建一个小字库来解决问题。使用该数据存储模块,就可以来存放中文字库了。在中文字库的提取方面,可以用3310液晶显示屏汉字提取程序来实现,其界面如图3所示。图3 字模提取
以内存转储为例,其方法是:1)将字模存入数值unsigned char g_w25x16WrDataBuf={0x00,0x00,0x00,0x00,0x10,0x60,0x02,0x0C,0xC0,0x10,0x08,0xF7,0x14,0x54,0x94,0x14,0xF4,0x04,0x00,0x00,0x04,0x04,0x7C,0x03,0x00,0x01,0x1D,0x13,0x11,0x55,0x99,0x51,... ...0x44,0x44,0x44,0x44,0x5F,0xC4,0x74,0x44,0x44,0x44,0x5F,0x44,0x44,0x44,0x44,0x00,0x10,0x08,0x04,0x02,0xFF,0x42,0x42,0x42,0x42,0x42,0x42,0xFE,0x00,0x00,0x00,0x00,};2)使用SPI_W25X16WrPage()语句执行转储功能3)使用SPI_W25X16RdPage()语句执行读取功能4)在OLED 屏上加以验证,其效果如图4所示图4 显示效果

marginer 发表于 2020-6-15 13:40

海内存知已,天涯若比邻

wf663776 发表于 2020-10-16 14:31

weict125 发表于 2020-10-16 15:25

{:smile:}

FKASHFKA 发表于 2021-5-27 21:23

有原程序吗,发来看看

jinglixixi 发表于 2021-5-28 07:55

FKASHFKA 发表于 2021-5-27 21:23
有原程序吗,发来看看

见官网的例程

zgs717 发表于 2021-5-29 08:54

本帖最后由 zgs717 于 2021-5-29 09:03 编辑

jinglixixi 发表于 2021-5-28 07:55
见官网的例程
你好,可否提供一个例程代码链接呢?找了下官网AC7801x下列程没有咯{:smile:},或者有W25Q16C的驱动代码列程(AC7811x或AC7801x)最好哦,谢谢!

jinglixixi 发表于 2021-5-29 09:09

zgs717 发表于 2021-5-29 08:54
你好,可否提供一个例程代码链接呢?找了下官网AC7801x下列程没有咯,或者有W25Q16C的驱动代码列 ...

好久没啥活动,已不用它了,就清了。

zgs717 发表于 2021-5-29 23:53

jinglixixi 发表于 2021-5-29 09:09
好久没啥活动,已不用它了,就清了。

请问还有机会找到W25Q16C的SPI驱动程序不?我现在正在用AC7811QBGE开发板调试驱动GD25Q16C,发现读取不了数据,有时候读取回来的数据是错误的,有点不稳定。

jinglixixi 发表于 2021-5-30 00:47

zgs717 发表于 2021-5-29 23:53
请问还有机会找到W25Q16C的SPI驱动程序不?我现在正在用AC7811QBGE开发板调试驱动GD25Q16C,发现读取不了 ...

抱歉,实在没有了,给你个AT32F421的参考一下吧!
想发个附件,电脑有问题不能添加附件发送,只好贴在下面:

/** ******************************************************************************* File   : SPI/SPI_W25Q_Flash/spi_flash.c * Version:V1.2.9* Date   : 2021-01-15* Brief: W25Q flash source code *******************************************************************************/ #include "at32f4xx.h"#include "spi_flash.h" uint8_t SpiFlash_SectorBuf;/* asector size */ uint8_t SpiFlash_Init(void){GPIO_InitTypeGPIO_InitStructure; SPI_InitTypeSPI_InitStructure; GPIO_StructInit(&GPIO_InitStructure); RCC_APB2PeriphClockCmd(SPIx_RCC_CLK, ENABLE); RCC_AHBPeriphClockCmd(SPIx_DMA_RCC_CLK | SPIx_GPIO_RCC_CLK, ENABLE); /* ConfigureSPI_FLASH pins*/ GPIO_InitStructure.GPIO_Pins = SPIx_PIN_MOSI; GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(SPIx_PORT_MOSI, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pins = SPIx_PIN_MISO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(SPIx_PORT_MISO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pins = SPIx_PIN_SCK; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(SPIx_PORT_SCK, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pins = SPIx_PIN_NSS; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP; GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL; GPIO_Init(SPIx_PORT_NSS, &GPIO_InitStructure); GPIO_PinAFConfig(SPIx_PORT_MOSI, GPIO_PinsSource5, GPIO_AF_0); GPIO_PinAFConfig(SPIx_PORT_MOSI, GPIO_PinsSource6, GPIO_AF_0); GPIO_PinAFConfig(SPIx_PORT_MOSI, GPIO_PinsSource7, GPIO_AF_0); FLASH_CS_HIGH();/* SPI_FLASHconfiguration ------------------------------------------------------*/ SPI_InitStructure.SPI_TransMode = SPI_TRANSMODE_FULLDUPLEX; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2EDGE; SPI_InitStructure.SPI_CPOL = SPI_CPOL_HIGH; SPI_InitStructure.SPI_CPOLY = 0; SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB; SPI_InitStructure.SPI_FrameSize = SPI_FRAMESIZE_8BIT; SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_8; SPI_InitStructure.SPI_NSSSEL = SPI_NSSSEL_SOFT; SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER; SPI_Init(FLASH_SPI, &SPI_InitStructure); /* Enable SPImodule */ SPI_Enable(FLASH_SPI, ENABLE); return 1; } /*** @briefWrite data to flash* @parampbBuffer: buffer name* @paramdwWriteAddr: buffer address * @paramdwNumByteToWrite: buffer length * @retval none*/void SpiFlash_Write(uint8_t* pbBuffer, uint32_tdwWriteAddr, uint32_t dwNumByteToWrite){ uint32_tdwSectorPos;uint16_twSectorOffset;uint16_twSectorRemain;       uint16_t i;   uint8_t *SpiFlash_BUF;    SpiFlash_BUF =SpiFlash_SectorBuf;          dwSectorPos = dwWriteAddr / SPIF_SECTOR_SIZE;// sector addresswSectorOffset= dwWriteAddr % SPIF_SECTOR_SIZE; // address offset in a sectorwSectorRemain= SPIF_SECTOR_SIZE - wSectorOffset; // the remain in a sector     if(dwNumByteToWrite <= wSectorRemain){   wSectorRemain = dwNumByteToWrite; // smaller than a sector size}while(1) {    SpiFlash_Read(SpiFlash_BUF, dwSectorPos * SPIF_SECTOR_SIZE,SPIF_SECTOR_SIZE); // read a sector    for(i=0;i<wSectorRemain; i++) // validate the read erea    {   if(SpiFlash_BUF!=0xFF)      {         break;//t here are some data not equal 0xFF, so this secotr needs erased      }    }    if(i <wSectorRemain) // need erase    {      SpiFlash_Erase_Sector(dwSectorPos); //erase the sector      for(i=0;i<wSectorRemain; i++) // copy the write data      {       SpiFlash_BUF = pbBuffer;          }   SpiFlash_Write_NoCheck(SpiFlash_BUF, dwSectorPos * SPIF_SECTOR_SIZE,SPIF_SECTOR_SIZE); // program the sector    }    else     {   SpiFlash_Write_NoCheck(pbBuffer, dwWriteAddr, wSectorRemain); // writedirectly in the erased area                   }   if(dwNumByteToWrite == wSectorRemain)    {      break; //write end    }    else // goon writing    {   dwSectorPos++;   wSectorOffset = 0;          pbBuffer+= wSectorRemain;                  dwWriteAddr += wSectorRemain;                      dwNumByteToWrite -= wSectorRemain;            if(dwNumByteToWrite > SPIF_SECTOR_SIZE)      {       wSectorRemain = SPIF_SECTOR_SIZE; // Could not write the remain data inthe next sector      }      else      {       wSectorRemain = dwNumByteToWrite; // Could write the remain data in thenext sector      }    }    }} /*** @briefRead data from flash* @parampbBuffer: buffer name* @paramdwReadAddr: buffer address* @paramdwNumByteToRead: buffer length* @retval none*/void SpiFlash_Read(uint8_t* pbBuffer, uint32_tdwReadAddr, uint32_t dwNumByteToRead){ FLASH_CS_LOW(); SPI_WriteByte(SPIF_ReadData); // send instruction SPI_WriteByte((uint8_t)((dwReadAddr) >> 16)); //send 24-bitaddress SPI_WriteByte((uint8_t)((dwReadAddr) >> 8));SPI_WriteByte((uint8_t)dwReadAddr); SPI_ReadBytes(pbBuffer,dwNumByteToRead); FLASH_CS_HIGH();} /*** @briefErase a sector data* @paramdwDstAddr: Sector address to erase* @retval none*/void SpiFlash_Erase_Sector(uint32_t dwDstAddr){    dwDstAddr*=SPIF_SECTOR_SIZE; // translatesector address to byte address SpiFlash_Write_Enable(); SpiFlash_Wait_Busy(); FLASH_CS_LOW(); SPI_WriteByte(SPIF_SectorErase); SPI_WriteByte((uint8_t)((dwDstAddr) >> 16));SPI_WriteByte((uint8_t)((dwDstAddr)>> 8)); SPI_WriteByte((uint8_t)dwDstAddr); FLASH_CS_HIGH(); SpiFlash_Wait_Busy();} /*** @briefWrite data without check * @parampbBuffer: buffer name* @paramdwWriteAddr: buffer address * @paramdwNumByteToWrite: buffer length * @retval none*/void SpiFlash_Write_NoCheck(uint8_t* pbBuffer,uint32_t dwWriteAddr, uint32_t dwNumByteToWrite)   {uint16_twPageRemain; wPageRemain=SPIF_PAGE_SIZE - dwWriteAddr % SPIF_PAGE_SIZE; // remainbytes in a page if(dwNumByteToWrite<=wPageRemain){   wPageRemain=dwNumByteToWrite;// smaller than a page size}    while(1)    {   SpiFlash_Write_Page(pbBuffer, dwWriteAddr, wPageRemain);      if(dwNumByteToWrite==wPageRemain)    {      break; //all data are programmed     }      else// NumByteToWrite>pageremain      {      pbBuffer+= wPageRemain;   dwWriteAddr += wPageRemain;   dwNumByteToWrite -= wPageRemain; // the remain bytes to be prorammed   if(dwNumByteToWrite > SPIF_PAGE_SIZE)      {       wPageRemain = SPIF_PAGE_SIZE; // can be progrmmed a page at a time      }      else      {       wPageRemain = dwNumByteToWrite; // smaller than a page size      }      }    }} /*** @briefWrite a page data* @parampbBuffer: buffer name* @paramdwWriteAddr: buffer address * @paramdwNumByteToWrite: buffer length* @retval none*/void SpiFlash_Write_Page(uint8_t* pbBuffer, uint32_tdwWriteAddr, uint32_t dwNumByteToWrite){if((0 < dwNumByteToWrite)&& (dwNumByteToWrite <= SPIF_PAGE_SIZE)){   SpiFlash_Write_Enable(); // SET WEL   FLASH_CS_LOW();   SPI_WriteByte(SPIF_PageProgram); // send instruction   SPI_WriteByte((uint8_t)((dwWriteAddr) >> 16)); // send 24-bitaddress   SPI_WriteByte((uint8_t)((dwWriteAddr) >> 8));   SPI_WriteByte((uint8_t)dwWriteAddr);   SPI_WriteBytes(pbBuffer,dwNumByteToWrite);   FLASH_CS_HIGH();   SpiFlash_Wait_Busy(); // Wait for program end}} /*** @briefWrite data continuously* @parampbBuffer: buffer name* @paramdwNumByteToWrite: buffer length* @retval none*/static void SPI_WriteBytes(uint8_t* pbBuffer, uint32_tdwNumByteToWrite){volatileuint8_t dummy_data; #if (SPI_MODE == 0)DMA_InitTypeDMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&FLASH_SPI->DT); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&dummy_data; DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = dwNumByteToWrite; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_DISABLE; DMA_InitStructure.DMA_PeripheralDataWidth =DMA_PERIPHERALDATAWIDTH_BYTE; DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(SPIx_Rx_DMA_Channel, &DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&FLASH_SPI->DT); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pbBuffer; DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST; DMA_InitStructure.DMA_BufferSize = dwNumByteToWrite; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataWidth =DMA_PERIPHERALDATAWIDTH_BYTE; DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(SPIx_Tx_DMA_Channel, &DMA_InitStructure); SPI_I2S_DMAEnable(FLASH_SPI,SPI_I2S_DMA_TX,ENABLE); SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_RX,ENABLE); DMA_ChannelEnable(SPIx_Rx_DMA_Channel, ENABLE); DMA_ChannelEnable(SPIx_Tx_DMA_Channel, ENABLE); while(DMA_GetFlagStatus(SPIx_Rx_DMA_FLAG) != SET); DMA_ClearFlag(SPIx_Rx_DMA_FLAG); DMA_ChannelEnable(SPIx_Tx_DMA_Channel, DISABLE); DMA_ChannelEnable(SPIx_Rx_DMA_Channel, DISABLE); SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_RX, DISABLE); SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_TX, DISABLE);#else while(dwNumByteToWrite--){   while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TE) == RESET);   SPI_I2S_TxData(FLASH_SPI, *pbBuffer);   while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RNE) == RESET);    dummy_data =SPI_I2S_RxData(FLASH_SPI);    pbBuffer ++;}#endif} /*** @briefWait program done* @paramnone* @retval none*/static void SpiFlash_Wait_Busy(void){    while((SpiFlash_ReadSR1()&0x01)== 0x01);} /*** @briefRead SR1 register* @paramnone* @retval none*/static uint8_t SpiFlash_ReadSR1(void){uint8_tbReadByte=0; FLASH_CS_LOW(); SPI_WriteByte(SPIF_ReadStatusReg1); bReadByte=(uint8_t)SPI_ReadByte(); FLASH_CS_HIGH();    return(bReadByte);} /*** @briefEnable write operation* @paramnone* @retval none*/static void SpiFlash_Write_Enable(void)   { FLASH_CS_LOW(); SPI_WriteByte(SPIF_WriteEnable); FLASH_CS_HIGH();} /*** @briefRead device ID* @paramnone* @retvaldevice ID*/uint16_t SpiFlash_ReadID(void){    uint16_twReceiveData = 0; FLASH_CS_LOW(); SPI_WriteByte(SPIF_ManufactDeviceID); SPI_WriteByte(0x00); SPI_WriteByte(0x00); SPI_WriteByte(0x00); wReceiveData|=SPI_ReadByte() << 8; wReceiveData|=SPI_ReadByte(); FLASH_CS_HIGH();    returnwReceiveData;} /*** @briefWrite a byte to flash* @parambWriteValue: Data to write* @retvalFlash return data*/static uint8_t SPI_WriteByte(uint8_t bWriteValue){uint8_tbRxBuff; SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_TX, DISABLE); SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_RX, DISABLE); SPI_I2S_TxData(FLASH_SPI, bWriteValue); while(!SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RNE));bRxBuff = SPI_I2S_RxData(FLASH_SPI); while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_BUSY)); returnbRxBuff;} /*** @briefRead a byte to flash* @paramnone* @retvalFlash return data*/ static uint8_t SPI_ReadByte(void){return(SPI_WriteByte(FLASH_SPI_DUMMY_BYTE));} /*** @briefRead data continuously* @parampbBuffer: Buffer to save data* @paramdwNumByteToRead: Buffer length* @retval none*/static void SPI_ReadBytes(uint8_t *pbBuffer, uint32_tdwNumByteToRead){uint8_tbWriteValue = FLASH_SPI_DUMMY_BYTE; #if (SPI_MODE == 0)DMA_InitTypeDMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&FLASH_SPI->DT); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&bWriteValue; DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST; DMA_InitStructure.DMA_BufferSize = dwNumByteToRead; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_DISABLE; DMA_InitStructure.DMA_PeripheralDataWidth =DMA_PERIPHERALDATAWIDTH_BYTE; DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(SPIx_Tx_DMA_Channel, &DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&FLASH_SPI->DT); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pbBuffer;DMA_InitStructure.DMA_Direction= DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = dwNumByteToRead; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataWidth =DMA_PERIPHERALDATAWIDTH_BYTE; DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(SPIx_Rx_DMA_Channel, &DMA_InitStructure); SPI_I2S_DMAEnable(FLASH_SPI,SPI_I2S_DMA_TX, ENABLE); SPI_I2S_DMAEnable(FLASH_SPI,SPI_I2S_DMA_RX, ENABLE);    DMA_ChannelEnable(SPIx_Rx_DMA_Channel, ENABLE); DMA_ChannelEnable(SPIx_Tx_DMA_Channel, ENABLE); while(DMA_GetFlagStatus(SPIx_Rx_DMA_FLAG)!=SET); DMA_ClearFlag(SPIx_Rx_DMA_FLAG); DMA_ChannelEnable(SPIx_Tx_DMA_Channel, DISABLE); DMA_ChannelEnable(SPIx_Rx_DMA_Channel, DISABLE);SPI_I2S_DMAEnable(FLASH_SPI,SPI_I2S_DMA_TX, DISABLE); SPI_I2S_DMAEnable(FLASH_SPI, SPI_I2S_DMA_RX, DISABLE);#else while(dwNumByteToRead--){   while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TE) == RESET);   SPI_I2S_TxData(FLASH_SPI, bWriteValue);   while(SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RNE) == RESET);    *pbBuffer =SPI_I2S_RxData(FLASH_SPI);    pbBuffer++;}#endif /* SPI_MODE */}

caigang13 发表于 2021-6-1 08:13

楼上的代码贴的厂
页: [1]
查看完整版本: 【AutoChips 7801x MCU评测报告】+W25Q16数据存储模块的使用