前提
查看MM32F0140的MiniBoard原理圖,SPI掛載了W25Q80。

一、SPI介紹
串行外設接口,Serial Peripheral Interface。一種高速的、全雙工、同步的串行通信總線。主要應用于EEPROM、FLASH、AD轉換器,還有數字信號處理器和數字信號解碼器之間。
SPI 支持同時發送和接收數據,采用主從工作方式。SPI 通過 4 個引腳與外部器件相連,分別是:
MOSI:主設備輸出、從設備輸入引腳。傳輸方向為主設備發送到從設備。
MISO:主設備輸入、從設備輸出引腳。傳輸方向為從設備發送到主設備。
NSS:片選信號,從設備選擇。
下圖示意主、從設備之間一對一通信時的連接情況:

主設備負責發起通信請求,從設備負責響應,從設備通過 SCK 引腳得到主設備提供的時鐘信號,從而使得主、從設備均使用同一個時鐘進行同步的全雙工通信。對于從設備而言,MOSI 引腳輸入來自主設備的發送數據,MISO 引腳輸出響應數據傳給主設備。
SPI 需要根據從機特性,選配時鐘極性(CPOL)和時鐘相位(CPHA),比如從機時鐘空閑時為低電平,且在時鐘信號的第一個跳變沿采樣,此時時序見下圖:

二、W25Q80介紹
W25Q80是一種串行閃存存儲器,主要特點包括:
容量:8 Mbit(1 MB)的存儲容量,可以存儲大量數據。
SPI接口:采用SPI接口進行數據通信,具備高速的數據傳輸能力。
快速讀取:支持快速的連續讀取操作,可提供高效的讀取性能。
塊擦除:支持塊擦除功能,可以批量擦除數據,提高擦除效率。
低功耗:采用低功耗設計,適用于對功耗要求較高的應用場景。
W25Q80可以劃分為 4096 個扇區,每個扇區包含 256 個頁,每個頁的大小為 256 字節。
下圖為W25Q80的指令:

三、例程
1.介紹
本例程實現SPI與W25Q80通信,SPI查詢W25Q80的設備號,并全片擦除后寫入數據,再讀取出來,看寫入的數據與讀取的數據是否一致。
2.編碼詳情
1)初始化配置SPI,速度為PCLK1(36MHz)的32分頻,約為1.125MHz;
SPI_InitStructure.SPI_Mode=SPI_Mode_Master; SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b; SPI_InitStructure.SPI_DataWidth=8; SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS=SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB; SPI_Init(SPI2,&SPI_InitStructure); exSPI_DataEdgeAdjust(SPI2,SPI_DataEdgeAdjust_FAST); SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Tx); SPI_BiDirectionalLineConfig(SPI2,SPI_Direction_Rx); SPI_Cmd(SPI2,ENABLE);
2)編寫SPI發送和讀取數據的函數
uint32_twriteAndReadData(uint8_tdata)
{
SPI_SendData(SPI2,data);
while(1){
if(SPI_GetFlagStatus(SPI2,SPI_FLAG_TXEPT)){
break;
}
}
while(1){
if(SPI_GetFlagStatus(SPI2,SPI_FLAG_RXAVL)){
returnSPI_ReceiveData(SPI2);
}
}
}
3)獲取W25Q80的設備ID
SPI_CSInternalSelected(SPI2,ENABLE);//片選 writeAndReadData(0x9F);//讀ID指令 ID|=writeAndReadData(0x00)<16; ????ID?|=?writeAndReadData(0x00)?<8; ????ID?|=?writeAndReadData(0x00); ????SPI_CSInternalSelected(SPI2,?DISABLE);?//?取消片選 ????printf(" read?device?id:?%X",?ID);
4)全片擦除W25Q80,并檢查狀態等待擦除完成
SPI_CSInternalSelected(SPI2,ENABLE); writeAndReadData(0x06);//寫使能 SPI_CSInternalSelected(SPI2,DISABLE); SPI_CSInternalSelected(SPI2,ENABLE); writeAndReadData(0xC7);//全片擦除指令 SPI_CSInternalSelected(SPI2,DISABLE); SPI_CSInternalSelected(SPI2,ENABLE); writeAndReadData(0x05);//讀狀態寄存器 while(1){ temp=writeAndReadData(0x00); if((temp&0x01)==0x0)//擦除完成 break; } SPI_CSInternalSelected(SPI2,DISABLE); printf(" erasecomplete");
5)寫數據,并檢查狀態等待寫完
for(i=0;i256;?i++)?txData[i]?=?i;
????SPI_CSInternalSelected(SPI2,?ENABLE);
????writeAndReadData(0x06);//?寫使能
????SPI_CSInternalSelected(SPI2,?DISABLE);?
????SPI_CSInternalSelected(SPI2,?ENABLE);
????writeAndReadData(0x02);?//?頁編程
????writeAndReadData(0x00);?//?頁地址
????writeAndReadData(0x00);
????writeAndReadData(0x00);
????for?(i?=?0;?i?256;?i++)
????{
????????writeAndReadData(txData[i]);
????}
????SPI_CSInternalSelected(SPI2,?DISABLE);?
????SPI_CSInternalSelected(SPI2,?ENABLE);
????writeAndReadData(0x05);?//?讀狀態寄存器
????while(1)?{
????????temp?=?writeAndReadData(0x00);
????????if((temp?&?0x01)?==?0x0)?//?頁編程完成
????????????break;
????}
????SPI_CSInternalSelected(SPI2,?DISABLE);
????printf("
page?programm?complete");
6)讀數據,并打印出來
SPI_CSInternalSelected(SPI2,ENABLE);
writeAndReadData(0x03);//讀數據
writeAndReadData(0x00);//頁地址
writeAndReadData(0x00);
writeAndReadData(0x00);
for(i=0;i10;?i++)
????{
????????rxData[i]?=?writeAndReadData(0x00);
????}
????SPI_CSInternalSelected(SPI2,?DISABLE);?
????printf("
read?data?completely
");
????for?(i?=?0;?i?10;?i++)?
????????printf("
rxDate[%d]?=?%d",?i,?rxData[i]);
3.串口輸出結果
下圖為串口輸出數據,基本符合程序流程和結果。

4.邏輯分析儀
下圖為邏輯分析儀截取的發送接收圖片,可以清楚的看到當前SCK速度接近1.125MHz,以及發送數據也符合預期。

審核編輯:劉清
-
解碼器
+關注
關注
9文章
1218瀏覽量
43393 -
FlaSh
+關注
關注
10文章
1748瀏覽量
155513 -
EEPROM
+關注
關注
9文章
1137瀏覽量
86029 -
AD轉換器
+關注
關注
4文章
252瀏覽量
43033 -
CPHA
+關注
關注
0文章
9瀏覽量
9630
發布評論請先 登錄
基于MM32F0140的SPI與W25Q80通信的實現方案
華邦存儲器W25Q80, W25Q16, W25Q32系列的spi通訊
基于MM32F0140的SPI與W25Q80通信
評論