新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 踏踏實(shí)實(shí)搞清 stm32 SPI總線 基礎(chǔ)和編程

踏踏實(shí)實(shí)搞清 stm32 SPI總線 基礎(chǔ)和編程

作者: 時(shí)間:2016-11-28 來源:網(wǎng)絡(luò) 收藏

全雙工模式(BIDIMODE=0并且RXONLY=0)

當(dāng)寫入數(shù)據(jù)到SPI_DR寄存器(發(fā)送緩沖器)后,傳輸開始;

在傳送第一位數(shù)據(jù)的同時(shí),數(shù)據(jù)被并行地從發(fā)送緩沖器傳送到8位的移位寄存器中,

然后按順序被串行地移位送到MOSI引腳上;

與此同時(shí),在MISO引腳上接收到的數(shù)據(jù),按順序被串行地移位進(jìn)入8位的移位寄存器

中,然后被并行地傳送到SPI_DR寄存器(接收緩沖器)中。

注意:也就是說,在主機(jī)模式下,發(fā)送和接收是同時(shí)進(jìn)行的,所以我們發(fā)送了一個(gè)數(shù)據(jù),也就能接收到一個(gè)數(shù)據(jù)。而STM32內(nèi)部硬件是這個(gè)過程的支撐!

讀一個(gè)字節(jié),往里面發(fā)送0,外設(shè)就返回一個(gè)數(shù)據(jù)了,發(fā)送的0外設(shè)不處理(需要先寫入命令生效)

#define SPI_ReadByte(SPIx) SPI_WriteByte(SPIx,0)

寫一個(gè)字節(jié)就直接發(fā)送相應(yīng)的字節(jié),外設(shè)就返回一個(gè)數(shù)據(jù)了

u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 byte);

//spi 寫一個(gè)字節(jié)...................................................................
u8 SPI_WriteByte(SPI_TypeDef* SPIx,u8 Byte)
{
while((SPIx->SR&SPI_I2S_FLAG_TXE)==RESET); //等待發(fā)送區(qū)空
SPIx->DR=Byte; //發(fā)送一個(gè)byte
while((SPIx->SR&SPI_I2S_FLAG_RXNE)==RESET);//等待接收完一個(gè)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();
}

//頁(yè)編程函數(shù),頁(yè)編程前一定要進(jìn)行頁(yè)擦除!!!
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ù)搞懂了,特別市紅色部分標(biāo)注的為重點(diǎn),對(duì)于spi也就基本清楚了,這些也算是最底層的函數(shù)了,提供基本的API供以后文件系統(tǒng)或其它地方使用。

----------------------------------------------------------------------------------------------

最后補(bǔ)上一些文件框架的說明

首先我們把最底層的SPI初始化寫上,函數(shù)如下:


可見有芯片自帶SPI模塊 有給mp3芯片的,有給flash的,還有給無線網(wǎng)絡(luò)的,還有給軟件模擬spi時(shí)序供給觸摸屏的控制器的,然后我們把這個(gè).c文件配套的.h文件給下面具體的函數(shù)包含,就能正確的選取和使用了,當(dāng)這些具體功能的函數(shù)寫好了后,對(duì)應(yīng)得.h函數(shù)就又繼續(xù)給更高級(jí)別的應(yīng)用層使用。

今天先就介紹下spi_flash模塊了,等天補(bǔ)上其它3個(gè)模塊的講解,畢竟現(xiàn)在是基礎(chǔ)哦。


上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: stm32SPI總

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉