1、说明
基于SDK3.x(非3.4)移植FATFS文件系统,泰凌微提供的U盘demo工程
2、操作
A.修改drivers/8258/spi.c和spi.h
其中在spi.c中添加以下代码(SPI驱动相关函数定义)
//MG add
void MG_spi_earse(unsigned int addr,GPIO_PinTypeDef CSPin)
{
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = 0x20;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>16)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>8)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_Write_Enable(GPIO_PinTypeDef CSPin)
{
unsigned char cmd = 0x06;
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = cmd;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_Standly(GPIO_PinTypeDef CSPin)
{
unsigned char cmd = 0xAB;
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = cmd;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_write(unsigned int addr, unsigned char*buf, unsigned char len,GPIO_PinTypeDef CSPin)
{
unsigned char cmd = 0x02;
unsigned char i=0;
//MG_spi_Write_Enable(GPIO_PD6);
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = cmd;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>16)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>8)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
for(i=0; i<len ;i++)
{
reg_spi_data = buf[i];
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
}
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_read(unsigned int addr, unsigned char*buf, unsigned char len,GPIO_PinTypeDef CSPin)
{
unsigned char cmd = 0x03;
unsigned char i=0;
unsigned char temp;
//MG_spi_Write_Enable(GPIO_PD6);
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = cmd;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>16)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr>>8)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_data = (addr)&0xFF;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
reg_spi_ctrl |=FLD_SPI_DATA_OUT_DIS;
// /***when the read_bit was set 1,you can read 0x800008 to take eight clock cycle***/
reg_spi_ctrl |= FLD_SPI_RD; //enable read,0x09-bit3 : 0 for read ,1 for write
temp = reg_spi_data; //first byte isn't useful data,only take 8 clock cycle
while(reg_spi_ctrl &FLD_SPI_BUSY ); //wait reading finished
for(i=0; i<len ;i++)
{
buf[i] = reg_spi_data;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
}
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_readID(unsigned char *buf,GPIO_PinTypeDef CSPin)
{
unsigned char cmd[4] = {0x90,0x00,0x00,0x00};
unsigned char i = 0;
unsigned char temp;
gpio_write(CSPin,0);//CS level is low
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
for(i=0; i<4; i++)
{
reg_spi_data = cmd[i];
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
}
reg_spi_ctrl |=FLD_SPI_DATA_OUT_DIS;
/***when the read_bit was set 1,you can read 0x800008 to take eight clock cycle***/
reg_spi_ctrl |= FLD_SPI_RD; //enable read,0x09-bit3 : 0 for read ,1 for write
temp = reg_spi_data; //first byte isn't useful data,only take 8 clock cycle
while(reg_spi_ctrl &FLD_SPI_BUSY ); //wait reading finished
for(i=0; i<2 ;i++)
{
buf[i] = reg_spi_data;
while(reg_spi_ctrl &FLD_SPI_BUSY ); //wait reading finished
}
gpio_write(CSPin,1);//CS level is high
}
void MG_spi_write_byte(unsigned char byte)
{
reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; //0x09- bit2 enables spi data output
reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write
reg_spi_data = byte;
while(reg_spi_ctrl& FLD_SPI_BUSY); //wait writing finished
}
void MG_spi_write_nbyte(unsigned char *buf, unsigned short int len)
{
unsigned short int i = 0 ;
for(i=0; i<len; i++)
{
MG_spi_write_byte(*buf++);
}
}
unsigned char MG_spi_read_byte()
{
unsigned char dat = 0;
reg_spi_ctrl |=FLD_SPI_DATA_OUT_DIS;
reg_spi_ctrl |= FLD_SPI_RD;
dat = reg_spi_data; //take 8 clock cycles
while(reg_spi_ctrl & FLD_SPI_BUSY ); //wait reading finished
return dat;
}
void MG_spi_read_nbyte(unsigned char *buf, unsigned int len)
{
unsigned int i = 0;
unsigned char temp;
temp = MG_spi_read_byte();
for(i=0; i<len; i++)
{
*buf++ = MG_spi_read_byte();
}
}
在spi.h中添加以下代码(SPI驱动相关函数声明)
//MG add
extern void MG_spi_earse(unsigned int addr,GPIO_PinTypeDef CSPin);
extern void MG_spi_Write_Enable(GPIO_PinTypeDef CSPin);
extern void MG_spi_Standly(GPIO_PinTypeDef CSPin);
extern void MG_spi_write(unsigned int addr, unsigned char*buf, unsigned char len,GPIO_PinTypeDef CSPin);
extern void MG_spi_read(unsigned int addr, unsigned char*buf, unsigned char len,GPIO_PinTypeDef CSPin);
extern void MG_spi_readID(unsigned char *buf,GPIO_PinTypeDef CSPin);
void MG_spi_write_nbyte(unsigned char *buf, unsigned short int len);
extern void MG_spi_read_nbyte(unsigned char *buf, unsigned int len);
#define MG_SPI_CS_LOW(CSPin) gpio_write(CSPin,0)
#define MG_SPI_CS_HIGH(CSPin) gpio_write(CSPin,1)
B.在8258_USB_Disk_Demo中新建MG_SPI_Flash.c和MG_SPI_Flash.h
其中在MG_SPI_Flash.c中添加以下代码(W25Q16U驱动相关函数定义)
#include "MG_SPI_Flash.h"
/*************************
Flash parameter define
*************************/
//Device id
#define W25Q16_MAN_ID 0x85
#define W25Q16_DEV_ID 0x14
/* Flash instruction list define */
#define W25Q16_WRTIEENABLE 0x06
#define W25Q16_WRTIEDISENABLE 0x04
#define W25Q16_READSTATUSREG 0x05
#define W25Q16_WRITESTATUSREG 0x01
#define W25Q16_READDATA 0x03
#define W25Q16_FASTREADDATA 0x0B
#define W25Q16_FASTREADDUAL 0x3B
#define W25Q16_PAGEPROGRAM 0x02
#define W25Q16_BLOCKERASE 0xD8
#define W25Q16_SECTORERASE 0x20
#define W25Q16_CHIPERASE 0xC7
#define W25Q16_POWERDOWN 0xB9
#define W25Q16_RELEASEPOWERDOWN 0xAB
#define W25Q16_DEVICEID 0xAB
#define W25Q16_MANUFACTDEVICEID 0x90
#define W25Q16_JEDECDEVICEID 0x9F
#define W25Q16_BUSY_BIT 0x01//确认Flash是否处于忙状态Bit位
#define W25Q16_SECTORSIZE 4096
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_ReadID()
*【输入参数】: 无
*【输出参数】: false:ID验证失败
true:ID验证成功
*【功 能】: 验证W25Q16 device ID
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
bool Megain_SPIFlash_ReadID()
{
unsigned char ReadIdCmd[4] = {0x90,0x00,0x00,0x00};
unsigned char rxbuf[2];
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(ReadIdCmd,4);
MG_spi_read_nbyte(rxbuf,2);
MG_SPI_CS_HIGH(MG_CS_PIN);
if(rxbuf[0] == W25Q16_MAN_ID ||
rxbuf[1] == W25Q16_DEV_ID )
{
//printf("data is : %d %d\r\n",rxbuf[0],rxbuf[1]);
return true;
}
return false;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_ReadSR()
*【输入参数】: 无
*【输出参数】: status:W25Q16当前状态寄存器的值
*【功 能】: 读取W25Q16状态寄存器
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
static unsigned char Megain_SPIFlash_ReadSR()
{
unsigned char status[1] = {0};
unsigned char ReadSR_Cmd[1] = {W25Q16_READSTATUSREG};
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(ReadSR_Cmd,1);
MG_spi_read_nbyte(status,1);
MG_SPI_CS_HIGH(MG_CS_PIN);
return status[0];
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_WaitBusy()
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: 等待W25Q16忙
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
static void Megain_SPIFlash_WaitBusy()
{
while((Megain_SPIFlash_ReadSR()&0x01));
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_WaitReady()
*【输入参数】: 无
*【输出参数】: 0:Flash芯片已经Ready
*【功 能】: 等待W25Q16空闲
*【作 者】: 黄金旭
*【修改时间】:2018.12.08
*******************************************************************************/
static int Megain_SPIFlash_WaitReady()
{
unsigned char status;
while(1)
{
status = Megain_SPIFlash_ReadSR();
if(!(status & W25Q16_BUSY_BIT)) //Ready
{
break;
}
}
return 0;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_WriteEnable()
*【输入参数】: 无
*【输出参数】: true:已经开启写使能
false:未成功开启写使能
*【功 能】: W25Q16写使能
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
static bool Megain_SPIFlash_WriteEnable()
{
unsigned char WtiteEnable_Cmd = W25Q16_WRTIEENABLE;
unsigned char status = 0;
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(&WtiteEnable_Cmd,1);
MG_SPI_CS_HIGH(MG_CS_PIN);
status = Megain_SPIFlash_ReadSR();
if(status&0x02)
{
return true;
}
return false;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_Write(uint32_t address, uint8_t len, uint8_t *buf)
*【输入参数】: 无
*【输出参数】: true:开启写使能,且SR寄存器不为忙
false:未成功开启写使能
*【功 能】: W25Q16写操作
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
bool Megain_SPIFlash_Write(unsigned int address, unsigned char len, unsigned char *buf)
{
unsigned char wbuf[4];
bool status = false;
//Megain_SPIFlash_ReleasePowerDown();
delay_us(100);
while(len>0)
{
Megain_SPIFlash_WaitReady();
status = Megain_SPIFlash_WriteEnable();
if(status == false)
{
return false;
}
unsigned int ilen;
ilen = 256 - (address % 256);
if (len < ilen)
{
ilen = len;
}
wbuf[0] = W25Q16_PAGEPROGRAM;
wbuf[1] = (address >> 16);
wbuf[2] = (address >> 8);
wbuf[3] = (address)&0xff;
address += ilen;
len -= ilen;
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_spi_write_nbyte(buf,ilen);
MG_SPI_CS_HIGH(MG_CS_PIN);
Megain_SPIFlash_WaitBusy();
buf += ilen;
}
//Megain_SPIFlash_PowerDown();
return true;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_Read(uint32_t address, uint8_t len, uint8_t *buf)
*【输入参数】: 无
*【输出参数】: true:开启写使能,且SR寄存器不为忙
false:未成功开启写使能
*【功 能】: W25Q16页编程
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
bool Megain_SPIFlash_Read(unsigned int address, unsigned int len, unsigned char *buf)
{
unsigned char wbuf[4];
wbuf[0] = W25Q16_READDATA;
wbuf[1] = (address>>16);
wbuf[2] = (address>>8);
wbuf[3] = (address)&0xFF;
//Megain_SPIFlash_ReleasePowerDown();
//Megain_SPIFlash_WaitReady();
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_spi_read_nbyte(buf,len);
MG_SPI_CS_HIGH(MG_CS_PIN);
// if(!Megain_SPIFlash_WaitReady())
// {
// return true;
// }
//Megain_SPIFlash_PowerDown();
// return false;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_EraseChip()
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: W25Q16片擦
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
void Megain_SPIFlash_EraseChip()
{
unsigned char wbuf[1];
wbuf[0] = W25Q16_CHIPERASE;
Megain_SPIFlash_WriteEnable();
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_SPI_CS_HIGH(MG_CS_PIN);
Megain_SPIFlash_WaitBusy();
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_EraseSector(uint32_t address)
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: W25Q16扇区擦(4K)
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
bool Megain_SPIFlash_EraseSector(unsigned int address, unsigned int len)
{
unsigned char wbuf[4];
bool status = false;
wbuf[0] = W25Q16_SECTORERASE;
wbuf[1] = (address>>16);
wbuf[2] = (address>>8);
wbuf[3] = (address)&0xFF;
status = Megain_SPIFlash_WriteEnable();
if(status == false)
{
return false;
}
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_SPI_CS_HIGH(MG_CS_PIN);
Megain_SPIFlash_WaitBusy();
return true;
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_PowerDown()
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: W25Q16 Power down模式
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
void Megain_SPIFlash_PowerDown()
{
unsigned char wbuf[1];
wbuf[0] = W25Q16_POWERDOWN;
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_SPI_CS_HIGH(MG_CS_PIN);
delay_us(10);
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_ReleasePowerDown()
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: W25Q16 解除Power down模式
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
void Megain_SPIFlash_ReleasePowerDown()
{
unsigned char wbuf[1];
wbuf[0] = W25Q16_RELEASEPOWERDOWN;
MG_SPI_CS_LOW(MG_CS_PIN);
MG_spi_write_nbyte(wbuf,sizeof(wbuf));
MG_SPI_CS_HIGH(MG_CS_PIN);
delay_us(10);
}
/*******************************************************************************
*【函数名称】: Megain_SPIFlash_Init()
*【输入参数】: 无
*【输出参数】: 无
*【功 能】: SPI 初始化
*【作 者】: 黄金旭
*【修改时间】:2018.12.03
*******************************************************************************/
unsigned char Megain_SPIFlash_Init()
{
unsigned char rx_data[2] = {0,0};
unsigned char tx_data[2] = {0x02,0x06};
/*
* SDO SDI SCK CN
* A2 A3 A4 D6
* B7 B6 D7 D2
*/
spi_master_set_pin(0);//
spi_master_set_cs_pin(GPIO_PD6);
spi_master_init(3,0);//4M、mode 0
//Megain_SPIFlash_EraseChip();
//Megain_SPIFlash_ReadID();
//Megain_SPIFlash_EraseSector(0x00002000,4096);
//Megain_SPIFlash_Read(0x00002000,2,rx_data);
//printf("data is : %d %d\r\n",rx_data[0],rx_data[1]);
//Megain_SPI_Flash_Write_NoCheck(0x00002000,2,tx_data);
//Megain_SPIFlash_Write(0x00002000,2,tx_data);
//Megain_SPIFlash_Read(0x00002000,2,rx_data);
//Megain_SPIFlash_EraseSector(0x00002000,4096);
//printf("data is : %d %d\r\n",rx_data[0],rx_data[1]);
//Megain_SPIFlash_Read(0x00002000,2,rx_data);
//printf("data is : %d %d\r\n",rx_data[0],rx_data[1]);
//if(rx_data[0] == tx_data[0] && rx_data[1] == tx_data[1])
//{
return 0;
//}
//else
//{
// return 1;
//}
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
void Megain_SPI_Flash_Write_Page(unsigned int address ,unsigned short int len, unsigned char *buf)
{
unsigned char wbuf[4];
//Megain_SPIFlash_ReleasePowerDown();
Megain_SPIFlash_WriteEnable();
MG_SPI_CS_LOW(MG_CS_PIN);
wbuf[0] = W25Q16_PAGEPROGRAM;
wbuf[1] = (address >> 16);
wbuf[2] = (address >> 8);
wbuf[3] = (address)&0xff;
MG_spi_write_nbyte(wbuf,4);
MG_spi_write_nbyte(buf,len);
MG_SPI_CS_HIGH(MG_CS_PIN);
Megain_SPIFlash_WaitBusy();
}
//无检验写SPI FLASH
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
//void Megain_SPI_Flash_Write_NoCheck(unsigned int address, unsigned short int len, unsigned char *buf)
//{
// unsigned short int pageremain;
// pageremain=256-address%256; //单页剩余的字节数
// if(len<=pageremain)
// {
// pageremain=len;//不大于256个字节
// }
// while(1)
// {
// Megain_SPI_Flash_Write_Page(address,pageremain,buf);
// if(len==pageremain)
// {
// buf=0;
// break;//写入结束了
// }
// else //NumByteToWrite>pageremain
// {
// buf = buf + pageremain;
// address = address + pageremain; //数据地址偏移
//
// len = len - pageremain; //减去已经写入了的字节数
// if(len>128)
// {
// pageremain=128; //一次可以写入256个字节
// }
// else
// {
// pageremain=len; //不够256个字节了
// }
// }
// }
//}
void Megain_SPI_Flash_Write_NoCheck(unsigned int address, unsigned short int len, unsigned char *buf)
{
unsigned short int pageremain;
pageremain=256-address%256; //单页剩余的字节数
if(len<=pageremain)
{
pageremain=len;//不大于256个字节
}
while(1)
{
Megain_SPI_Flash_Write_Page(address,pageremain,buf);
if(len==pageremain)
{
buf=0;
break;//写入结束了
}
else //NumByteToWrite>pageremain
{
buf = buf + pageremain;
address = address + pageremain; //数据地址偏移
len = len - pageremain; //减去已经写入了的字节数
if(len>128)
{
pageremain=128; //一次可以写入256个字节
}
else
{
pageremain=len; //不够256个字节了
}
}
}
}
//写SPI FLASH
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
unsigned char W25Q16_BUFFER[4096];
void W25Q16_Write(unsigned char *pBuffer,unsigned int WriteAddr,unsigned short int NumByteToWrite)
{
unsigned int secpos;
unsigned short int secoff;
unsigned short int secremain;
unsigned short int i;
unsigned char *W25Q16_BUF;
W25Q16_BUF=W25Q16_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)
{
Megain_SPIFlash_Read(secpos*4096,4096,W25Q16_BUF);
//W25QXX_Read(W25Q16_BUF,secpos*4096,4096);//读出整个扇区的内容
for(i=0;i<secremain;i++)//校验数据
{
if(W25Q16_BUF[secoff+i]!=0XFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
Megain_SPIFlash_EraseSector(secpos,4096);//擦除这个扇区
for(i=0;i<secremain;i++) //复制
{
W25Q16_BUF[i+secoff]=pBuffer[i];
}
//W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//写入整个扇区
Megain_SPI_Flash_Write_NoCheck(secpos*4096,4096,W25Q16_BUF);
}else Megain_SPI_Flash_Write_NoCheck(WriteAddr,secremain,pBuffer);//写已经擦除了的,直接写入扇区剩余区间.
if(NumByteToWrite==secremain)break;//写入结束了
else//写入未结束
{
secpos++;//扇区地址增1
secoff=0;//偏移位置为0
pBuffer+=secremain; //指针偏移
WriteAddr+=secremain;//写地址偏移
NumByteToWrite-=secremain; //字节数递减
if(NumByteToWrite>4096)secremain=4096; //下一个扇区还是写不完
else secremain=NumByteToWrite; //下一个扇区可以写完了
}
};
}
在MG_SPI_Flash.h中添加以下代码(W25Q16U驱动相关函数声明)
#ifndef _MG_SPI_FLASH_H
#define _MG_SPI_FLASH_H
#include "app_config.h"
//CS 引脚定义
#define MG_CS_PIN GPIO_PD6
extern bool Megain_SPIFlash_ReadID();
extern void Megain_SPIFlash_ReleasePowerDown();
extern void Megain_SPIFlash_PowerDown();
extern bool Megain_SPIFlash_EraseSector(unsigned int address, unsigned int len);
extern void Megain_SPIFlash_EraseChip();
extern bool Megain_SPIFlash_Read(unsigned int address, unsigned int len, unsigned char *buf);
extern bool Megain_SPIFlash_Write(unsigned int address, unsigned char len, unsigned char *buf);
extern unsigned char Megain_SPIFlash_Init();
extern void W25Q16_Write(unsigned char* pBuffer,unsigned int WriteAddr,unsigned short int NumByteToWrite);
extern void Megain_SPI_Flash_Write_NoCheck(unsigned int address, unsigned short int len, unsigned char *buf);
extern void Megain_SPI_Flash_Write_Page(unsigned int address ,unsigned short int len, unsigned char *buf);
#endif
C.在app.c中的user_init函数中添加以下代码(测试W25Q16U)
unsigned char work_buf[4096];
for(i = 0; i<4096 ;i++)
{
work_buf[i] = 0xA0;
}
for(i = 0; i<4096 ;i++)
{
printf("data[%d] is :%d\r\n",i,work_buf[i]);
}
Megain_SPIFlash_Init();
Megain_SPIFlash_EraseSector(0x00001000,4096);
W25Q16_Write(work_buf,0x00001000,4096);
for(i = 0; i<4096 ;i++)
{
work_buf[i] = 0;
}
Megain_SPIFlash_Read(0x00001000,4096,work_buf);
for(i = 0; i<4096 ;i++)
{
printf("data[%d] is :%d\r\n",i,work_buf[i]);
}
3、现象
烧录至板子后,串口成功打印出写入W25Q16U的数据