娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年11月03日(星期日)

2021年11月03日 | STM32F103ZET6 — SPI

發布者:電子思維 來源: eefocus關鍵字:STM32F103ZET6  SPI  時鐘 手機看文章 掃描二維碼
隨時隨地手機看文章

簡介

SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設備接口。是Motorola首先在其MC68HCXX系列處理器上定義的。SPI接口主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器數字信號解碼器之間。SPI,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節約了芯片的管腳,同時為PCB的布局上節省空間,提供方便,正是出于這種簡單易用的特性,現在越來越多的芯片集成了這種通信協議


SPI 具有信號線少,協議簡單,數據率高等優點。數據傳送速率達幾MB/s


Pin 腳介紹

標準的 SPI 使用 4 Pin 進行數據傳送:


(1)MOSI – 主器設備數據輸出,從器件數據輸入


(2)MISO – 主器設備件數據輸入,從器件數據輸出


(3)SCLK – 時鐘信號,由主器件產生, 最大為fPCLK/2,從模式頻率最大為fCPU/2


(4)NSS – 從器件使能信號,由主器件控制,有的 IC 會標注為 CS (Chip select)

數據時在 CLK 時鐘的驅動下,在數據線上按照一個 bit 一個 bit 的進行傳送,數據可以在時鐘的上升沿或者下降沿改變(或者采樣)。


SPI 傳輸的缺點是,沒有數據完整性校驗,也沒有流控機制。


既然稱 SPI 為總線,則 SPI 就可以支持多個設備相連接,通過 CS 片選信號來指定期望通訊的設備。(多機通訊)


SPI 模式

SPI 通訊有 4 中不同的通訊模式,通信雙方需要配置成為一樣的模式,才能夠進行正常的數據傳輸,這里有兩個概念:


CPOL:時鐘極性


CPHA:時鐘相位


CPOL:(時鐘極性)控制在沒有數據傳輸時,SPI 時鐘的空閑狀態電平。即,定義了總線空閑的工作狀態(注意,和 UART 不同,SPI 是通過 CLK 的狀態來表征當前的總線狀態,即不發生任何數據交互的時候,時鐘信號總是沒有進行翻轉的)


CPOL=0,表示當SCLK=0時處于空閑態


CPOL=1,表示當SCLK=1時處于空閑態


CPHA:(時鐘相位)是用來配置數據采樣是在第幾個邊沿。


CPHA=0,表示數據采樣是在第1個邊沿


CPHA=1,表示數據采樣是在第2個邊沿


所以 CPOL 和 CPHA 的不同組合,成為了 SPI 的四種傳輸模式:


SPI Mode

image.png

四種傳輸模式,定義了不同時刻的總線啟動,以及數據發送和采樣時間:


CPOL=0,CPHA=0:此時空閑態時,SCLK處于低電平,數據采樣是在第1個邊沿,也就是 SCLK 由低電平到高電平的跳變,所以數據采樣是在上升沿,數據發送是在下降沿。


CPOL=0,CPHA=1:此時空閑態時,SCLK處于低電平,數據發送是在第1個邊沿,也就是 SCLK 由低電平到高電平的跳變,所以數據采樣是在下降沿,數據發送是在上升沿。


CPOL=1,CPHA=0:此時空閑態時,SCLK處于高電平,數據采集是在第1個邊沿,也就是 SCLK 由高電平到低電平的跳變,所以數據采集是在下降沿,數據發送是在上升沿。


CPOL=1,CPHA=1:此時空閑態時,SCLK處于高電平,數據發送是在第1個邊沿,也就是 SCLK 由高電平到低電平的跳變,所以數據采集是在上升沿,數據發送是在下降沿。


對應到波形上:

STM32 SPI 特性

STM32 上支持 3 路 SPI:


可以支持全雙工的通信

支持硬件 CRC

可編程的數據順序,MSB在前或LSB在前

主模式和從模式的快速通信

可編程的時鐘極性和相位(CPOL,CPHA)

可觸發中斷的專用發送和接收標志

可觸發中斷的主模式故障、過載以及CRC錯誤標志

支持DMA功能的1字節發送和接收緩沖器:產生發送和接受請求


SPI 時鐘

單板上使用 SPI2 進行 SPI FLASH 的操作,使用的是 APB1 的時鐘,最大配置為 36MHz。


硬件連接

硬件上,通過單板的 SPI2 引腳,連接到外部的 SPI FLASH (W25Q64)

所以,在配置的時候,需要針對 SPI2 進行配置。


SPI Flash 簡介

硬件單板上,連接的是 WinBond 的 W25Q64BV 的 SPI Flash,此款 Flash 的特性如下:


大小:64M-bit / 8M-byte

頁 : 256B

支持 80MHz 的時鐘

支持扇區擦除:Sector Erase (4K-bytes)

支持塊擦除:Block Erase (32K and 64K-bytes)

支持頁寫入:0~256-bytes

軟件/硬件寫保護

由于暫時不需要硬件寫保護和Hold功能,故,直接將 WP和HOLD引腳接到 VCC(3.3V)


(此款SPI FLASH 還支持雙線和4線 QSPI 的讀寫,由于 STM32 不支持,所以不在多說)


根據 W25Q64BV 的 Datasheet 描述,在操作這塊 FLASH 的時候,需要配置主機為:


SPI Mode 0 或者 Mode 3

MSB 先傳輸

故,在 SPI2 配置的時候,需要進行對應的配置,才能夠繼續正常數據通信


W25Q64BV 存在兩個寄存器可以被訪問,為 Status Register-1 和 Status Register-2,其中描述的關于 Write-Protect 的部分,暫時不管。與讀寫相關的就是 BUSY 位了,因為對 SPI Flash 編程后,Flash 需要內部的 cylce 進行數據的寫入,內部program的時候會將 BUSY 置成 1,寫入完成后,會將 BUSY 位置 0,故,每次對 Flash 進行寫(包括擦除)之前,均要進行 BUSY 位的判斷。

好啦,現在就開始按照 DateSheet 進行配置我們的 STM32 了。


STM32 SPI2 配置

配置過程主要分為兩步:GPIO 的配置,SPI2 的配置(如原理圖所示,PB_12 的 GPIO 用于了 CS 片選,我們需要將其配置成為輸出的 GPIO,拉低的時候,選中 Flash,拉高的時候釋放 Flash 信號)


1. 開啟 GPIO B 組的時鐘


2. 開啟 SPI2 的時鐘


3. 按照 STM32 手冊,配置 SCK 、MOSI 和 NSS 為復用推挽輸出、MISO為浮空輸入(有的代碼將 MISO 配置成為的輸出,雖然也可以運行,不過,您不覺得別扭么?還是遵循 Spec 的來吧)。同時將 GPIO_B _12配置為輸出(CS信號)

4. 配置 SPI2 為全雙工模式


5. SPI2 為 Master


6. SPI2 運行在 MODE3(按照 W25Q64BV 的 Timing 要求 )


7. SPI2 NSS 為軟件模式(根本沒用)


8. 預分頻系數為 4 分頻(APB1 為 36M,則 SPI2 的 SCK 為 9 MHz)


9. SPI2 傳輸 MSB(按照 W25Q64BV 的 Timing 要求)


10. 不啟用 CRC


11. 開啟 SPI 功能


此刻 SPI 的配置就基本完成了。接下來就是 按照 W25Q64BV 的 Timing 要求,寫 FLASH 驅動咯.....


#define SK_SPI_FLASH_CS_HIGH()           GPIO_SetBits(GPIOB, GPIO_Pin_12)

#define SK_SPI_FLASH_CS_LOW()            GPIO_ResetBits(GPIOB, GPIO_Pin_12)

 

/*******************************************************************************

* Function Name  : SK_SPIPortInit

* Description    : Configure the I/O port for SPI2.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

static void _SK_SPI2PortInit(void)

{

    GPIO_InitTypeDef stGpioInit;

 

    /*!< Configure pins: SCK */

    stGpioInit.GPIO_Pin = GPIO_Pin_13;

    stGpioInit.GPIO_Speed = GPIO_Speed_50MHz;

    stGpioInit.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &stGpioInit);

 

    /*!< Configure pins: MISO */

    stGpioInit.GPIO_Pin = GPIO_Pin_14;

    stGpioInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOB, &stGpioInit);

 

    /*!< Configure pins: MOSI */

    stGpioInit.GPIO_Pin = GPIO_Pin_15;

    stGpioInit.GPIO_Speed = GPIO_Speed_50MHz;

    stGpioInit.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &stGpioInit);

 

    /*!< Configure pins: CS */

    stGpioInit.GPIO_Pin = GPIO_Pin_12;

    stGpioInit.GPIO_Speed = GPIO_Speed_50MHz;

    stGpioInit.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOB, &stGpioInit);

}

 

/*******************************************************************************

* Function Name  : _SK_SPI2BusInit

* Description    : Configure the SPI2 Bus to adpte the W25Q64 Flash.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

static void _SK_SPI2BusInit(void)

{

    SPI_InitTypeDef  SPI_InitStructure;

 

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // PCLK = 36M, SPI2 CLK = PCLK/4 = 9M

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_CRCPolynomial = 7;

 

    SPI_Init(SPI2, &SPI_InitStructure);

    SPI_Cmd(SPI2, ENABLE);

}

 

/*******************************************************************************

* Function Name  : SK_SPIInit

* Description    : Initializes the peripherals used by the SPI FLASH driver.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void SK_SPIFlashInit(void)

{

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

 

    _SK_SPI2PortInit();

 

    SK_SPI_FLASH_CS_HIGH();

 

    _SK_SPI2BusInit();

}


W25Q64BV Flash 驅動

W25Q64BV 是 Flash 嘛,最主要的就是讀和寫。當然,除了這些,還有擦除功能,讀 ID 等等。不著急,一步一步來,都是套路。


STM32 在進行 SPI 全雙工數據傳輸的時候,在通過 MOSI 寫出去數據后,可以立馬進行 MISO 數據讀取,通過輪詢 TXE 標志來判斷數據已經全部加載到移位寄存器,通過輪詢 RXE 標志來得知本次 MISO 的數據已經全部到賬。


針對  W25Q64BV Flash,Datasheet 中列出了支持的多種不同的命令:

對應上述表格,有不同的 Timing 進行描述,比如:Opcode 為 0x9F 的時候,是讀取一個叫 JEDEC ID 的東西:

可以看到,主機首先將 CS 拉低,然后主機處在 Mode 0 或者 Mode 3 的時候,在 MOSI 信號上輸出 0x9F 的數據(命令),然后接著寫入 Dummy Data (隨便寫點東西),然后再 MISO 信號上就能夠收到 manufacture ID 的信息(為 0xEF),在繼續寫入 Dummy Data,繼續接收,繼續寫入,繼續接收,這樣便可以得到期望的數據了。


獲取 Flash ID 信息

根據上述方式,便可以獲取 ID 信息:


/********************** W25Q64 Flash Command Defination ***********************/

#define SPI_FLASH_PerWritePageSize      256

 

#define W25X_WriteEnable                0x06 

#define W25X_WriteDisable               0x04 

#define W25X_ReadStatusReg_1            0x05

#define W25X_ReadStatusReg_2            0x35 

#define W25X_WriteStatusReg             0x01 

#define W25X_ReadData                   0x03 

#define W25X_FastReadData               0x0B 

#define W25X_FastReadDual               0x3B 

#define W25X_PageProgram                0x02 

#define W25X_64K_BlockErase             0xD8 

#define W25X_32K_BlockErase             0x52 

#define W25X_4K_SectorErase             0x20 

#define W25X_ChipErase                  0xC7 

#define W25X_PowerDown                  0xB9 

#define W25X_ReleasePowerDown           0xAB 

#define W25X_DeviceID                   0xAB 

#define W25X_ManufactDeviceID           0x90 

#define W25X_JedecDeviceID              0x9F 

 

#define Busy_Flag                       0x01  /* Write In Progress (WIP) flag */

#define Dummy_Byte                      0xFF  /* Dummy Data */

 

typedef struct {

    uint8_t manufacturer_id;

    uint8_t memory_type_id;

    uint8_t capacity_id;

    uint8_t device_id;

} W25Q64_ID_t;

 

 

/*******************************************************************************

* Function Name  : SPI_FLASH_SendByte

* Description    : Sends a byte through the SPI interface and return the byte

*                  received from the SPI bus.

* Input          : byte : byte to send.

* Output         : None

* Return         : The value of the received byte.

*******************************************************************************/

static uint8_t SPI_FLASH_SendByte(uint8_t byte)

{

  /* Loop while DR register in not emplty */

  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

 

  /* Send byte through the SPI2 peripheral */

[1] [2] [3]
關鍵字:STM32F103ZET6  SPI  時鐘 引用地址:STM32F103ZET6 — SPI

上一篇:STM32 DMA外設地址的計算問題
下一篇:STM32F103ZET6 — SDIO (Mirco SDCard)

推薦閱讀

?集微網消息(文/Lee)日前,有消息稱,針對當前民營上市公司面臨的股權質押流動性危機,北京市西城區按照“政府引導、市場運作、社會參與”的原則,擬發起設立北京新動力優質企業發展基金,基金目標規模100億元。對此,有投資者在互動平臺上詢問耐威科技公司作為西城區大股東質押比例比較高的公司,有沒有主動尋求國資的支持。如有的話,通過何種途徑來...
10月30日,2019國際服務機器人及特種機器人峰會在北京開幕,峰會上,從中國機械工業聯合會執行副會長、中國機器人產業聯盟執行理事長宋曉剛處獲悉,中國正在研究制定面向2035年的機器人產業發展規劃,近期,在工信部支持下,相關部門已在西南、東北、珠三角、長三角進行了將近兩個月的密集調研,這一機器人發展規劃的一個最重要的內容就是總結“十三五”...
諾基亞(Nokia)公布第三季度凈銷售額為53億歐元(62億美元),同比減少7%;營業利潤為3.5億歐元,營業利潤率增長2個百分點,達到6.6%。 展望未來,諾基亞的總裁兼首席執行官Pekka Lundmark表示,“2021年的財務表現預計將具有挑戰性,意味著公司需要做出更多改變。” 他進一步指出,“我們失去了一個北美大客戶的業務,在這個市場里面臨著利潤率的壓力,因而...
在半導體行業,不僅僅面臨芯片短缺的問題,勞動力和技能同樣面臨不足,半導體人才供應不足不僅僅發生在中國,全球皆是如此。即使在數字時代,制造業也離不開人。然而,需求遠遠超過供應。事實證明,合格的半導體工程師的短缺是該行業增長的系統性制約因素,加劇了全球新冠疫情下的供應鏈問題。半導體勞動力短缺的狀況半導體技能短缺并不是什么新鮮事。 20...

史海拾趣

問答坊 | AI 解惑

sos 緊急求教modbus協議的數據采集系統

[ip]快畢業了,畢業論文是 基于modbus協議的數據采集系統,不知道各位高手們有沒有想要對我這個笨笨知道的地方.謝謝,謝謝,十分感謝.…

查看全部問答∨

使用實時頻譜分析儀進行 EMI診斷

泰克公司方案,用于 EMI診斷…

查看全部問答∨

學習android,團購性價比很高的OK6410 了

淘寶:http://gooogleman.taobao.com/ OK6410 官方報價 860 RMB——團購活動,再下一城,那么大家還猶豫什么?!  結構:核心板+底板  接口:眾多,詳細情況請看官方介紹了,不多說了。  團購活動因為是非正常價格銷 ...…

查看全部問答∨

SQL如何將數據自動顯示到終端

如何將控制臺數據自動分工位顯示到終端 例: 工位號分為  A 、B 、C 、D 、E 、F      分別顯示到 A 、B 、C 、D 、E 、F 終端 …

查看全部問答∨

如何在EVC4里面安裝SDK

請問怎么在EVC4里面安裝SDK啊?我直接雙擊自己導出的SDK,不能安裝,那要怎么裝呢?…

查看全部問答∨

WinCE Driver 開發新手問題

各位大俠:小弟現需在WinCE5.0開發wifi driver,以前完全沒有相關經驗,完全沒有概念,模不著頭腦,問題真的很多。感覺微軟本身的文檔挺混亂的,說的也不怎么具體,大家有沒有好的教材?最好可以可以手把手教這個開發過程的啊(第一步做什么,第二 ...…

查看全部問答∨

Altium Designer 6 經典教程資料

收集到很多關于Altium Designer 資料,希望對大家有所幫助。 [ 本帖最后由 熊貓 于 2010-12-23 20:17 編輯 ]…

查看全部問答∨

Cortex M3學習筆記(一)--Systick的應用

這篇學習筆記,完全是基于《STM32不完全手冊》而言的,我沒有買Alientek的開發板,買的是ARMFly的,其實都差不多,只不過安福萊的板載資源非常豐富罷了,應用起來其實都差不都。 《STM32不完全手冊》的51到56頁就是要這次筆記學習的內容,請自己參 ...…

查看全部問答∨

led驅動學習

還沒有學驅動時,大部分對驅動的言論,包括老師的介紹都說做驅動是嵌入式里最難的部分,涉及到底層硬件和內核的知識,心里因此增加了不少畏懼。自己開始學習的時候便開始看些驅動方面的書,希望能有個比較好的認識,可慢慢的發現幾乎看不懂,看了韋 ...…

查看全部問答∨

PIC單片機程序的基本結構

建立源程序時首先用偽指令TITLE提供程序的標題,接著給出整個程序的總說明,并用列表偽指令LIST指定所用單片機型號和文件輸出格式,再利用INCLUDE偽指令讀入MPASM中提供的定義文件如《P16F84?INC》,然后對片內常用資源進行定義,再給出一般程序的 ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 青浦区| 巢湖市| 新和县| 吉林市| 广西| 泸西县| 西峡县| 宁蒗| 两当县| 韶关市| 曲沃县| 崇州市| 彰化县| 柳江县| 突泉县| 章丘市| 东乡族自治县| 博湖县| 清水河县| 崇明县| 辽中县| 寿宁县| 芦山县| 陕西省| 丹东市| 河北区| 星子县| 新野县| 平昌县| 乌鲁木齐县| 罗甸县| 剑川县| 同仁县| 深水埗区| 潞城市| 南京市| 包头市| 桐庐县| 鄂州市| 遂平县| 金门县|