|
|
本帖最后由 秦延雷 于 2017-12-20 17:31 編輯
一、概述
1.SPI通訊總線介紹
2.STM32F40xSPI模塊介紹
3.STM32F40xSPI模塊相關(guān)寄存器
4.W25Q64 Flah存儲芯片介紹
二、講解
1.SPI通訊總線介紹
1)SPI通訊協(xié)議概述
SPI是由MOTOROLA公司研發(fā)的串行外圍通訊設(shè)備接口,是一種高速的、全雙工、同步的通訊總線。
2)SPI通訊接口
SPIO通訊接口分為:五線制和四線制
①五線制:
a)MOSI:也稱為DO,作為主器件的時候為數(shù)據(jù)輸出,作為從器件的時候為數(shù)據(jù)輸入。
b)MISO:也稱為DI,作為主器件的時候為數(shù)據(jù)輸入,作為從器件的時候為數(shù)據(jù)輸出。
c)SCLK:時鐘信號線。由主器件產(chǎn)生。
d)NSS:也稱為CS,從器件使能信號。由主器件控制。
e)GND:公共地線
②四線制:
a)MOSI:雙向數(shù)據(jù)線(可收可發(fā))
b)SCLK:時鐘信號線。由主器件產(chǎn)生。
c)NSS:也稱為CS,從器件使能信號。由主器件控制。
d)GND:公共地線
3)SPI通訊物理連接
4)SPI通訊原理
①NSS控制從器件是否被選中,也就是說當(dāng)只有片選信號為預(yù)先規(guī)定的使能信號(高電平或者低電平)時,對從器件的操作才算有效。
②主器件在SCLK時鐘線上提供時鐘脈沖,MOSI或MISO則基于這個脈沖信號完成數(shù)據(jù)的傳輸。
③數(shù)據(jù)通過MOSI線,在時鐘的上升沿或者下降沿改變數(shù)據(jù),在緊接著的下降沿或者上升沿被讀取。SPI通訊協(xié)議規(guī)定傳輸?shù)臄?shù)據(jù)為8位,傳輸順序是高位在前,低位在后。
④SPI總線是一個數(shù)據(jù)交換協(xié)議,主機(jī)給從機(jī)發(fā)送一個位的數(shù)據(jù),從機(jī)必定會返回一個位的數(shù)據(jù)給主機(jī)。也就是說,主機(jī)想讀取從機(jī)的數(shù)據(jù),需要先發(fā)一個位的數(shù)據(jù)給從機(jī),從機(jī)才會回發(fā)一個位的數(shù)據(jù)給主機(jī)。
5)SPI總線數(shù)據(jù)傳輸方式
SPI一共有四種傳輸方式,四種方式的主要區(qū)別是總線空閑時SCLK的時鐘狀態(tài)以及數(shù)據(jù)采樣的時刻(上升沿、下降沿、前沿或者后沿)
SPI模式 時鐘極性(CPOL) 時鐘相位(CPHA) 時鐘空閑狀態(tài) 數(shù)據(jù)采集時刻
0 0 0 低電平 時鐘的奇數(shù)邊緣采集
1 0 1 低電平 時鐘的偶數(shù)邊緣采集
2 1 0 高電平 時鐘的奇數(shù)邊緣采集
3 1 1 高電平 時鐘的偶數(shù)邊緣采集
①時鐘相位(CPHA):決定了數(shù)據(jù)線上第1個數(shù)據(jù)的采集時刻。
a)CPHA = 0:MOSI或MISO數(shù)據(jù)線上的數(shù)據(jù)在串行時鐘線(SCLK)的奇數(shù)邊沿被采集。
b)CPHA = 1:MOSI或MISO數(shù)據(jù)線上的數(shù)據(jù)在串行時鐘線(SCLK)的偶數(shù)邊沿被采集。
②時鐘極性(CPOL):決定了SPI總線在空閑狀態(tài)時(SPI通訊開始之前),時鐘線的電平狀態(tài)。
a)CPOL = 0:串行同步時鐘總線(SCLK)的空閑狀態(tài)為低電平。
b)CPOL = 1:串行同步時鐘總線(SCLK)的空閑狀態(tài)為高電平。
2.STM32F40xSPI模塊介紹
1)STM32F40xSPI模塊概述
STM32F40x的SPI模塊支持兩個功能,分別為:SPI通訊總線協(xié)議以及IIS音頻協(xié)議,默認(rèn)功能為SPI通訊總線協(xié)議功能。SPI通訊協(xié)議支持SPI四線制(半雙工)和五線制(全雙工)通訊模式。同時還可以配置成主機(jī)模式和從機(jī)模式以及多主機(jī)模式,還可以使用CRC校驗實現(xiàn)可靠通信。
2)STM32F40xSPI模塊主要特性
①由SPI模塊中的SCLK、MOSI以及MISO三線組成全雙工同步通信。
②支持SPI四線制同步半雙工通信
③支持?jǐn)?shù)據(jù)傳輸字長為8位或16位
④可以設(shè)置成主機(jī)模式和從機(jī)模式(默認(rèn)是從機(jī)模式)和多主機(jī)模式(在同一個時間內(nèi)只能有1個主機(jī)在工作)
⑤可以對SPI的輸入時鐘源進(jìn)行分頻,頻率最大值為(fpclk/2)
⑥NSS在主模式下為軟件管理,在從模式線為硬件管理
⑦可以設(shè)置數(shù)據(jù)的傳輸順序(先高還是先低)以及SPI的數(shù)據(jù)傳輸方式
⑧支持MOTOROL公司以及TI公司的SPI通訊協(xié)議
⑨SPI中斷源分別為:發(fā)送、接收、主模式錯誤、上溢錯誤、CRC錯誤
⑩支持DMA功能
3)SPI主機(jī)模式設(shè)置
①根據(jù)需要驅(qū)動的目標(biāo)器件來確定SPI的傳輸速度比特率。
②根據(jù)需要驅(qū)動的目標(biāo)器件來配置時鐘極性和相位(TI模式忽略此步)。
③根據(jù)需要驅(qū)動的目標(biāo)器件來確定數(shù)據(jù)位長度。
④根據(jù)需要驅(qū)動的目標(biāo)器件來配置數(shù)據(jù)的傳輸方式(TI模式忽略此步)。
⑤把NSS管腳設(shè)置位軟件管理模式
⑥選擇SPI通信協(xié)議格式
⑦把SPI配置位主機(jī)模式
⑧是SPI模塊
3.STM32F40xSPI模塊相關(guān)寄存器
1)SPI 控制寄存器 1 (SPI_CR1)
寄存器作用:設(shè)置SPI模塊工作模式
2)SPI 控制寄存器 2 (SPI_CR2)
寄存器作用:設(shè)置SPI模塊工作模式
3)SPI 狀態(tài)寄存器 (SPI_SR)
寄存器作用:檢測SPI具體相應(yīng)功能的具體狀態(tài)。
4)SPI 數(shù)據(jù)寄存器 (SPI_DR)
寄存器作用:存放需要發(fā)送或接收的數(shù)據(jù)
4.W25Q64 Flah存儲芯片介紹
1)W25Q64 Flah芯片概述
W25Q64是一款具有SPI通信接口,大小為8M(Byte)的Flash芯片。W25Q64內(nèi)部把8M大小的存儲空間分為128塊(Bolck),每塊大小為64K字節(jié),而每塊又分為16個扇區(qū)(Sector),每個扇區(qū)大小為4K字節(jié)。每個扇區(qū)分為16頁,每頁256個字節(jié)。Flash內(nèi)部數(shù)據(jù)只能有1變0,不能由0變1。
2)W25Q64管腳
①/CS:片選管腳,低電平有效。在執(zhí)行一條新指令之前,必須要讓CS管腳先出現(xiàn)一個下降沿。
②DO(MISO):串行數(shù)據(jù)輸出管腳,在CLK管腳的下降沿輸出數(shù)據(jù)。
③/WP:寫保護(hù)管腳,低電平有效,高電平可讀可寫,低電平僅僅可讀。
④DI(MOSI):串行數(shù)據(jù)輸入管腳,在CLK管腳的上升沿捕獲數(shù)據(jù)。
⑤CLK:串行時鐘管腳,為輸入和輸出數(shù)據(jù)提供時鐘脈沖。
⑥/HOLD:保存管腳,有效電平為低電平。當(dāng)/HOLD為低電,并且CS也為低電平時,數(shù)據(jù)輸出管腳將保持高阻態(tài),同時會忽略數(shù)據(jù)輸出管腳以及時鐘管腳上的信號。把/HOLD管腳拉高,器件恢復(fù)正常工作。
3)W25Q64傳輸速度
W25Q64在標(biāo)準(zhǔn)模式下支持80Mbit/s;快速模式下支持160Mbit/s;高速模式下支持320Mbit/s
4)W25Q64數(shù)據(jù)傳輸
W25Q64支持模式0和模式3數(shù)據(jù)傳輸時序模式。數(shù)據(jù)傳輸?shù)淖珠L為8位,傳輸順序為先高再低。
5)W25Q64工作原理
通過SPI總線接口,用標(biāo)準(zhǔn)的SPI協(xié)議發(fā)送相應(yīng)的指令給Flash,然后Flash根據(jù)命令執(zhí)行各種相關(guān)操作。
5.SPI通信編程思路
1)配置SPI相應(yīng)功能的GPIO管腳
2)使能SPI模塊時鐘
3)設(shè)置SPI模塊工作模式:按照SPI主機(jī)模式設(shè)置步驟設(shè)置
4)編寫SPI字節(jié)數(shù)據(jù)傳輸函數(shù)
#include "spi.h"
/********** SPI初始化函數(shù)**************
DO ----> PB4 復(fù)用模式
CLK ----> PB3 復(fù)用模式
DI ----> PB5 復(fù)用模式
***************************************/
void SPI_Init(void)
{
/* SPI引腳管腳配置 */
RCC->AHB1ENR |= 1 << 1; //使能 GPIOB外設(shè)時鐘
/* PB3(CLK)管腳配置 復(fù)用模式 */
/* 管腳模式配置 */
GPIOB->MODER &= ~(3 << (3 * 2)); //清零
GPIOB->MODER |= 2 << (3 * 2); //PB3配置為復(fù)用模式
/* 復(fù)用功能配置 */
GPIOB->AFR[0] &= ~(0x0f << (3 * 4)); //清零
GPIOB->AFR[0] |= 5 << (3 * 4); //PB3 復(fù)用選擇SPI_1
/* 輸出速率配置 */
GPIOB->OSPEEDR &= ~(3 << (3 * 2)); //清零
GPIOB->OSPEEDR |= 2 << (3 * 2); //輸出速率50M
/* PB4(DO)管腳配置 復(fù)用模式*/
/* 管腳模式配置 */
GPIOB->MODER &= ~(3 << (4 * 2)); //清零
GPIOB->MODER |= 2 << (4 * 2); //PB4配置為復(fù)用模式
/* 復(fù)用功能配置 */
GPIOB->AFR[0] &= ~(0x0f << (4 * 4)); //清零
GPIOB->AFR[0] |= 5 << (4 * 4); //PB4 復(fù)用選擇SPI_1
/* PB5(DI)管腳配置 復(fù)用模式 */
/* 管腳模式配置 */
GPIOB->MODER &= ~(3 << (5 * 2)); //清零
GPIOB->MODER |= 2 << (5 * 2); //PB5配置為復(fù)用模式
/* 復(fù)用功能配置 */
GPIOB->AFR[0] &= ~(0x0f << (5 * 4)); //清零
GPIOB->AFR[0] |= 5 << (5 * 4); //PB5 復(fù)用選擇SPI_1
/* 輸出速率配置 */
GPIOB->OSPEEDR &= ~(3 << (5 * 2)); //清零
GPIOB->OSPEEDR |= 2 << (5 * 2); //輸出速率50M
/* 使能SPI模塊時鐘 */
RCC->APB2ENR |= 1 << 12; //使能SPI_1時鐘
/* 設(shè)置SPI模塊工作模式 */
SPI1->CR1 &= ~(7 << 3); //SPI_1波特率42M
SPI1->CR1 &= ~(1 << 1); //SPI_1時序模式0
SPI1->CR1 &= ~(1 << 0);
SPI1->CR1 &= ~(1 << 11); //8位數(shù)據(jù)長度
SPI1->CR1 &= ~(1 << 7); //先發(fā)高位
SPI1->CR1 |= 1 << 9; //NSS軟件管理
SPI1->CR1 |= 1 << 8; //NSS內(nèi)部狀態(tài)為高電平
SPI1->CR2 &= ~(1 << 4); //選擇MOTOROLA模式
SPI1->CR1 |= 1 << 2; //主機(jī)模式
/* 使能SPI */
SPI1->CR1 |= 1 << 6; //使能SPI_1
}
/********************** SPI數(shù)據(jù)傳輸函數(shù) *********************************/
u16 SPI_Send_Read_Byte(u8 data)
{
u16 ErrTimer = 0;
/* 寫功能 */
while( !(SPI1->SR & (1 << 1)) )
{
ErrTimer++;
if(ErrTimer >= 0xfffe)
{
return 0;
}
}
SPI1->DR = data;
ErrTimer = 0;
/* 讀功能 */
while( !(SPI1->SR & (1 << 0)) )
{
ErrTimer++;
if(ErrTimer >= 0xfffe)
{
return 0;
}
}
return SPI1->DR;
}
|
|