stm32f429固件庫之SPI讀寫FLASH
SPI——串行外設(shè)總線(Seriel Peripheral Interface),全雙工通信,4條線:1、SCK(Seriel Clock,時(shí)鐘信號(hào)線——用于同步通信),由主機(jī)產(chǎn)生,兩個(gè)設(shè)備通信時(shí),速率受限于低速設(shè)備;2、SS(也稱NSS、CS,設(shè)備選擇信號(hào)線,也是片選信號(hào)線),每個(gè)設(shè)備通過一條獨(dú)有的CS線連接到主機(jī),當(dāng)CS拉低時(shí),表示被選中;3、MISO(Master Input Slave Output,主機(jī)輸入從機(jī)輸出);4、MOSI(Master Input Slave Output,主機(jī)輸出從機(jī)輸入)。SCK、MISO、MOSI這三條線各個(gè)從機(jī)共用,CS線為每個(gè)從機(jī)獨(dú)有連接主機(jī)。
SPI協(xié)議層:通信的起始信號(hào):CS由高變低;
通信的結(jié)束信號(hào):CS由低變高;
數(shù)據(jù)的有效性:在SCK每個(gè)時(shí)鐘周期發(fā)送一位數(shù)據(jù),數(shù)據(jù)輸入輸出同時(shí)進(jìn)行,在什么時(shí)候采樣以及時(shí)鐘信號(hào)在通信開始前的狀態(tài)由SPI控制寄存器1位0CPHA(Clock Phase)位1CPOL(Clock Polarity)決定,CPOL和CPHA不同組合形成4種模式,00,01 ,10,11,在FLASH芯片W25Q128中支持模式0和模式3。
之后感覺重要的就是FLASH芯片的Instructions了,在文檔中有命令表。
然后復(fù)習(xí)一下思路:1、初始化——初始化GPIO引腳,初始化SPI結(jié)構(gòu)體,打開引腳和外設(shè)時(shí)鐘,使能SPI。這塊FLASH芯片是先接收MSB的,所以初始化里設(shè)置為MSB先行。
2、在讀取芯片ID——先寫一個(gè)讀寫函數(shù)uint8_t Read_Write_Byte(uint8_t data)。在發(fā)送數(shù)據(jù)之前,先通過SPI_GetFlagStatus(...)判斷SPI狀態(tài)寄存器位1-TXE,等待發(fā)送緩沖區(qū)為空,再調(diào)用SPI_I2S_SendData(...)發(fā)送一個(gè)8位數(shù)據(jù),在通過SPI_GetFlagStatus(...)判斷SPI狀態(tài)寄存器位0-RXNE,等待接收緩沖區(qū)不為空,開始接收一個(gè)8位數(shù)據(jù),返回讀到的值。在初始化中設(shè)置發(fā)送接收數(shù)據(jù)長度。關(guān)于這邊為什么在一個(gè)函數(shù)中同時(shí)發(fā)送接收,說是不發(fā)送數(shù)據(jù)時(shí)鐘線不開,接收也無效?!癝PI設(shè)備間的數(shù)據(jù)傳輸又被稱為數(shù)據(jù)交換,SPI協(xié)議規(guī)定SPI設(shè)備在通訊中不能僅充當(dāng)一個(gè)“發(fā)送者”或“接受者”,在每個(gè)CLOCK周期內(nèi),SPI設(shè)備都會(huì)發(fā)送并接收一個(gè)bit大小的數(shù)據(jù),相當(dāng)于數(shù)據(jù)交換”(百度文庫)。
3、讀取芯片ID——拉高CS,用讀寫函數(shù)發(fā)送讀取ID指令9FH,之后,用讀寫函數(shù)發(fā)送一個(gè)DUMMY(任意數(shù)據(jù))并用一個(gè)8位變量接收返回值即(MF7-MF0),再用兩個(gè)變量接收(ID15-ID8)和(ID7-ID0),將三個(gè)變量整合到一個(gè)32位數(shù)據(jù)作為返回值返回。
4.1、寫使能——拉高CS,發(fā)送Write Enable指令06H,拉低CS
4.2、擦除存儲(chǔ)區(qū)域——在我們下載程序,寫入之前,得先擦除,擦除之前,先發(fā)送寫使能。FLASH有個(gè)特性,只能將0寫成1,不能將1寫成0,所以擦除后的FLASH全為1。這塊16MByte的FLASH芯片,由256個(gè)Block(塊,64k)組成,每個(gè)塊由16個(gè)Sector(扇區(qū),4k)組成,所以有整片擦除、扇區(qū)擦除、塊擦除。擦除扇區(qū)相當(dāng)于向存儲(chǔ)器寫1,所以在擦除扇區(qū)之前要先發(fā)送寫使能命令。
5、讀取數(shù)據(jù)——讀取數(shù)據(jù)之前得先等待芯片處理完內(nèi)部時(shí)序,即總線空閑,等待芯片狀態(tài)寄存器位0-BUSY為0。拉高CS,發(fā)送Read Data 指令03H,分3次發(fā)送讀的起始地址,開始讀,傳入一個(gè)數(shù)組指針,將讀到的值存入一個(gè)數(shù)組,通過串口顯示出來,地址自加1。通過判斷讀出的數(shù)據(jù)是否全為1檢驗(yàn)程序?qū)﹀e(cuò)。
6、寫數(shù)據(jù)——等待芯片處理時(shí)序,即等待總線空閑,發(fā)送寫使能,發(fā)送Page Program指令02H,分三次發(fā)送要寫入的地址,之后發(fā)送要寫入的數(shù)據(jù),可以通過數(shù)組指針寫入多個(gè)數(shù)據(jù),但是不得多于256個(gè),芯片規(guī)定??梢酝ㄟ^循環(huán)寫入超過256個(gè)數(shù)據(jù)
7、通過讀取數(shù)據(jù)將之顯示出來與寫入數(shù)據(jù)比較,檢驗(yàn)程序是否正確。
8、掉電模式——可用可不用,進(jìn)入掉電模式之后只有Release Power_down或者是重新上電才能與芯片通信。,拉高CS,通過簡(jiǎn)單的發(fā)送Power down指令B9H,拉低CS,就能使芯片進(jìn)入掉電模式,在程序最結(jié)束循環(huán)前加入掉電函數(shù),實(shí)驗(yàn)現(xiàn)象就是在第二次下載時(shí)讀不到ID,當(dāng)然在沒有重新上電的情況下。如果我們之前用指令A(yù)BH讀取ID,那么就沒有進(jìn)入掉電模式的實(shí)驗(yàn)現(xiàn)象了。
來自學(xué)習(xí)野火教程,純個(gè)人理解。