您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
串行外圍總線 (SPI)
N76E003系列提供支持高速串行通信的SPI模塊。SPI 為微控制與外設(shè) EEPROM, LCD 驅(qū)動(dòng), D/A 轉(zhuǎn)換之間提供
全雙工、高速、同步傳輸?shù)目偩?商峁┲鳈C(jī)從機(jī)模式傳輸,速度可達(dá)到時(shí)鐘頻率FSYS/2,支持傳輸完成標(biāo)志位
和“寫”沖突標(biāo)志位。在多主機(jī)系統(tǒng)中,SPI 支持主機(jī)模式錯(cuò)誤用以防止主機(jī)沖突。
圖14-1展示了SPI的簡單體系結(jié)構(gòu)。SPI的主要模塊有SPI控制寄存器,SPI狀態(tài)邏輯,波特率控制和管腳邏輯控
制。為了傳送數(shù)據(jù)和接收數(shù)據(jù),SPI 提供了移位寄存器和讀數(shù)據(jù)緩沖器。因?yàn)闊o論傳送數(shù)據(jù)或是接收數(shù)據(jù)都是雙
緩存,所以傳輸端時(shí),在前一個(gè)數(shù)據(jù)發(fā)送完成前,也可以寫入下一筆把數(shù)據(jù)。接收端能讀取讀數(shù)據(jù)緩存,在移位寄
存器接收第二個(gè)數(shù)據(jù)時(shí),同時(shí)前一個(gè)接收的數(shù)據(jù)將被傳送到讀數(shù)據(jù)緩存。
SPI 接口有四個(gè)管腳,分別是主進(jìn)/從出(MISO),主出/從進(jìn)(MOSI),移位時(shí)鐘(SPCLK), 和從機(jī)選擇( SS )。
MOSI腳用于傳輸主機(jī)到從機(jī)的8位數(shù)據(jù),所以MOSI是一個(gè)主機(jī)設(shè)備的輸出引腳,從機(jī)設(shè)備的輸入引腳。相應(yīng)
的,MISO用于接收從機(jī)到主機(jī)的串行數(shù)據(jù)。
SPCLK引腳為主機(jī)模式下的時(shí)鐘輸出,從機(jī)的輸入時(shí)鐘。移位時(shí)鐘用于MOSI和MISO腳之間數(shù)據(jù)傳輸?shù)耐綍r(shí)
鐘。主機(jī)模式發(fā)送8個(gè)移位時(shí)鐘周期,在總線上交換一個(gè)字節(jié)數(shù)據(jù)。位移時(shí)鐘由主機(jī)輸出,所以一組SPI傳輸系
統(tǒng)上只能有一個(gè)主機(jī)以避免設(shè)備沖突。
從機(jī)設(shè)備通過設(shè)定從機(jī)選擇腳 ( SS )選擇。當(dāng)需要訪問任何從機(jī)時(shí),該從機(jī)的此信號(hào)腳必須保持低。當(dāng)SS 為
高,該從機(jī)訪問將被禁止。若為多從機(jī)模式,在同一時(shí)刻必須保持只有一個(gè)從機(jī)被選定。對(duì)于主機(jī), SS 腳不做
任何用途,可配置為普通端口另做他用。SS可用于多主機(jī)模式下主機(jī)模式錯(cuò)誤偵測(cè)功能
N76E003也提供自動(dòng)激活片選腳功能,通過自動(dòng)觸發(fā)SS來傳輸字節(jié)。
圖 14?2為典型的SPI設(shè)備連接圖。通信總線通過3根信號(hào)線相連, MOSI ~ MOSI, MISO ~ MISO, 和 SPCLK ~
SPCLK。主機(jī)通過一個(gè)并口的4個(gè)管腳來控制4個(gè) ? 腳,從而實(shí)現(xiàn)每個(gè) ? 線分別控制每個(gè)從機(jī)。MCU1 和 MCU2
可以任意定義為主機(jī)或從機(jī)模式。SS需配置為主機(jī)模式偵測(cè)功能避免多主機(jī)沖突。
圖 14?3表示SPI 模塊單主機(jī)/從機(jī)互連簡圖。在傳輸時(shí),主機(jī)通過MOSI線向從機(jī)發(fā)送數(shù)據(jù)。同時(shí),主機(jī)也通過MISO線由從機(jī)接收數(shù)據(jù)。此時(shí)主機(jī)和從機(jī)的兩個(gè)移位寄存器可被視為一個(gè)16位的循環(huán)移位寄存器。因此,當(dāng)主機(jī)向從機(jī)發(fā)送數(shù)據(jù)時(shí),從機(jī)數(shù)據(jù)也同時(shí)推向主機(jī)。這樣通過兩mcu的SPI移位寄存器,就完成了交換數(shù)據(jù)。
默認(rèn)情況下,SPI先發(fā)送MSB 。當(dāng)LSBFE (SPCR.5) 置1,SPI首先發(fā)送LSB,該位不會(huì)影響寄存器內(nèi)MSB/LSB的排列順序。注,下述全部是基于 LSBFE為0的情況,MSB 首先被發(fā)送和接收?刂萍拇嫫 (SPCR), SPI 狀態(tài)寄存器 (SPSR), SPI 數(shù)據(jù)寄存器 (SPDR) 這三個(gè)寄存器用于SPI傳輸。這些寄存器提供控制,狀態(tài)檢測(cè),數(shù)據(jù)存儲(chǔ)以及時(shí)鐘發(fā)生設(shè)置。下面描述SPI寄存器的相關(guān)功能。
主機(jī)模式
MSTR (SPCR.4)位置1,SPI工作在主機(jī)模式。整個(gè)SPI系統(tǒng)中只允許一個(gè)主機(jī)啟動(dòng)傳輸。每次傳輸總是由主機(jī)發(fā)起,對(duì)主機(jī)SPDR寄存器的寫開始傳送。在SPCLK控制下在MOSI管腳傳送數(shù)據(jù)。同時(shí),MISO管腳接收數(shù)據(jù)。在8位數(shù)據(jù)傳輸完畢后,SPIF (SPSR.7)由硬件自動(dòng)置位以示完成一個(gè)字節(jié)數(shù)據(jù)傳輸。同時(shí)接收到的數(shù)據(jù)也會(huì)傳送到SPDR。用戶可以從SPDR讀出數(shù)據(jù),并清除SPIF。14.2.2 從機(jī)模式
設(shè)定MSTR為0,SPI將工作在從機(jī)模式。當(dāng)作為從機(jī)模式時(shí),SPCLK管腳變?yōu)檩斎肽_,它將作為時(shí)鐘輸入被另外一個(gè)主機(jī)SPI設(shè)備的輸出時(shí)鐘控制, SS管腳也變?yōu)檩斎肽_。當(dāng)從機(jī)設(shè)備的SS 管腳不為低時(shí),主機(jī)設(shè)備不能與從機(jī)交換數(shù)據(jù)。在數(shù)據(jù)傳輸開始前和數(shù)據(jù)傳輸完成前,SS 管腳都需要保持低電平狀態(tài)。如果SS 變?yōu)楦唠娖剑?/em>SPI將被迫進(jìn)入閑置狀態(tài)。如果SS 管腳在傳輸?shù)倪^程被置高,那么傳輸將被取消,接收移位緩存區(qū)里剩下的位數(shù)將變高,同時(shí)也將進(jìn)入閑置狀態(tài)。
在從機(jī)模式下,數(shù)據(jù)通過MOSI管腳從主機(jī)向從機(jī)傳輸,通過MISO管腳從從機(jī)向主機(jī)傳輸。通過主機(jī)SPCLK的時(shí)鐘控制,數(shù)據(jù)進(jìn)入位移寄存器。在移位寄存器接收到一個(gè)字節(jié)后,數(shù)據(jù)將移到讀數(shù)據(jù)緩存,同時(shí)SPIF置1。對(duì)SPDR的讀操作實(shí)際上就是對(duì)讀緩沖器的一次讀操作。為了防止緩沖器溢出或因溢出導(dǎo)致數(shù)據(jù)丟失,從設(shè)備必須在數(shù)據(jù)第二次從移位寄存器向讀緩沖器傳送前,把數(shù)據(jù)從SPDR讀出和把SPIF清零。
時(shí)鐘格式和數(shù)據(jù)傳輸
為了適應(yīng)各種各樣的同步串行外設(shè),SPI提供時(shí)鐘極性位CPOL(SPCR.3)和時(shí)鐘相位位CPHA(SPCR.2)寄存器用以控制。如圖14?4.所示,CPOL和CPHA組合出四種不同的時(shí)鐘格式。 CPOL 位表示空閑狀態(tài)時(shí)SPCLK腳電平。 CPHA位定義表示是MOSI和MISO上時(shí)鐘的哪個(gè)邊沿用來采樣。在同一系統(tǒng)上的主從設(shè)備中,CPOL和CPHA的配置應(yīng)該是相同的。傳輸不同的數(shù)據(jù)格式,將產(chǎn)生隨機(jī)錯(cuò)誤結(jié)果。
在SPI傳輸中,總是由主機(jī)啟動(dòng)傳輸。如果SPI被選定作為主模機(jī)式(MSTR = 1)并且打開傳輸(SPIEN=1),對(duì)主機(jī)的SPI數(shù)據(jù)寄存器(SPDR)寫入數(shù)據(jù)將啟動(dòng)SPI時(shí)鐘和數(shù)據(jù)傳輸。傳出一個(gè)字節(jié)的同時(shí)會(huì)接收一個(gè)字節(jié)的內(nèi)容,此后SPI時(shí)鐘停止,主機(jī)和從機(jī)的SPIF(SPSR.7)同時(shí)被置1 。如果SPI中斷使能位ESPI(EIE.0)設(shè)置為1,全局中斷使能(EA= 1),將執(zhí)行SPI的(ISR)中斷服務(wù)程序。
關(guān)于從機(jī)模式下, SS 信號(hào)需要注意。如圖14?4.所示,CPHA=0時(shí), SPCLK第一個(gè)邊沿為MSB的采樣點(diǎn)(LSBFE= 0,MSB優(yōu)先發(fā)送為例)。因此,從機(jī)必須在SPCLK第一個(gè)采樣邊沿出現(xiàn)之前先把MSB傳出。SS 的下降沿可用于準(zhǔn)備MISO的MSB。因此,每次成功串行傳輸一個(gè)字節(jié)后, SS 引腳必須切換先高然后低。此外,如果從機(jī)將數(shù)據(jù)寫入SPI數(shù)據(jù)寄存器(SPDR)時(shí),如果SS為低電位,則會(huì)發(fā)生寫沖突錯(cuò)誤。當(dāng)CPHA = 1,采樣邊沿位于SPCLK時(shí)鐘的第二個(gè)邊沿。從機(jī)使用的第一個(gè)SPCLK時(shí)鐘轉(zhuǎn)移的MSB,而不是SS的下降沿。因此,在每次成功傳輸時(shí)SS 可以始終保持低電位保持低之間的轉(zhuǎn)移。此格式更適合單主機(jī)單從機(jī)的結(jié)構(gòu)使用。CPHA =1模式,從機(jī)的SS可以不連接在SPI系統(tǒng)中,直接接地。
在SPI傳輸使能(SPIEN = 1)前,必須先對(duì)SPI傳輸進(jìn)行配置,否則傳輸過程中對(duì)LSBFE, MSTR, CPOL, CPHA及 SPR[1:0] 的任一更改,將會(huì)停止SPI傳輸并強(qiáng)迫總線進(jìn)入空閑模式。所以在任何配置位更改前,請(qǐng)先關(guān)閉SPIEN使能位。
從機(jī)選擇引腳SS配置
N76E003SPI提供靈活的SS 配置用于不同系統(tǒng)。當(dāng)作為從機(jī)時(shí), SS 始終定義為選擇輸入腳。當(dāng)作為主機(jī)時(shí),
SS有三種不同的功能定義,可以通過DISMODF (SPSR.3) 和SSOE (SPCR.7)來配置。默認(rèn)情況DISMODF=0,
故障偵測(cè)功能打開, SS 配置為輸入腳并檢測(cè)是否發(fā)生故障。反之,如果DISMODF=1,故障偵測(cè)功能關(guān)閉,
SSOE寄存器定義控制SS 管腳。當(dāng)SSOE=1,從機(jī)選擇信號(hào)自動(dòng)生成,主機(jī)的SS 管腳直接與從機(jī)的SS 腳連
接,當(dāng)選擇外部從機(jī)進(jìn)行傳輸時(shí)SS 自動(dòng)拉低,當(dāng)進(jìn)入閑置狀態(tài)或者沒有選擇從機(jī)時(shí),自動(dòng)拉高。當(dāng)SSOE=0且
DISMODF=1時(shí),SS不再用作SPI管腳,而完全配置為普通端口狀態(tài)。
模式故障偵測(cè)
在一個(gè)SPI網(wǎng)絡(luò)中,當(dāng)不止一個(gè)設(shè)備有可能成為主機(jī)時(shí),為減少數(shù)據(jù)傳輸錯(cuò)誤,模式故障偵測(cè)功能是非常有用
的。當(dāng)一個(gè)主機(jī)打開模式故障偵測(cè)并發(fā)現(xiàn)SS 由其它設(shè)備拉低,配置詳見 表14-1.從機(jī)選擇腳定義,說明系統(tǒng)上
有一個(gè)從機(jī)試圖尋找主機(jī)地址并把主機(jī)認(rèn)為從機(jī)。此時(shí),硬件會(huì)自動(dòng)將SPCR 的 MSTR 和SPIEN清除,從而SPI
功能關(guān)閉,并使能錯(cuò)誤偵測(cè)標(biāo)志MODF (SPSR.4)置1 ,如果之前已打開中斷ESPI (EIE .6) 和EA置1,則會(huì)進(jìn)入
中斷向量。
寫沖突錯(cuò)誤
SPI在發(fā)送方向上是單緩存,但在接收上是雙緩存。除非前一個(gè)數(shù)據(jù)傳輸完,否則新的數(shù)據(jù)不能寫入移位寄存
器。當(dāng)正在進(jìn)行一次傳送時(shí),如果設(shè)備同時(shí)又寫數(shù)據(jù)到SPDR,將發(fā)生寫沖突錯(cuò)誤。發(fā)送數(shù)據(jù)時(shí)由于SPDR不是
一個(gè)雙緩存,任何寫入SPDR數(shù)據(jù)將直接寫入SPI的移位寄存器。一旦發(fā)生一個(gè)寫沖突錯(cuò)誤,WCOL(SPSR.6)會(huì)
被硬件置1指示發(fā)生一個(gè)寫沖突。這種情況下,當(dāng)前的傳輸繼續(xù)不停,然而引起寫沖突的新數(shù)據(jù)將丟失。盡管
SPI邏輯可以在主機(jī)和從機(jī)之間進(jìn)行寫沖突檢測(cè),但寫沖突通常會(huì)是一個(gè)從機(jī)錯(cuò)誤,原因是當(dāng)主機(jī)開始一次傳送
時(shí),從機(jī)是無法預(yù)知。在從機(jī)接收過程中,寫SPDR也將產(chǎn)生寫沖突錯(cuò)誤。WCOL標(biāo)志用軟件清除。
移出錯(cuò)誤
對(duì)于接收數(shù)據(jù),SPI是雙緩存的。接收到的數(shù)據(jù)移入到一個(gè)讀數(shù)據(jù)緩存中,同時(shí)能接收第二個(gè)數(shù)據(jù)。然而,在下
一個(gè)數(shù)據(jù)移入之前,必須確保已從SPDR中讀取出已接收數(shù)據(jù)。在下一個(gè)數(shù)據(jù)被移入前,要把前一個(gè)數(shù)據(jù)從讀緩
沖區(qū)內(nèi)讀出,并且清除SPIF,這樣的才不會(huì)產(chǎn)生移出錯(cuò)誤,反之,將產(chǎn)生移出錯(cuò)誤。這種情況下,第二個(gè)字節(jié)
的數(shù)據(jù)不會(huì)正常移入讀數(shù)據(jù)緩存,緩存區(qū)內(nèi)仍保留有前一個(gè)數(shù)據(jù)。當(dāng)發(fā)生移出錯(cuò)誤時(shí),SPIOVF (SPSR.5)會(huì)被
硬件置1。如果中斷打開,會(huì)進(jìn)入中斷請(qǐng)求。Figure 14?7.表示接收數(shù)據(jù)與移出錯(cuò)誤之間的關(guān)系。
SPI 中斷
SPI中斷狀態(tài)標(biāo)志包括SPIF、MODF 和 SPIOVF,用于產(chǎn)生SPI事件中斷請(qǐng)求。這些位都放在SPSR寄存器中。
當(dāng)有外部數(shù)據(jù)傳入SPDR或自身完成數(shù)據(jù)傳輸后,SPIF標(biāo)志將被置位。MODF置1時(shí),表示SS 進(jìn)入模式錯(cuò)誤狀
態(tài),SPIOVF表示接收發(fā)生數(shù)據(jù)移出錯(cuò)誤。當(dāng)SPI中斷打開時(shí)(ESPI (EIE.6) 和EA置1),當(dāng)這3個(gè)標(biāo)志中的任意
一個(gè)置1,CPU會(huì)執(zhí)行SPI中斷服務(wù)程序。用戶若需要了解是由何種標(biāo)志引起中斷,必須檢查相應(yīng)的標(biāo)志位。這
三個(gè)標(biāo)志必須由用戶軟件清除。
/*---------------------------------------------------------------------------------------------------------*/ /* */ /* Copyright(c) 2015 Nuvoton Technology Corp. All rights reserved. */ /* */ /*---------------------------------------------------------------------------------------------------------*/ //*********************************************************************************************************** // Nuvoton Technoledge Corp. // Website: http://www.nuvoton.com // E-Mail : MicroC-8bit@nuvoton.com // Date : Apr/21/2015 //*********************************************************************************************************** //*********************************************************************************************************** // File Function: N76E885 Access SPI Flash (W25Q16BV) demo code //*********************************************************************************************************** #include <stdio.h> #include <intrins.h> #include <string.h> #include "N76E885.h" #include "Version.h" #include "Typedef.h" #include "Define.h" #include "SFR_Macro.h" #include "Common.h" #include "Delay.h" /* //-------- <<< Use Configuration Wizard in Context Menu >>> ------------ // //<e0> System Clock Source Configuration // <o1> System Clock Source Selection // <0=> 2~25MHz XTAL // <1=> 32.768KHz XTAL // <2=> 22.1184MHz Internal // <3=> 10KHz Internal // <4=> OSC-In External //</e> // //<e2> Clock Divider Configuration // <o3.0..7> System Clock Source Devider <1-255> // <i> Fsys = (System Clock Source) / (2 * Devider) //</e> // // <o4> SPI Clock Rate Selection (11.0592MHz System Clock) // <0=> 2.7648MHz, Fosc/4 // <1=> 1.3824MHz, Fosc/8 // <2=> 0.6912MHz, Fosc/16 // <3=> 0.3456MHz, Fosc/32 //-------- <<< end of configuration section >>> ------------------------------ */ #define SYS_CLK_EN 0 #define SYS_SEL 2 #define SYS_DIV_EN 0 //0: Fsys=Fosc, 1: Fsys = Fosc/(2*CKDIV) #define SYS_DIV 1 #define SPI_CLOCK 0 #define SS_PIN P04 #define WRITE_ENABLE 0x06 #define WRITE_DISABLE 0x04 #define READ_DATA 0x03 #define PAGE_PROGRAM 0x02 #define CHIP_ERASE 0xC7 #define READ_STATUS1 0x05 bit BIT_TMP; //----------------------------------------------------------------------------------------------------------- void SPI_Error(void) { printf ("\n* SPI Error, please check the connection between MCU and SPI Flash"); while(1); } //----------------------------------------------------------------------------------------------------------- void SPI_Initial(void) { #if SPI_CLOCK == 0 clr_SPR1; clr_SPR0; #elif SPI_CLOCK == 1 clr_SPR1; set_SPR0; #elif SPI_CLOCK == 2 set_SPR1; clr_SPR0; #elif SPI_CLOCK == 3 set_SPR1; set_SPR0; #endif /* /SS General purpose I/O ( No Mode Fault ) */ set_DISMODF; clr_SSOE; /* SPI in Master mode */ set_MSTR; /* MSB first */ clr_LSBFE; clr_CPOL; clr_CPHA; /* Enable SPI function */ set_SPIEN; } //----------------------------------------------------------------------------------------------------------- void Read_MID_DID(UINT8 *pu8MID,UINT8 *pu8DID) { SS_PIN = 0; SPDR = 0x90; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0xFF; while((SPSR&0x80)==0x00); *pu8MID = SPDR; clr_SPIF; SPDR = 0xFF; while((SPSR&0x80)==0x00); *pu8DID = SPDR; clr_SPIF; SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Write_Enable(void) { SS_PIN = 0; SPDR = WRITE_ENABLE; while((SPSR&0x80)==0x00); clr_SPIF; SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Write_Disable(void) { SS_PIN = 0; SPDR = WRITE_DISABLE; while((SPSR&0x80)==0x00); clr_SPIF; SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Chip_Erase(void) { SS_PIN = 0; SPDR = CHIP_ERASE; while((SPSR&0x80)==0x00); clr_SPIF; SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Read_Status(void) { UINT8 u8Status; SS_PIN = 0; do{ SPDR = READ_STATUS1; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0xFF; while((SPSR&0x80)==0x00); u8Status = SPDR; clr_SPIF; }while((u8Status&0x01)==0x01); SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Erase_Verify(void) { UINT16 u16CNT; UINT8 u8Data; SS_PIN = 0; SPDR = READ_DATA; while((SPSR&0x80)==0x00); clr_SPIF; /* 24-bit Address */ SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; for(u16CNT=0;u16CNT<256;u16CNT++) { SPDR = 0x00; while((SPSR&0x80)==0x00); u8Data = SPDR; clr_SPIF; if(u8Data != 0xFF) { SPI_Error(); } } SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Program(void) { UINT16 u16CNT; SS_PIN = 0; SPDR = PAGE_PROGRAM; while((SPSR&0x80)==0x00); clr_SPIF; /* 24-bit Address */ SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; /* Send the data to SPI_Flash buffer */ for(u16CNT=0;u16CNT<256;u16CNT++) { SPDR = (UINT8)u16CNT; while((SPSR&0x80)==0x00); clr_SPIF; } SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void Flash_Program_Verify(void) { UINT16 u16CNT; UINT8 u8Data; SS_PIN = 0; SPDR = READ_DATA; while((SPSR&0x80)==0x00); clr_SPIF; /* 24-bit Address */ SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; SPDR = 0x00; while((SPSR&0x80)==0x00); clr_SPIF; for(u16CNT=0;u16CNT<256;u16CNT++) { SPDR = 0x00; while((SPSR&0x80)==0x00); u8Data = SPDR; clr_SPIF; if(u8Data != (UINT8)u16CNT) { SPI_Error(); } } SS_PIN = 1; } //----------------------------------------------------------------------------------------------------------- void main(void) { UINT8 u8MID,u8DID; /* Note MCU power on system clock is HIRC (22.1184MHz), so Fsys = 22.1184MHz */ Set_All_GPIO_Quasi_Mode(); InitialUART0_Timer1_Type1(9600); /* 9600 Baud Rate*/ Show_FW_Version_Number_To_PC(); printf ("\n*==================================================================="); printf ("\n* Name: N76E885 SPI Demo Code, MCU <--> W25Q16BV"); printf ("\n*===================================================================\n"); /* Change system closk source */ #if SYS_CLK_EN == 1 #if SYS_SEL == 0 System_Clock_Select(E_HXTEN); //Fosc = 2~25MHz XTAL #elif SYS_SEL == 1 System_Clock_Select(E_LXTEN); //Fosc = 32.768KHz XTAL #elif SYS_SEL == 2 System_Clock_Select(E_HIRCEN); //Fosc = 22.1184MHz Internal RC #elif SYS_SEL == 3 System_Clock_Select(E_LIRCEN); //Fosc = 10KHz Internal RC #elif SYS_SEL == 4 System_Clock_Select(E_OSCEN); //Fosc = OSC-In External OSC #endif #endif #if SYS_DIV_EN == 1 CKDIV = SYS_DIV; //Fsys = Fosc / (2* CLKDIV) = Fcpu #endif SPI_Initial(); Read_MID_DID(&u8MID,&u8DID); printf ("\n* MID value of W25Q16BV = 0x%X",(UINT16)u8MID); printf ("\n* DID value of W25Q16BV = 0x%X",(UINT16)u8DID); if((u8MID != 0xEF)&&(u8DID != 0x17)) { SPI_Error(); } /* The procedure of SPI Flash at erase mode */ Flash_Write_Enable(); Flash_Chip_Erase(); Flash_Read_Status(); Flash_Write_Disable(); Flash_Erase_Verify(); /* The procedure of SPI Flash at program mode */ Flash_Write_Enable(); Flash_Program(); Flash_Read_Status(); Flash_Write_Disable(); /* Program verify */ Flash_Program_Verify(); printf("\nFinished the SPI Demo Code and test pass!!!\n"); while(1); } //-----------------------------------------------------------------------------------------------------------
具體講解 容后再說
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08