void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u32 secpos; u16 secoff; u16 secremain; u16 i; u8 * SPI_FLASH_BUF; #ifdef MEM_ALLOC_TABLE_SIZE SPI_FLASH_BUF=mymalloc(4096); //使用内存管理 if(SPI_FLASH_BUF==NULL)return; //申请失败 #else SPI_FLASH_BUF=SPI_FLASH_BUFFER; //不使用内存管理 #endif secpos=WriteAddr/4096;//扇区地址 0~511 for w25x16 secoff=WriteAddr%4096;//在扇区内的偏移 secremain=4096-secoff;//扇区剩余空间大小 if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节 while(1) { SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容 SPI_USART_IO_SET(0);//SPI 工作 for(i=0;i<secremain;i++)//校验数据 { if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除 } if(i<secremain)//需要擦除 { SPI_Flash_Erase_Sector(secpos);//擦除这个扇区 for(i=0;i<secremain;i++) //复制 { SPI_FLASH_BUF[i+secoff]=pBuffer[i]; } SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区 }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间. if(NumByteToWrite==secremain)break;//写入结束了 else//写入未结束 { secpos++;//扇区地址增1 secoff=0;//偏移位置为0 pBuffer+=secremain; //指针偏移 WriteAddr+=secremain;//写地址偏移 NumByteToWrite-=secremain; //字节数递减 if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完 else secremain=NumByteToWrite; //下一个扇区可以写完了 } }; SPI_USART_IO_SET(1);//USART2 工作 #ifdef MEM_ALLOC_TABLE_SIZE myfree(SPI_FLASH_BUF); //释放内存 #endif }
void p_dr_SPIFlashWrite(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u32 secpos; u16 secoff; u16 secremain; u16 i; secpos = WriteAddr/W25X_FLASH_SECTOR_SIZE; secoff = WriteAddr%W25X_FLASH_SECTOR_SIZE; secremain = W25X_FLASH_SECTOR_SIZE - secoff; if(NumByteToWrite <= secremain) secremain = NumByteToWrite; while(1) { p_dr_SPIFlashRead(G_u8_SPIFlashBuf, secpos*4W25X_FLASH_SECTOR_SIZE, W25X_FLASH_SECTOR_SIZE); for(i=0; i<secremain; i++) { if(G_u8_SPIFlashBuf[secoff + i] != 0XFF) break; } if(i<secremain) { p_dr_SPIFlashEraseSector(secpos); for(i=0; i<secremain; i++) { G_u8_SPIFlashBuf[i+secoff] = pBuffer[i]; } SPI_Flash_Write_NoCheck(G_u8_SPIFlashBuf, secpos*4W25X_FLASH_SECTOR_SIZE, 4W25X_FLASH_SECTOR_SIZE); } else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain); if(NumByteToWrite == secremain) break; else { secpos++; secoff = 0; pBuffer += secremain; WriteAddr += secremain; NumByteToWrite -= secremain; if(NumByteToWrite > 4W25X_FLASH_SECTOR_SIZE) secremain = 4W25X_FLASH_SECTOR_SIZE; else secremain = NumByteToWrite; } }; }
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite) { u32 secpos; u16 secoff; u16 secremain; u16 i; u8 * SPI_FLASH_BUF; SPI_FLASH_BUF=SPI_FLASH_BUFFER; secpos=WriteAddr/4096;//扇区地址 secoff=WriteAddr%4096;//在扇区内的偏移 secremain=4096-secoff;//扇区剩余空间大小 //printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//测试用 if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节 while(1) { SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);//读出整个扇区的内容 for(i=0;i<secremain;i++)//校验数据 { if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除 } if(i<secremain)//需要擦除 { SPI_Flash_Erase_Sector(secpos);//擦除这个扇区 for(i=0;i<secremain;i++) //复制 { SPI_FLASH_BUF[i+secoff]=pBuffer[i]; } SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);//写入整个扇区 }else SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间. if(NumByteToWrite==secremain)break;//写入结束了 else//写入未结束 { secpos++;//扇区地址增1 secoff=0;//偏移位置为0 pBuffer+=secremain; //指针偏移 WriteAddr+=secremain;//写地址偏移 NumByteToWrite-=secremain; //字节数递减 if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完 else secremain=NumByteToWrite; //下一个扇区可以写完了 } }; }