[$group] 元件库-储存器.$pname$ [$last_ver_update_time] 2021-04-03 [$min_need_ver] 1.23 [$p_list] [$short_show_UIname] [$code_area_type] codes,exe_per_1ms,init_code [$blocks_type] line [$name] w25q64的初始化积木 [($_xgm$spi_sel),type=num]|寄存器占用:spi flash存储器积木已经占用此spi端口 [$引脚占用列表,用于提示冲突] [($_xgm$Cs_pin1),type=pin]|spi flash存储器积木已经占用此cs片选脚 [$寄存器占用列表,用于提示冲突,但=>后的值没变则不提示冲突] [$中断函数号占用列表,用于提示冲突] [$thread_do] [$cs] [$function_ref_define_in_headfile] @@file=w25qxxx.h extern u8 SPI_FLASH_writeBUF[]; // NSS #define SPI_FLASH_CS_LOW_$rnd_varname_pre$() IO_Write([($_xgm$Cs_pin1),type=pin] ,0) #define SPI_FLASH_CS_HIGH_$rnd_varname_pre$() IO_Write([($_xgm$Cs_pin1),type=pin] ,1) //Write_Protect #define SPI_FLASH_Write_Protect_Assert_$rnd_varname_pre$() // GPIO_ResetBits(GPIOC, GPIO_Pin_6) #define SPI_FLASH_Write_Protect_Deassert_$rnd_varname_pre$() // GPIO_SetBits(GPIOC, GPIO_Pin_6) //Hold #define SPI_FLASH_Hold_Assert_$rnd_varname_pre$() // GPIO_ResetBits(GPIOD, GPIO_Pin_15) #define SPI_FLASH_Hold_Deassert_$rnd_varname_pre$() //GPIO_SetBits(GPIOD, GPIO_Pin_15) void SPI_FLASH_Write_Protect_ENABLE_$rnd_varname_pre$(void);//flash 关闭写保护 void SPI_FLASH_Write_Protect_DISABLE_$rnd_varname_pre$(void);//flash 打开写保护 void SPI_FLASH_Hold_ENABLE_$rnd_varname_pre$(void);//flash HOLD ENABLE void SPI_FLASH_Hold_DISABLE_$rnd_varname_pre$(void);//flash HOLD DISABLE void SPI_FLASH_Init_$rnd_varname_pre$(void); void SPI_FLASH_SectorErase_$rnd_varname_pre$(u32 SectorAddr); void SPI_FLASH_BulkErase_$rnd_varname_pre$(void); void SPI_FLASH_PageWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite); void SPI_FLASH_BufferWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite); void SPI_FLASH_BufferRead_$rnd_varname_pre$(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead); u32 SPI_FLASH_ReadID_$rnd_varname_pre$(void); u32 SPI_FLASH_ReadDeviceID_$rnd_varname_pre$(void); void SPI_FLASH_StartReadSequence_$rnd_varname_pre$(u32 ReadAddr); void SPI_Flash_PowerDown_$rnd_varname_pre$(void); void SPI_Flash_WAKEUP_$rnd_varname_pre$(void); void SPI_Flash_Write_by_earse_ok_$rnd_varname_pre$(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite); void W25X_Read_Sector_$rnd_varname_pre$(uint32_t nSector, u8* pBuffer); void W25X_Write_Sector_$rnd_varname_pre$(uint32_t nSector, u8* pBuffer); //void SPI_FLASH_SendByte(u8 byte); u8 SPI_FLASH_SendByte_$rnd_varname_pre$(u8 byte); u8 SPI_FLASH_ReadByte_$rnd_varname_pre$(void); u16 SPI_FLASH_SendHalfWord_$rnd_varname_pre$(u16 HalfWord); void SPI_FLASH_WriteEnable_$rnd_varname_pre$(void); void SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(void); [$init_code_for_define_area_once] @@file=w25qxxx.c u8 SPI_FLASH_BUF[4096]; u8 SPI_FLASH_writeBUF[100]; [$init_code_for_define_area] @@file=w25qxxx.c #define uint8 u8 #define uint16 u16 #define uint32 u32 #include "main.h" #include "usart_Lib.h" #include "protothread.h" #include "app_process.h" #include "sys/timer.h" #include "Extline_Lib.h" #include "Lib_base.h" //考虑PROCESS2_WAIT_UNTIL宏 #include "spi_Lib.h" // NSS #define SPI_FLASH_CS_LOW_$rnd_varname_pre$() IO_Write([($_xgm$Cs_pin1),type=pin] ,0) #define SPI_FLASH_CS_HIGH_$rnd_varname_pre$() IO_Write([($_xgm$Cs_pin1),type=pin] ,1) //Write_Protect #define SPI_FLASH_Write_Protect_Assert_$rnd_varname_pre$() // GPIO_ResetBits(GPIOC, GPIO_Pin_6) #define SPI_FLASH_Write_Protect_Deassert_$rnd_varname_pre$() // GPIO_SetBits(GPIOC, GPIO_Pin_6) //Hold #define SPI_FLASH_Hold_Assert_$rnd_varname_pre$() // GPIO_ResetBits(GPIOD, GPIO_Pin_15) #define SPI_FLASH_Hold_Deassert_$rnd_varname_pre$() //GPIO_SetBits(GPIOD, GPIO_Pin_15) void SPI_FLASH_Write_Protect_ENABLE_$rnd_varname_pre$(void);//flash 关闭写保护 void SPI_FLASH_Write_Protect_DISABLE_$rnd_varname_pre$(void);//flash 打开写保护 void SPI_FLASH_Hold_ENABLE_$rnd_varname_pre$(void);//flash HOLD ENABLE void SPI_FLASH_Hold_DISABLE_$rnd_varname_pre$(void);//flash HOLD DISABLE void SPI_FLASH_Init_$rnd_varname_pre$(void); void SPI_FLASH_SectorErase_$rnd_varname_pre$(u32 SectorAddr); void SPI_FLASH_BulkErase_$rnd_varname_pre$(void); void SPI_FLASH_PageWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite); void SPI_FLASH_BufferWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite); void SPI_FLASH_BufferRead_$rnd_varname_pre$(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead); u32 SPI_FLASH_ReadID_$rnd_varname_pre$(void); u32 SPI_FLASH_ReadDeviceID_$rnd_varname_pre$(void); void SPI_FLASH_StartReadSequence_$rnd_varname_pre$(u32 ReadAddr); void SPI_Flash_PowerDown_$rnd_varname_pre$(void); void SPI_Flash_WAKEUP_$rnd_varname_pre$(void); void SPI_Flash_Write_by_earse_ok_$rnd_varname_pre$(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite); void W25X_Read_Sector_$rnd_varname_pre$(uint32_t nSector, u8* pBuffer); void W25X_Write_Sector_$rnd_varname_pre$(uint32_t nSector, u8* pBuffer); //void SPI_FLASH_SendByte(u8 byte); u8 SPI_FLASH_SendByte_$rnd_varname_pre$(u8 byte); u8 SPI_FLASH_ReadByte_$rnd_varname_pre$(void); u16 SPI_FLASH_SendHalfWord_$rnd_varname_pre$(u16 HalfWord); void SPI_FLASH_WriteEnable_$rnd_varname_pre$(void); void SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(void); unsigned char SPIx_ReadWriteByte_$rnd_varname_pre$( unsigned char Byte ) { return TT_send_a_spi_p([($_xgm$spi_sel),type=num],Byte); } /* Private typedef -----------------------------------------------------------*/ //#define SPI_FLASH_PageSize 4096 #define SPI_FLASH_PageSize 256 //一页是256个字节从00h到FFh,到100h就是下一个页,一直到FFFh此扇区完成,(16个是一个扇区sector),再到1000h是下一个扇区,2000h是第二个扇区。一直到FFFFh,在到下一个10000h是下一个块(block) ,25Q64是128个块,25Q32是64块 #define SPI_FLASH_PerWritePageSize 256 /* Private define ------------------------------------------------------------*/ #define W25X_WriteEnable 0x06 #define W25X_WriteDisable 0x04 #define W25X_ReadStatusReg 0x05 #define W25X_WriteStatusReg 0x01 #define W25X_ReadData 0x03 #define W25X_FastReadData 0x0B #define W25X_FastReadDual 0x3B #define W25X_PageProgram 0x02 #define W25X_BlockErase 0xD8 #define W25X_SectorErase 0x20 #define W25X_ChipErase 0xC7 #define W25X_PowerDown 0xB9 #define W25X_ReleasePowerDown 0xAB #define W25X_DeviceID 0xAB #define W25X_ManufactDeviceID 0x90 #define W25X_JedecDeviceID 0x9F #define WIP_Flag 0x01 /* Write In Progress (WIP) flag */ #define Dummy_Byte 0xFF void SPI_FLASH_Write_Protect_ENABLE_$rnd_varname_pre$(void)//flash 打开写保护 { SPI_FLASH_Write_Protect_Assert_$rnd_varname_pre$(); } void SPI_FLASH_Write_Protect_DISABLE_$rnd_varname_pre$(void)//flash 关闭写保护 { SPI_FLASH_Write_Protect_Deassert_$rnd_varname_pre$(); } void SPI_FLASH_Hold_ENABLE_$rnd_varname_pre$(void)//flash HOLD ENABLE { SPI_FLASH_Hold_Assert_$rnd_varname_pre$(); } void SPI_FLASH_Hold_DISABLE_$rnd_varname_pre$(void)//flash HOLD DISABLE { SPI_FLASH_Hold_Deassert_$rnd_varname_pre$(); } /******************************************************************************* * Function Name : SPI_FLASH_Init * Description : Initializes the peripherals used by the SPI FLASH driver. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_Init_$rnd_varname_pre$(void) { } /******************************************************************************* * Function Name : SPI_FLASH_SectorErase * Description : Erases the specified FLASH sector. * Input : SectorAddr: address of the sector to erase. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_SectorErase_$rnd_varname_pre$(u32 SectorAddr) { /* Send write enable instruction */ SPI_FLASH_WriteEnable_$rnd_varname_pre$(); SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); /* Sector Erase */ /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send Sector Erase instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_SectorErase); /* Send SectorAddr high nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$((SectorAddr & 0xFF0000) >> 16); /* Send SectorAddr medium nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$((SectorAddr & 0xFF00) >> 8); /* Send SectorAddr low nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$(SectorAddr & 0xFF); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); } void SPI_Flash_Erase_SectorOK_$rnd_varname_pre$(u32 Dst_Addr) { Dst_Addr*=4096; SPI_FLASH_WriteEnable_$rnd_varname_pre$(); //SET WEL SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); SPI_FLASH_CS_LOW_$rnd_varname_pre$(); //使能器件 SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_SectorErase); //发送扇区擦除指令 SPI_FLASH_SendByte_$rnd_varname_pre$((u8)((Dst_Addr)>>16)); //发送24bit地址 SPI_FLASH_SendByte_$rnd_varname_pre$((u8)((Dst_Addr)>>8)); SPI_FLASH_SendByte_$rnd_varname_pre$((u8)Dst_Addr); SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); //取消片选 SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); //等待擦除完成 } /******************************************************************************* * Function Name : SPI_FLASH_BulkErase * Description : Erases the entire FLASH. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_BulkErase_$rnd_varname_pre$(void) { /* Send write enable instruction */ SPI_FLASH_WriteEnable_$rnd_varname_pre$(); /* Bulk Erase */ /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send Bulk Erase instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_ChipErase); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); } /******************************************************************************* * Function Name : SPI_FLASH_PageWrite * Description : Writes more than one byte to the FLASH with a single WRITE * cycle(Page WRITE sequence). The number of byte can't exceed * the FLASH page size. * Input : - pBuffer : pointer to the buffer containing the data to be * written to the FLASH. * - WriteAddr : FLASH's internal address to write to. * - NumByteToWrite : number of bytes to write to the FLASH, * must be equal or less than "SPI_FLASH_PageSize" value. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_PageWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { /* Enable the write access to the FLASH */ SPI_FLASH_WriteEnable_$rnd_varname_pre$(); /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Write to Memory " instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_PageProgram); /* Send WriteAddr high nibble address byte to write to */ SPI_FLASH_SendByte_$rnd_varname_pre$((WriteAddr & 0xFF0000) >> 16); /* Send WriteAddr medium nibble address byte to write to */ SPI_FLASH_SendByte_$rnd_varname_pre$((WriteAddr & 0xFF00) >> 8); /* Send WriteAddr low nibble address byte to write to */ SPI_FLASH_SendByte_$rnd_varname_pre$(WriteAddr & 0xFF); if(NumByteToWrite > SPI_FLASH_PerWritePageSize) { NumByteToWrite = SPI_FLASH_PerWritePageSize; //printf("\n\r Err: SPI_FLASH_PageWrite too large!"); } /* while there is data to be written on the FLASH */ while (NumByteToWrite--) { /* Send the current byte */ SPI_FLASH_SendByte_$rnd_varname_pre$(*pBuffer); /* Point on the next byte to be written */ pBuffer++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); /* Wait the end of Flash writing */ SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(); } /******************************************************************************* * Function Name : SPI_FLASH_BufferWrite * Description : Writes block of data to the FLASH. In this function, the * number of WRITE cycles are reduced, using Page WRITE sequence. * Input : - pBuffer : pointer to the buffer containing the data to be * written to the FLASH. * - WriteAddr : FLASH's internal address to write to. * - NumByteToWrite : number of bytes to write to the FLASH. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_BufferWrite_$rnd_varname_pre$(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite) { u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; Addr = WriteAddr % SPI_FLASH_PageSize; count = SPI_FLASH_PageSize - Addr; NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned */ { if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ { SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, NumByteToWrite); } else /* NumByteToWrite > SPI_FLASH_PageSize */ { while (NumOfPage--) { SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, SPI_FLASH_PageSize); WriteAddr += SPI_FLASH_PageSize; pBuffer += SPI_FLASH_PageSize; } SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, NumOfSingle); } } else /* WriteAddr is not SPI_FLASH_PageSize aligned */ { if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */ { if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */ { temp = NumOfSingle - count; SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, count); WriteAddr += count; pBuffer += count; SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, temp); } else { SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, NumByteToWrite); } } else /* NumByteToWrite > SPI_FLASH_PageSize */ { NumByteToWrite -= count; NumOfPage = NumByteToWrite / SPI_FLASH_PageSize; NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize; SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, count); WriteAddr += count; pBuffer += count; while (NumOfPage--) { SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, SPI_FLASH_PageSize); WriteAddr += SPI_FLASH_PageSize; pBuffer += SPI_FLASH_PageSize; } if (NumOfSingle != 0) { SPI_FLASH_PageWrite_$rnd_varname_pre$(pBuffer, WriteAddr, NumOfSingle); } } } } void SPI_Flash_Write_Page_$rnd_varname_pre$(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u16 i; SPI_FLASH_WriteEnable_$rnd_varname_pre$(); //SET WEL SPI_FLASH_CS_LOW_$rnd_varname_pre$(); //使能器件 SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_PageProgram); //发送写页命令 SPI_FLASH_SendByte_$rnd_varname_pre$((u8)((WriteAddr)>>16)); //发送24bit地址 SPI_FLASH_SendByte_$rnd_varname_pre$((u8)((WriteAddr)>>8)); SPI_FLASH_SendByte_$rnd_varname_pre$((u8)WriteAddr); for(i=0;ipageremain { pBuffer+=pageremain; WriteAddr+=pageremain; NumByteToWrite-=pageremain; //减去已经写入了的字节数 if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节 else pageremain=NumByteToWrite; //不够256个字节了 } }; } //写SPI FLASH //在指定地址开始写入指定长度的数据 //该函数带擦除操作! //pBuffer:数据存储区 //WriteAddr:开始写入的地址(24bit) //NumByteToWrite:要写入的字节数(最大65535) void SPI_Flash_Write_by_earse_ok_$rnd_varname_pre$(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u32 secpos; u16 secoff; u16 secremain; u16 i; secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16 secoff=WriteAddr%4096;//在扇区内的偏移 secremain=4096-secoff;//扇区剩余空间大小 if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节 while(1) { SPI_FLASH_BufferRead_$rnd_varname_pre$(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容 for(i=0;i4096)secremain=4096; //下一个扇区还是写不完 else secremain=NumByteToWrite; //下一个扇区可以写完了 } }; } u8 read_w25q64_byte_$rnd_varname_pre$(u32 ReadAddr1){ u8 setaas1[2]; SPI_FLASH_BufferRead_$rnd_varname_pre$(setaas1, ReadAddr1, 1); return setaas1[0]; } #define W25X_ReadData 0x03 #define W25X_PageProgram 0x02 #define FLASH_PAGE_SIZE 256 #define FLASH_SECTOR_SIZE 4096 #define FLASH_SECTOR_COUNT 512 #define FLASH_BLOCK_SIZE 65536 #define FLASH_PAGES_PER_SECTOR FLASH_SECTOR_SIZE/FLASH_PAGE_SIZE //Sector Read void W25X_Read_Sector_$rnd_varname_pre$(uint32_t nSector, u8* pBuffer) { uint16_t i; //扇区号转为地址 nSector *= FLASH_SECTOR_SIZE; SPI_FLASH_CS_LOW_$rnd_varname_pre$(); SPI1_ExchangeByte_$rnd_varname_pre$(W25X_ReadData); SPI1_ExchangeByte_$rnd_varname_pre$(((nSector & 0xFFFFFF) >> 16)); SPI1_ExchangeByte_$rnd_varname_pre$(((nSector & 0xFFFF) >> 8)); SPI1_ExchangeByte_$rnd_varname_pre$(nSector & 0xFF); for(i=0;i> 16)); SPI1_ExchangeByte_$rnd_varname_pre$(((nSector & 0xFFFF) >> 8)); SPI1_ExchangeByte_$rnd_varname_pre$(nSector & 0xFF); for(i=0;i> 16); /* Send ReadAddr medium nibble address byte to read from */ SPI_FLASH_SendByte_$rnd_varname_pre$((ReadAddr& 0xFF00) >> 8); /* Send ReadAddr low nibble address byte to read from */ SPI_FLASH_SendByte_$rnd_varname_pre$(ReadAddr & 0xFF); while (NumByteToRead--) /* while there is data to be read */ { /* Read a byte from the FLASH */ *pBuffer = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Point to the next location where the byte read will be saved */ pBuffer++; } /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); } /******************************************************************************* * Function Name : SPI_FLASH_ReadID * Description : Reads FLASH identification. * Input : None * Output : None * Return : FLASH identification *******************************************************************************/ u32 SPI_FLASH_ReadID(void) { u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "RDID " instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_JedecDeviceID); /* Read a byte from the FLASH */ Temp0 = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Read a byte from the FLASH */ Temp1 = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Read a byte from the FLASH */ Temp2 = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2; return Temp; } /******************************************************************************* * Function Name : SPI_FLASH_ReadID * Description : Reads FLASH identification. * Input : None * Output : None * Return : FLASH identification *******************************************************************************/ u32 SPI_FLASH_ReadDeviceID_$rnd_varname_pre$(void) { u32 Temp = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "RDID " instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_DeviceID); SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Read a byte from the FLASH */ Temp = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); return Temp; } /******************************************************************************* * Function Name : SPI_FLASH_StartReadSequence * Description : Initiates a read data byte (READ) sequence from the Flash. * This is done by driving the /CS line low to select the device, * then the READ instruction is transmitted followed by 3 bytes * address. This function exit and keep the /CS line low, so the * Flash still being selected. With this technique the whole * content of the Flash is read with a single READ instruction. * Input : - ReadAddr : FLASH's internal address to read from. * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_StartReadSequence_$rnd_varname_pre$(u32 ReadAddr) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Read from Memory " instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_ReadData); /* Send the 24-bit address of the address to read from -----------------------*/ /* Send ReadAddr high nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$((ReadAddr & 0xFF0000) >> 16); /* Send ReadAddr medium nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$((ReadAddr& 0xFF00) >> 8); /* Send ReadAddr low nibble address byte */ SPI_FLASH_SendByte_$rnd_varname_pre$(ReadAddr & 0xFF); } u8 SPI_FLASH_ReadByte_$rnd_varname_pre$(void) { return (SPIx_ReadWriteByte_$rnd_varname_pre$(Dummy_Byte)); } /******************************************************************************* * Function Name : SPI_FLASH_SendByte * Description : Sends a byte through the SPI interface and return the byte * received from the SPI bus. * Input : byte : byte to send. * Output : None * Return : The value of the received byte. *******************************************************************************/ u8 SPI_FLASH_SendByte_$rnd_varname_pre$(u8 byte1) { return SPIx_ReadWriteByte_$rnd_varname_pre$(byte1); } /******************************************************************************* * Function Name : SPI_FLASH_WriteEnable * Description : Enables the write access to the FLASH. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_WriteEnable_$rnd_varname_pre$(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Write Enable" instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_WriteEnable); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); } /******************************************************************************* * Function Name : SPI_FLASH_WaitForWriteEnd * Description : Polls the status of the Write In Progress (WIP) flag in the * FLASH's status register and loop until write opertaion * has completed. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_FLASH_WaitForWriteEnd_$rnd_varname_pre$(void) { u8 FLASH_Status = 0; /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Read Status Register" instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_ReadStatusReg); /* Loop as long as the memory is busy with a write cycle */ do { /* Send a dummy byte to generate the clock needed by the FLASH and put the value of the status register in FLASH_Status variable */ FLASH_Status = SPI_FLASH_SendByte_$rnd_varname_pre$(Dummy_Byte); } while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */ /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); } //进入掉电模式 void SPI_Flash_PowerDown_$rnd_varname_pre$(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Power Down" instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_PowerDown); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); } //唤醒 void SPI_Flash_WAKEUP_$rnd_varname_pre$(void) { /* Select the FLASH: Chip Select low */ SPI_FLASH_CS_LOW_$rnd_varname_pre$(); /* Send "Power Down" instruction */ SPI_FLASH_SendByte_$rnd_varname_pre$(W25X_ReleasePowerDown); /* Deselect the FLASH: Chip Select high */ SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); //等待TRES1 } [$init_code_for_init_val] TT_init_spi([($_xgm$spi_sel),type=num],[($_xgm$Cs_pin1),type=pin],SPI_BaudRatePrescaler_32,SPI_FirstBit_MSB,SPI_CPOL_High, SPI_CPHA_2Edge,7);//32分频以上,不然死机! SPI_FLASH_CS_HIGH_$rnd_varname_pre$(); SPI_Flash_WAKEUP_$rnd_varname_pre$(); /* 读取芯片ID 返回值如下: //0XEF13,表示芯片型号为W25Q80 //0XEF14,表示芯片型号为W25Q16 //0XEF15,表示芯片型号为W25Q32 //0XEF16,表示芯片型号为W25Q64 //0XEF17,表示芯片型号为W25Q128 //0XEF18,表示芯片型号为W25Q256 */ [$timer0_1ms_code] [$toolbox_block_code] SPI1引脚: clk=PA5,miso=PA6,mosi=PA7 SPI2引脚: clk=PB13,miso=PB14,mosi=PB15 SPI3引脚: clk=PB3,miso=PB4,mosi=PB5 [$replace_map] $_xgm$dev_no = $field$dev_no,mytype|num, ptype|TIMES $_xgm$Cs_pin1 = $field$Cs_pin1,mytype|pin, ptype|TIMES $_xgm$spi_sel = $field$spi_sel,mytype|num, ptype|TIMES $_xgm$w25qxxx_type = $field$w25qxxx_type,mytype|num, ptype|TIMES $_xgm$value11 =$dev_no_for_complie_include_code$$field$spi_sel