1.SPI簡介
SPI是串行外設(shè)接口(Serial Peripheral Interface)的縮寫,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時為PCB的布局上節(jié)省空間,提供方便,正是出于這種簡單易用的特性,越來越多的芯片集成了這種通信協(xié)議。
SPI:高速同步串行口。是一種標準的四線同步雙向串行總線,是串行外圍設(shè)備接口。是Motorola首先在其MC68HCXX系列處理器上定義的。SPI接口主要應(yīng)用在 EEPROM,F(xiàn)LASH,實時時鐘,AD轉(zhuǎn)換器,還有數(shù)字信號處理器和數(shù)字信號解碼器之間。
該接口一般使用4條線:串行時鐘線(SCLK)、主機輸入/從機輸出數(shù)據(jù)線MISO、主機輸出/從機輸入數(shù)據(jù)線MOSI和低電平有效的從機選擇線SS(有的SPI接口芯片帶有中斷信號線INT、有的SPI接口芯片沒有主機輸出/從機輸入數(shù)據(jù)線MOSI)。
SPI根據(jù)時鐘極性(CPOL)和時鐘相位(CPHA)的不同,能夠產(chǎn)生4時鐘時序。時鐘極性(CPOL)控制時鐘線空閑電平狀態(tài),時鐘相位(CPHA)用來控制數(shù)據(jù)采樣極性。
模式0:CPOL=0,CPHA=0
??時鐘線空閑電平為低電平,第一個邊沿采樣數(shù)據(jù),第二個邊沿發(fā)送數(shù)據(jù);
模式1:CPOL=0,CPHA=1
??時鐘線空閑電平為低電平,第一個邊沿發(fā)送數(shù)據(jù),第二個邊沿采樣數(shù)據(jù);
模式2:CPOL=1,CPHA=0
??時鐘線空閑電平為高電平,第一個邊沿采樣數(shù)據(jù),第二個邊沿發(fā)送數(shù)據(jù);
模式3:CPOL=1,CPHA=1
??時鐘線空閑電平為高電平,第一個邊沿發(fā)送數(shù)據(jù),第二個邊沿采樣數(shù)據(jù);
2 硬件接口
2.1 W25Q64簡介
W25Q64(64M-bit),W25Q16(16M-bit)和W25Q32(32M-bit)是為系統(tǒng)提供一個最小的空間、引腳和功耗的存儲器解決方案的串行Flash存儲器。25Q系列比普通的串行Flash存儲器更靈活,性能更優(yōu)越?;陔p倍/四倍的SPI,它們能夠可以立即完成提供數(shù)據(jù)給RAM,包括存儲聲音、文本和數(shù)據(jù)。芯片支持的工作電壓2.7V到3.6V,正常工作時電流小于5mA,掉電時低于1uA。所有芯片提供標準的封裝。
W25Q64/16/32由每頁256字節(jié)組成。每頁的256字節(jié)用一次頁編程指令即可完成。每次可以擦除16頁(1個扇區(qū))、128 頁(32KB塊)、256頁(64KB塊)和全片擦除。
W25Q64的內(nèi)存空間結(jié)構(gòu):一頁256字節(jié),4K(4096字節(jié))為一個扇區(qū),16個扇區(qū)為1塊,容量為8M字節(jié),共有128個塊,2048個扇區(qū)。
W25Q64可擦寫周期至少10萬次,數(shù)據(jù)保存20年。
W25Q64驅(qū)動方式為SPI,支持SPI總線的工作模式0(0,0)和3( 1,1)。模式0和模式3。
2.2 硬件接口
引腳 | 說明 |
CS | 片選(低電平選中) PB12 |
SPI2_MISO | 主機輸入從機輸出PB14 |
SPI2_MOSI | 主機輸出從機輸入PB15 |
SPI_SCK | 時鐘線PB13 |
CS | 片選(低電平選中) PB12 |
2.3 軟件設(shè)置
SPI2配置:
NSS引腳配置:
3 代碼生成
3.1 SPI初始化
??SPI配置信息可參考STM32中文參考手冊第23.5.1SPI控制寄存器小結(jié)。
3.2 SPI讀寫一字節(jié)函數(shù)
uint8_t SPI2_WROneByte(uint8_t data)
{
uint8_t dat_rx=0;
HAL_SPI_TransmitReceive(&hspi2,&data,&dat_rx,1,100);
return dat_rx;
}
3.3 W25Q64 編程
3.3.1 讀取W25Q64制造商/芯片ID
/*獲取W25Q64設(shè)備ID*/
uint16_t W25Q64_GetDeviceID(void)
{
uint16_t id;
W25Q64_CS(0);//選中W25Q64
SPI2_WROneByte(0x90);//發(fā)送指令0x90
//發(fā)送24位地址
SPI2_WROneByte(0);
SPI2_WROneByte(0);
SPI2_WROneByte(0);
id=SPI2_WROneByte(0xff);//制造商ID:0xef
id<<=8;
id|=SPI2_WROneByte(0xff);//設(shè)備ID:0x16
W25Q64_CS(1);//取消選中
return id;
}
3.3.2 W25Q64頁編程0x02
頁編程指令允許從一個字節(jié)到256字節(jié)的數(shù)據(jù)編程(一頁)(編程之前必須保證內(nèi)存空間是 0XFF)。允許寫入指令之前,必須先發(fā)送設(shè)備寫使能指令。寫使能開啟后,設(shè)備才能接收編程指令。開啟頁編程先拉底/ CS, 然后發(fā)送指令代碼“02 h”,接著發(fā)送一個 24 位地址(A23-A0)(發(fā)送3次,每次 8 位) 和至少一個數(shù)據(jù)字節(jié)(數(shù)據(jù)字節(jié)不能超過256字節(jié))。數(shù)據(jù)字節(jié)發(fā)送完畢,需要拉高片選線 CS/,并判斷狀態(tài)位,等待寫入結(jié)束。
進行頁編程時,如果數(shù)據(jù)字節(jié)數(shù)超過了256字節(jié),地址將自動回到頁的起始地址,覆蓋掉之前的數(shù)據(jù)。在某些情況下,數(shù)據(jù)字節(jié)小于256字節(jié)(同一頁內(nèi)), 也可以正常對其他字節(jié)存放,不會有任何影響。如果存放超過256字節(jié)的數(shù)據(jù),需要分次編程存放。
3.3.3 W25Q64讀數(shù)據(jù)0x03
讀取數(shù)據(jù)指令允許按順序讀取一個字節(jié)的內(nèi)存數(shù)據(jù)。當片選CS/拉低之后, 緊隨其后是一個24位的地址(A23-A0)(需要發(fā)送3次,每次8個字節(jié),先發(fā)高位)。芯片收到地址后,將要讀的數(shù)據(jù)按字節(jié)大小轉(zhuǎn)移出去,數(shù)據(jù)是先轉(zhuǎn)移高位,對于單片機,時鐘下降沿發(fā)送數(shù)據(jù),上升沿接收數(shù)據(jù)。讀數(shù)據(jù)時,地址會自動增加,允許連續(xù)的讀取數(shù)據(jù)。這意味著讀取整個內(nèi)存的數(shù)據(jù),只要用一個指令就可以讀完。數(shù)據(jù)讀取完成之后,片選信號/ CS 拉高。讀取數(shù)據(jù)的指令序列,如上圖所示。如果一個讀數(shù)據(jù)指令而發(fā)出的時候,設(shè)備正在擦除扇區(qū),或者(忙= 1),該讀指令將被忽略,也不會對當前周期有什么影響。
3.3.4 扇區(qū)擦除0x20
扇區(qū)擦除指令可以擦除指定一個扇區(qū)(4 k字節(jié))內(nèi)所有數(shù)據(jù),將內(nèi)存空間恢復(fù)到 0xFF 狀態(tài)。寫入扇區(qū)擦除指令之前必須執(zhí)行設(shè)備寫使能(發(fā)送設(shè)備寫使能指令 0x06),并判斷狀態(tài)寄存器(狀態(tài)寄存器位最低位必須等于0才能操作)。發(fā)送的扇區(qū)擦除指令前,先拉低/ CS, 接著發(fā)送扇區(qū)擦除指令碼”20 h”,和24位地址(A23-A0),地址發(fā)送完畢后,拉高片選線 CS/,并判斷狀態(tài)位,等待擦除結(jié)束。擦除一個扇區(qū)的最少需要 150ms 時間。
3.3.5 讀狀態(tài)0x05和0x35
讀取狀態(tài)寄存器的指令是8位的指令。發(fā)送指令之前,先將/ CS 拉低,再發(fā)送指令碼“05 h”或者“35h”。設(shè)備收到讀取狀態(tài)寄存器的指令后,將狀態(tài)信息(高位)依次移位發(fā)送出去,讀出的狀態(tài)信息,最低位為1代表忙,最低位為0代表可以操作,狀態(tài)信息讀取完畢,將片選線拉高。
讀狀態(tài)寄存器指令可以使用在任何時候,即使程序在擦除的過程中或者寫狀態(tài)寄存器周期正在進行中。這可以檢測忙碌狀態(tài)來確定周期是否完成,以確定設(shè)備是否可以接受另一個指令。
3.3.6 W25Q64指令表
4 主函數(shù)
MX_GPIO_Init();
MX_FSMC_Init();
MX_USART1_UART_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
char buff[200];
char buff_tx[]="HAL庫配置SPI硬件時序驅(qū)動W25Q64S數(shù)據(jù)讀寫測試 -- Ver1.0";
char buf_rx[100];
NT35310_Init();//LCD初始化
LCD_Display_Str(LCD_WIDTH/2-strlen("W25Q64初始化")/2*8,20,16,(u8 *)"W25Q64初始化",BLACK);
LCD_Display_Str(20,40,16,(u8 *)"W25Q64 OK",RED);
uint16_t id=W25Q64_GetDeviceID();
snprintf(buff,sizeof(buff),"ID信息:%#x",id);
LCD_Display_Str(20,60,16,(u8 *)buff,RED);
LCD_Display_Str(LCD_WIDTH/2-strlen("W25Q64讀寫測試")/2*8,90,16,(u8 *)"W25Q64讀寫測試",BLACK);
W25Q64_WriteData(100,buf_tx,sizeof(buf_tx));
W25Q64_ReadData(100,buf_rx,sizeof(buf_tx));
LCD_Display_Str(20,120,16,(u8 *)"W25Q64寫數(shù)據(jù):OK",RED);
LCD_Display_Str(20,140,16,(u8 *)"W25Q64讀數(shù)據(jù):OK",RED);
LCD_Display_Str(20,160,16,(u8 *)"數(shù)據(jù)內(nèi)容:",RED);
LCD_Display_Str(20,180,16,(u8 *)buf_rx,BLUE);
while(1)
{
}
-
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356001 -
SPI
+關(guān)注
關(guān)注
17文章
1706瀏覽量
91581 -
HAL
+關(guān)注
關(guān)注
2文章
70瀏覽量
12615 -
w25Q64
+關(guān)注
關(guān)注
1文章
15瀏覽量
3022
發(fā)布評論請先 登錄
相關(guān)推薦
評論