中级会员
 
- 积分
- 303
- 金钱
- 303
- 注册时间
- 2016-8-23
- 在线时间
- 49 小时
|

楼主 |
发表于 2016-8-25 08:57:21
|
显示全部楼层
多谢,我的就是根据你们的例程写的代码,可是不行。。。
//擦除一个扇区
//eraseAddr:扇区地址 根据实际容量设置
//擦除一个山区的最少时间
void MX25XX_Erase_Sector(u32 eraseAddr)
{
uint8_t cmd = 0;
cmd = sFLASH_MX_4kB_SECTOR_ERASE;
eraseAddr &= sFLASH_4kB_SECTOR_ALIGN;
SpiFlashWriteEn();
SpiFlashWaitReady();
sFLASH_CS_LOW();
SpiFlashSendByte(cmd);
SpiFlashSendByte((eraseAddr >> 24) & 0xFF);
SpiFlashSendByte((eraseAddr >> 16) & 0xFF);
SpiFlashSendByte((eraseAddr >> 8) & 0xFF);
SpiFlashSendByte(eraseAddr & 0xFF);
sFLASH_CS_HIGH();
SpiFlashWaitReady();
}
//读取SPI FLASH
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(32bit)
//NumByteToRead:要读取的字节数(最大65535)
void MX25XX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)
{
uint32_t i = 0;
sFLASH_CS_LOW();
SpiFlashSendByte((uint8_t)sFLASH_MX_READ_MEMORY_ARRAY);
SpiFlashSendByte((ReadAddr >> 24) & 0xFF);
SpiFlashSendByte((ReadAddr >> 16) & 0xFF);
SpiFlashSendByte((ReadAddr >> 8) & 0xFF);
SpiFlashSendByte(ReadAddr & 0xFF);
// 写数据
for (i = 0; i < NumByteToRead; i++)
{
while ((sFLASH_SPI->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
// 数据发送
sFLASH_SPI->DR = sFLASH_DUMMY_BYTE;
// 等待数据接收
while ((sFLASH_SPI->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
// 数据接收
pBuffer = sFLASH_SPI->DR;
}
sFLASH_CS_HIGH();
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
void MX25XX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u16 i;
SpiFlashWriteEn();
sFLASH_CS_LOW();
SpiFlashSendByte(sFLASH_MX_PAGE_PROGRAM);
SpiFlashSendByte((WriteAddr >> 24) & 0xFF);
SpiFlashSendByte((WriteAddr >> 16) & 0xFF);
SpiFlashSendByte((WriteAddr >> 8) & 0xFF);
SpiFlashSendByte(WriteAddr & 0xFF);
for (i = 0; i < NumByteToWrite; i++)
{
SpiFlashSendByte(pBuffer);
}
sFLASH_CS_HIGH();
SpiFlashWaitReady();
}
//无检验写SPI FLASH
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void MX25XX_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u16 pageremain;
pageremain = sFLASH_PAGE_SIZE - WriteAddr%sFLASH_PAGE_SIZE; //单页剩余的字节数
if(NumByteToWrite<=pageremain) pageremain = NumByteToWrite;//不大于256个字节
while(1)
{
MX25XX_Write_Page(pBuffer,WriteAddr,pageremain);
if(NumByteToWrite == pageremain) break;//写入结束了
else //NumByteToWrite>pageremain
{
pBuffer += pageremain;
WriteAddr += pageremain;
NumByteToWrite -= pageremain; //减去已经写入了的字节数
if(NumByteToWrite>256) pageremain = 256; //一次可以写入256个字节
else pageremain = NumByteToWrite; //不够256个字节了
}
};
}
//写SPI FLASH
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大65535)
u8 MX25XX_BUFFER[4096];
void MX25XX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
u8 * MX25XX_BUF;
MX25XX_BUF = MX25XX_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)
{
MX25XX_Read(MX25XX_BUF,secpos*4096,4096);//读出整个扇区的内容
for(i=0; i<secremain; i++) //校验数据
{
if(MX25XX_BUF[secoff+i] != 0XFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
MX25XX_Erase_Sector(secpos);//擦除这个扇区
for(i=0; i<secremain; i++) //复制
{
MX25XX_BUF[i+secoff] = pBuffer;
}
MX25XX_Write_NoCheck(MX25XX_BUF,secpos*4096,4096);//写入整个扇区
} else MX25XX_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; //下一个扇区可以写完了
}
};
}
#include "diskio.h"
#include "spi_flash.h"
#include "usbh_usr.h"
#include "malloc.h"
#define EX_FLASH 0 //外部flash,卷标为0
#define USB_DISK 1 //U盘,卷标为1
//对于MX25L25735F
//前28M字节给fatfs用,28M字节后,给客户自己用
#define FLASH_SECTOR_SIZE 512
u16 FLASH_SECTOR_COUNT = 2048*28; //MX25L25735F,前28M字节给FATFS占用
#define FLASH_BLOCK_SIZE 8 //每个BLOCK有8个扇区
//获得磁盘状态
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
//初始化磁盘
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
u8 res=0;
switch(pdrv)
{
case EX_FLASH: //外部flash
SpiFlashInit(); //MX25XX初始化
break;
case USB_DISK: //U盘
res=!USBH_UDISK_Status();//U盘连接成功,则返回1.否则返回0
break;
default:
res=1;
}
if(res)return STA_NOINIT;
else return 0; //初始化成功
}
//读扇区
//pdrv:磁盘编号0~9
//*buff:数据接收缓冲首地址
//sector:扇区地址
//count:需要读取的扇区数
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case EX_FLASH: //外部flash
for(; count>0; count--)
{
MX25XX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res = 0;
break;
case USB_DISK: //U盘
res = USBH_UDISK_Read(buff,sector,count);
break;
default:
res = 1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res==0x00)return RES_OK;
else return RES_ERROR;
}
//写扇区
//pdrv:磁盘编号0~9
//*buff:发送数据首地址
//sector:扇区地址
//count:需要写入的扇区数
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case EX_FLASH: //外部flash
for(; count>0; count--)
{
MX25XX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff+=FLASH_SECTOR_SIZE;
}
res=0;
break;
case USB_DISK: //U盘
res=USBH_UDISK_Write((u8*)buff,sector,count);
break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
//其他表参数的获得
//pdrv:磁盘编号0~9
//ctrl:控制代码
//*buff:发送/接收缓冲区指针
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv==EX_FLASH) //外部FLASH
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
} else if(pdrv==USB_DISK) //U盘
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff=512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff=512;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff=USBH_MSC_Param.MSCapacity;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
} else res=RES_ERROR;//其他的不支持
return res;
}
//获得时间
//User defined function to give a current time to fatfs module */
//31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */
//15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
DWORD get_fattime (void)
{
return 0;
}
//动态分配内存
void *ff_memalloc (UINT size)
{
return (void*)mymalloc(size);
}
//释放内存
void ff_memfree (void* mf)
{
myfree(mf);
}
|
|