● 全雙工模式(BIDIMODE=0并且RXONLY=0)
─ 當寫入數(shù)據(jù)到SPI_DR寄存器(發(fā)送緩沖器)后,傳輸開始;
─ 在傳送第一位數(shù)據(jù)的同時,數(shù)據(jù)被并行地從發(fā)送緩沖器傳送到8位的移位寄存器中,
然后按順序被串行地移位送到MOSI引腳上;
─ 與此同時,在MISO引腳上接收到的數(shù)據(jù),按順序被串行地移位進入8位的移位寄存器
中,然后被并行地傳送到SPI_DR寄存器(接收緩沖器)中。
注意:也就是說,在主機模式下,發(fā)送和接收是同時進行的,所以我們發(fā)送了一個數(shù)據(jù),也就能接收到一個數(shù)據(jù)。而STM32內(nèi)部硬件是這個過程的支撐!
讀一個字節(jié),往里面發(fā)送0,外設(shè)就返回一個數(shù)據(jù)了,發(fā)送的0外設(shè)不處理(需要先寫入命令生效)
#define SPI_ReadByte(SPIx) SPI_WriteByte(SPIx,0)
寫一個字節(jié)就直接發(fā)送相應的字節(jié),外設(shè)就返回一個數(shù)據(jù)了
u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 byte);
//spi 寫一個字節(jié)...................................................................
u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
{
while((SPIx->SR&SPI_I2S_FLAG_TXE)==RESET); //等待發(fā)送區(qū)空
SPIx->DR=Byte; //發(fā)送一個byte
while((SPIx->SR&SPI_I2S_FLAG_RXNE)==RESET);//等待接收完一個byte
return SPIx->DR; //返回收到的數(shù)據(jù)
}
void M25P16_Write_Enable(void)
{
Select_Flash();
SPI_Flash_Write(WRITE_ENABLE);
NotSelect_Flash();
}
void M25P16_Read_Id(u8 * id)
{
u8 i;
Select_Flash();
SPI_Flash_Write(READ_ID);
for(i=0;i<20;i++)
{
id[i] = SPI_Flash_Read();
}
NotSelect_Flash();
}
void M25P16_Write_Status_Reg(u8 reg)
{
Select_Flash();
SPI_Flash_Write(WRITE_STAUS_REG);
SPI_Flash_Write(reg);
NotSelect_Flash();
}
void M25P16_Read_Data(u32 addr,u32 len,u8 *buf)
{
u32 i;
Select_Flash();
SPI_Flash_Write(READ_DATA);
SPI_Flash_Write((addr>>16) & 0xff);
SPI_Flash_Write((addr>>8) & 0xff);
SPI_Flash_Write(addr & 0xff);
for(i=0;i{
buf[i]=SPI_Flash_Read();
}
NotSelect_Flash();
}
//頁編程函數(shù),頁編程前一定要進行頁擦除!!!
void M25P16_Page_Program(u32 addr,u16 len,u8 *buf)
{
u32 i;
M25P16_Write_Enable();
Select_Flash();
SPI_Flash_Write(PAGE_PROGRAM);
SPI_Flash_Write((addr>>16) & 0xff);
SPI_Flash_Write((addr>>8) & 0xff);
SPI_Flash_Write(addr & 0xff);
for(i=0;iSPI_Flash_Write(buf[i]);
NotSelect_Flash();
while(M25P16_Read_Status_Reg()&0x01);
}
以上函數(shù)搞懂了,特別市紅色部分標注的為重點,對于spi也就基本清楚了,這些也算是最底層的函數(shù)了,提供基本的API供以后文件系統(tǒng)或其它地方使用。
----------------------------------------------------------------------------------------------
最后補上一些文件框架的說明
首先我們把最底層的SPI初始化寫上,函數(shù)如下:
可見有芯片自帶SPI模塊 有給mp3芯片的,有給flash的,還有給無線網(wǎng)絡的,還有給軟件模擬spi時序供給觸摸屏的控制器的,然后我們把這個.c文件配套的.h文件給下面具體的函數(shù)包含,就能正確的選取和使用了,當這些具體功能的函數(shù)寫好了后,對應得.h函數(shù)就又繼續(xù)給更高級別的應用層使用。
今天先就介紹下spi_flash模塊了,等天補上其它3個模塊的講解,畢竟現(xiàn)在是基礎(chǔ)哦。
評論