SPI分主设备和从设备,对于主设备是有自己的时钟的,但是对于从设备,自身是没有时钟的,它的时钟必须由主设备提供,所以在用SPI对FLASH进行操作时,一般分为这样几个过程,首先是发送命令(比如0x90是读设备ID;0x03是读命令;0x06是写命令;0x02是对FLASH芯片进行编程的命令),发完命令之后就是发地址,最后才是读数据或者写数据。
下面是读ID的函数,其中有几点做一下简单的说明
unsigned int SpiFlash_ReadMidDid(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
// /CS: 片选拉低
SPI_SET_SS_LOW(SPI2);
// configure transaction length as 8 bits
SPI_SET_DATA_WIDTH(SPI2, 8);
// send Command: 0x90, Read Manufacturer/Device ID
au32SourceData = 0x90;
SPI_WRITE_TX(SPI2, au32SourceData);
while(SPI_IS_BUSY(SPI2));
// configure transaction length as 24 bits
SPI_SET_DATA_WIDTH(SPI2, 24);
// send 24-bit '0', dummy
au32SourceData = 0x0; //这里发送0x00是因为从设备不能自己产生时钟,所以主设备
// 通过向从设备发数据来提供时钟
SPI_WRITE_TX(SPI2, au32SourceData);
while(SPI_IS_BUSY(SPI2));
// configure transaction length as 16 bits
SPI_SET_DATA_WIDTH(SPI2, 16);
I2S_CLR_RX_FIFO(SPI2); //禁止音频接口功能,因为它与SPI公用的一个FIFO
// receive
au32SourceData = 0x0; //同样发0x00是为了给从设备提供时钟
SPI_WRITE_TX(SPI2, au32SourceData);
while(SPI_IS_BUSY(SPI2));
// /CS: de-active
SPI_SET_SS_HIGH(SPI2);
// dump Rx register
au32DestinationData = SPI_READ_RX(SPI2);
return (au32DestinationData & 0xffff);
}
对于SPI,新唐提供的基本操作函数还是挺全的,读数据可以用SpiFlash_ReadData()
向FLASH写数据可以用SpiFlash_PageProgram()不过这个函数是一次编程一页的数据进去。
擦除的话可以用SpiFlash_ChipErase(void)
一般应用就是对FLASH进行读写就够了,可以像下面这样写
Open_SPI_Flash(); //使能SPI
MidDid = SpiFlash_ReadMidDid(); //读设备ID
printf("\n MID and DID = %x\n ", MidDid);
SpiFlash_ChipErase(); //进行片擦,写之前一般都要先擦出一块来
printf("\n Flash Erasing... \n");
SpiFlash_WaitReady(); //等待FLASH准备好
printf("\n Done!\n");
SpiFlash_PageProgram(Buff, u32ProgramFlashAddress, 256); //对FLASH进行写操作
SpiFlash_WaitReady();
SpiFlash_ReadData(DestArray, u32VerifyFlashAddress, 256); //对FLASH进行读操作
SPI_Display(DestArray, 256); //这是一个对读回来的数据进行串口打印的一个函数,这个是自
//己写的,不是官方自带的.函数源码在下面
while(1); //让程序死到这里
----------------------------------------------------------------------------------------------------------------------
void SPI_Display(unsigned char *DataBuff, unsigned int ByteCount)
{
unsigned int i;
for(i=0; i<ByteCount;i++)
{
printf(" %02x",*DataBuff++);
}
}
至于对SPI进本概念的详解,时序的详解,这类帖子有很多,这里就不重复了。 |