引 言
PIC單片機" title="單片機">單片機以性能穩(wěn)定,、品種眾多等特點在工業(yè)控制、儀器儀表、家電,、通信等領(lǐng)域得到廣泛應(yīng)用,。雖然很多型號自身集成了存儲器,但在很多情況下難以滿足系統(tǒng)對大容量存儲的要求,,需要外擴非易失性的存儲器,。與并行Flash存儲器相比,串行Flash存儲器占用MCU引腳少,,體積小,,易于擴展,接線簡單,,工作可靠,,故而越來越多地應(yīng)用在各類電子產(chǎn)品和工業(yè)測控系統(tǒng)中。本文主要討論PIC16F877A單片機與串行閃存" title="串行閃存">串行閃存M25P16之間的SPI通信,,在要求大容量數(shù)據(jù)存儲且MCU引腳資源有限的情況下具有實用價值,。
1 SPI工作原理
SPI(Serial Peripheral Interface)是一種常用的串行通信協(xié)議,用于MCU系統(tǒng)與外圍設(shè)備的通信,,可用來連接存儲器,、A/D轉(zhuǎn)換器、D/A轉(zhuǎn)換器,、實時時鐘,、LCD驅(qū)動器,、傳感器,,甚至其他處理器。SPI主要使用4個信號:MOSI(主機輸出/從機輸人),、MISO(主機輸入/從機輸出),、SCK(串行時鐘)和CS(片選)。其中,,SCK由主機產(chǎn)生,,作為傳輸?shù)耐綍r鐘,控制所有數(shù)據(jù)傳輸,。主機通過觸發(fā)從設(shè)備的CS決定二者之間的SPI傳輸是否能夠進行,。主機和外設(shè)都包含1個串行移位寄存器。主機通過向自己的SPI串行寄存器寫入1個字節(jié)來發(fā)起1次傳輸,,然后通過MOSI信號線將數(shù)據(jù)傳給外設(shè),,同時外設(shè)將自己移位寄存器中的內(nèi)容通過MISO信號線返回給主機,如圖1所示,。這樣,,兩個移位寄存器中的內(nèi)容就交換了。也就是說,,外設(shè)的寫操作和讀操作是同步完成的,。在實際應(yīng)用中,,如果只進行寫操作,則主機只需忽略收到的字節(jié)即可,;如果主機要讀外設(shè)的數(shù)據(jù),,必須發(fā)送1個字節(jié)來引發(fā)從機的傳輸,發(fā)送的這個字節(jié)可以是任意數(shù)據(jù),。
2 M25P16簡介
M25P16是16 Mb的串行閃存,,具有先進的寫保護機制,支持速度高達50 MHz的SPI總線的存取操作,。該存儲器有32個扇區(qū),,每個扇區(qū)256頁,每頁256字節(jié),。工作電壓范圍2.7~3.6 V,,工作溫度范圍-40~+85℃。數(shù)據(jù)保存長達20年,,每個扇區(qū)可擦寫/編程100 000次,。
M25P16支持的操作指令共有12條。指令格式為:
其中,,8位的命令字是必需的,,地址、啞元以及數(shù)據(jù)字節(jié)的有無和長度會因指令的不同而有所差別,,詳情如表1所列,。所有的命令碼、地址,、串行輸入/輸出的數(shù)據(jù),,均是高位在前,低位在后,。
對M25P16操作時,,先選中芯片(即片選信號S拉低),然后串行輸入操作指令字節(jié),,緊接著串行輸入地址字節(jié)(0或3字節(jié)),,必要時還要加入啞讀字節(jié),最后串行輸入/輸出數(shù)據(jù)字節(jié),,然后把片選信號拉高,,之后M25P16啟動內(nèi)部控制邏輯,自行完成相應(yīng)的操作,。
3 SPI硬件設(shè)計
PIC16F877A單片機具有非常完善的SPI接口(RC3/SCK,、RC4/SDI、RC5/SDO、RA5/SS),,只有PIC16F877A作為從機時,,RA5/SS引腳才作為SPI腳,PIC16F877A為主機時,,SS可作為普通I/O使用,。通過該接口,可比較容易地實現(xiàn)PIC16F877A與SPI Flash的通信,。PIC16F877A與M25P16的硬件接口如圖2所示,。其中,SCK,、SDI,、SDO為MCU的SPI專用引腳,分別與存儲器的對應(yīng)引腳相連,,可選MCU的任意I/O腳作為存儲器的片選信號,,圖中選取RC2腳與存儲器的片選S相連,這樣,,在SPI通信時只涉及MCU的C口,,便于操作。M25P16的HOLD和W直接接高電平,,表示不允許在S有效的情況下暫停SPI通信且整個存儲區(qū)都沒有寫保護,。
圖2中,VDD為+5 V,,由于PIC16F877A工作在5 V電壓下,,而M25P16的工作電壓范圍為2.7~3.6 V,二者不能直接相連,。這里采用電阻分壓的方式,,保證輸入M25P16的S、C,、D腳的電壓在存儲器能承受且能識別的范圍內(nèi),通過在M25P16向PIC16F877A輸入數(shù)據(jù)的SDO腳加上拉電阻,,保證MCU可以識別M25P16輸出的高電壓,,從而保證正常的SPI通信。如果MCU工作于3.3 V,,則直接將二者的對應(yīng)引腳相連即可,。
4 SPI軟件設(shè)計
在硬件連線正確的基礎(chǔ)上,要進行SPI通信,,還要對M25P16編寫驅(qū)動程序,,包括SPI初始化、讀M25P16的數(shù)據(jù)、向M25P16寫人數(shù)據(jù),、數(shù)據(jù)的擦除等,,這里使用C語言編程,編譯器選擇PICC,,開發(fā)環(huán)境為MPLAB IDE8.10,。
PIC16F877A的SPI通信涉及4個寄存器:控制寄存器SSPCON、狀態(tài)寄存器SSPSTAT串行接收/發(fā)送緩沖器SSPBUF和移位寄存器SSPSR,。其中,,SSPCON的8位都是可讀可寫的,用于設(shè)置SSP處于主/從模式,、時鐘頻率,、時鐘極性、SSP使能以及寫沖突檢測,;SSPSTAT只有高2位可讀寫,,低6位是只讀的。PIC16F877A處于接收模式時,,SSPSR和SSPBUF構(gòu)成2級緩沖的接收器,,SSPSR每收到1個完整的字節(jié),就將該字節(jié)傳給SSPBUF,,并將中斷標志位SSPIF置1,,可通過讀SSPBUF得到數(shù)據(jù);877A處于發(fā)送模式時,寫SSPBUF操作會同時將數(shù)據(jù)寫入SSPSR,,觸發(fā)傳輸,。下面結(jié)合具體的代碼進行詳細闡述。
(1)SPI初始化與讀寫函數(shù)
從SendByte和RcvByte函數(shù)的代碼中,,可以看出數(shù)據(jù)發(fā)送和接收是否完成,都是通過判斷STAT_BF標志位(SSPSTAT寄存器的BF位,,STAT_BF是在頭文件pic1687x.h中定義的名稱)來實現(xiàn)的,,而數(shù)據(jù)手冊中關(guān)于BF位的描述僅用于接收模式。這是由于PIC16F877A通過SDO發(fā)送數(shù)據(jù)的同時,,會通過SDI讀人數(shù)據(jù),,當1字節(jié)發(fā)送完成時,剛好接收1字節(jié)到SSPBUF,,這時SSPBUF滿,,BY被置為1,故可通過STAT_BF標志判斷1字節(jié)是否發(fā)送完成,。
(2)連續(xù)寫函數(shù)
M25P16的PP指令允許1次連續(xù)寫入不超過1頁(256字節(jié))的數(shù)據(jù),。寫人數(shù)據(jù)之前,,首先要發(fā)出寫允許命令,然后才能執(zhí)行數(shù)據(jù)寫入操作,。數(shù)據(jù)寫入函數(shù)參數(shù)包括address(32位地址),、block(寫入數(shù)據(jù)緩沖區(qū)指針)、n(一次連續(xù)寫入的字節(jié)數(shù),,n<256),。如果address的低8位不全為0,即不是從頁起始處寫,,并且需要寫入的數(shù)據(jù)超出該頁剩余空間,,則超出部分被丟棄。代碼如下:
其中,,delay()為延時子函數(shù),,參數(shù)為ms級,delay(1)即延時1ms,。加入延時,,是為了保證存儲器在準備好的情況下才進行讀寫操作。
(3)連續(xù)讀函數(shù)
M25P16允許發(fā)出讀指令后,,連續(xù)讀取數(shù)據(jù),,這一模式極大提高了總線效率。數(shù)據(jù)讀取函數(shù)的參數(shù)包括address:32位地址,;block:讀數(shù)據(jù)緩沖區(qū)指針,;n:一次連續(xù)讀取的字節(jié)數(shù),代碼如下:
M25P16的連續(xù)讀操作與連續(xù)寫不同的是,,無論READ還是FAST_READ,,在起始地址處1字節(jié)的數(shù)據(jù)讀出后,會自動尋址更高地址處的數(shù)據(jù),,故程序中無需address++語句,。
除了對M25P16的初始化、讀寫之外,,經(jīng)常還要對其進行擦除操作,,擦除有扇區(qū)擦除和整體擦除2種方式,執(zhí)行數(shù)據(jù)擦除將使內(nèi)部所有數(shù)據(jù)變?yōu)镕FH,。擦除操作與寫操作類似,,在此不再贅述。
結(jié) 語
本文介紹的M25P16與PIC16F877A的接口已應(yīng)用于自來水流量數(shù)據(jù)采集的本地存儲中,。運行穩(wěn)定可靠,未發(fā)現(xiàn)數(shù)據(jù)丟失現(xiàn)象,,對其他應(yīng)用有一定的參考價值,。