前提
查看MM32F0140的MiniBoard原理圖,SPI掛載了W25Q80。
一、SPI介紹
串行外設(shè)接口,Serial Peripheral Interface。一種高速的、全雙工、同步的串行通信總線。主要應(yīng)用于EEPROM、FLASH、AD轉(zhuǎn)換器,還有數(shù)字信號(hào)處理器和數(shù)字信號(hào)解碼器之間。
SPI 支持同時(shí)發(fā)送和接收數(shù)據(jù),采用主從工作方式。SPI 通過 4 個(gè)引腳與外部器件相連,分別是:
MOSI:主設(shè)備輸出、從設(shè)備輸入引腳。傳輸方向?yàn)橹髟O(shè)備發(fā)送到從設(shè)備。
MISO:主設(shè)備輸入、從設(shè)備輸出引腳。傳輸方向?yàn)閺脑O(shè)備發(fā)送到主設(shè)備。
SCK:串行時(shí)鐘信號(hào),由主設(shè)備產(chǎn)生并提供給從設(shè)備。
NSS:片選信號(hào),從設(shè)備選擇。
下圖示意主、從設(shè)備之間一對(duì)一通信時(shí)的連接情況:
主設(shè)備負(fù)責(zé)發(fā)起通信請(qǐng)求,從設(shè)備負(fù)責(zé)響應(yīng),從設(shè)備通過 SCK 引腳得到主設(shè)備提供的時(shí)鐘信號(hào),從而使得主、從設(shè)備均使用同一個(gè)時(shí)鐘進(jìn)行同步的全雙工通信。對(duì)于從設(shè)備而言,MOSI 引腳輸入來自主設(shè)備的發(fā)送數(shù)據(jù),MISO 引腳輸出響應(yīng)數(shù)據(jù)傳給主設(shè)備。
SPI 需要根據(jù)從機(jī)特性,選配時(shí)鐘極性(CPOL)和時(shí)鐘相位(CPHA),比如從機(jī)時(shí)鐘空閑時(shí)為低電平,且在時(shí)鐘信號(hào)的第一個(gè)跳變沿采樣,此時(shí)時(shí)序見下圖:
二、W25Q80介紹
W25Q80是一種串行閃存存儲(chǔ)器,主要特點(diǎn)包括:
容量:8 Mbit(1 MB)的存儲(chǔ)容量,可以存儲(chǔ)大量數(shù)據(jù)。
SPI接口:采用SPI接口進(jìn)行數(shù)據(jù)通信,具備高速的數(shù)據(jù)傳輸能力。
快速讀取:支持快速的連續(xù)讀取操作,可提供高效的讀取性能。
塊擦除:支持塊擦除功能,可以批量擦除數(shù)據(jù),提高擦除效率。
低功耗:采用低功耗設(shè)計(jì),適用于對(duì)功耗要求較高的應(yīng)用場(chǎng)景。
W25Q80可以劃分為 4096 個(gè)扇區(qū),每個(gè)扇區(qū)包含 256 個(gè)頁,每個(gè)頁的大小為 256 字節(jié)。
下圖為W25Q80的指令:
三、例程
1.介紹
本例程實(shí)現(xiàn)SPI與W25Q80通信,SPI查詢W25Q80的設(shè)備號(hào),并全片擦除后寫入數(shù)據(jù),再讀取出來,看寫入的數(shù)據(jù)與讀取的數(shù)據(jù)是否一致。
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發(fā)送和讀取數(shù)據(jù)的函數(shù)
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的設(shè)備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,并檢查狀態(tài)等待擦除完成
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);//讀狀態(tài)寄存器 while(1){ temp=writeAndReadData(0x00); if((temp&0x01)==0x0)//擦除完成 break; } SPI_CSInternalSelected(SPI2,DISABLE); printf(" erasecomplete");
5)寫數(shù)據(jù),并檢查狀態(tài)等待寫完
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);?//?讀狀態(tài)寄存器 ????while(1)?{ ????????temp?=?writeAndReadData(0x00); ????????if((temp?&?0x01)?==?0x0)?//?頁編程完成 ????????????break; ????} ????SPI_CSInternalSelected(SPI2,?DISABLE); ????printf(" page?programm?complete");
6)讀數(shù)據(jù),并打印出來
SPI_CSInternalSelected(SPI2,ENABLE); writeAndReadData(0x03);//讀數(shù)據(jù) 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.串口輸出結(jié)果
下圖為串口輸出數(shù)據(jù),基本符合程序流程和結(jié)果。
4.邏輯分析儀
下圖為邏輯分析儀截取的發(fā)送接收?qǐng)D片,可以清楚的看到當(dāng)前SCK速度接近1.125MHz,以及發(fā)送數(shù)據(jù)也符合預(yù)期。
審核編輯:劉清
-
解碼器
+關(guān)注
關(guān)注
9文章
1143瀏覽量
40718 -
FlaSh
+關(guān)注
關(guān)注
10文章
1633瀏覽量
147943 -
EEPROM
+關(guān)注
關(guān)注
9文章
1019瀏覽量
81560 -
AD轉(zhuǎn)換器
+關(guān)注
關(guān)注
4文章
250瀏覽量
41410 -
CPHA
+關(guān)注
關(guān)注
0文章
8瀏覽量
9380
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論