日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F429入门(二十一):SPI协议及SPI读写FLASH

發布時間:2024/3/26 编程问答 79 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F429入门(二十一):SPI协议及SPI读写FLASH 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IIC主要用于通訊速率一般的場合,而SPI一般用于較高速的場合。

一、SPI協議簡介

SPI 協議是由摩托羅拉公司提出的通訊協議(Serial Peripheral Interface),即串行外圍設 備接口,是一種高速全雙工的通信總線。它被廣泛地使用在 ADC、LCD 等設備與 MCU 間, 要求通訊速率較高的場合。

(一)物理層

?

SPI 通訊使用 3 條總線及片選線,3 條總線分別為 SCK、MOSI、MISO,片選線為SS,它們的作用介紹如下:

  • SS:從設備選擇信號線,常稱為片選信號線,也稱為NSS、CS。每個從設備都有獨立的一條SS信號線,本信號線獨占主機的一個引腳,即有多少個從設備,就有多少條片選信號線。IIC協議中通過設備地址來尋址、選中總線上的某個設備并與其進行通訊;而SPI協議中沒有設備地址,它使用SS信號線來尋址,當主機選擇從設備時,把該從設備的SS信號線設置為低電平,該從設備即被選中,即片選有效,接著主機開始與被選中的從設備進行SPI通訊。所以SPI通訊以SS線置低電平為開始信號,以SS線被拉高作為結束信號

  • SCK:時鐘信號線,用于通訊數據同步。它由通訊主機產生,決定了通訊的速率,不同的設備支持的最高時鐘頻率不一樣。(同步通訊)STM32 的 SPI 時鐘頻率最大為 fpclk/2,兩個設備之間通訊時,通訊速率受限于低速設備

  • MOSI(Master Output,Slave Input):主設備輸出/從設備輸入引腳。主機的數據從這條信號線輸出,從機由這條信號線讀入主機發送的數據,即這條線上數據的方向為主機到從機

  • MISO(Master Input,Slave Output):主設備輸入/從設備輸出的引腳。主機從這條信號線讀入數據,從機的數據由這條信號線輸出到主機,即在這條線上數據的方向為從機到主機

(二)協議層

SPI協議定義了通訊的起始和停止信號、數據有效性、時鐘同步等環節。

(1)SPI基本通訊過程

  • 通訊的起始和停止信號

    SS信號線由高變低,是SPI通訊的起始信號。NSS是每個從機各自獨占的信號線,當從機檢測到NSS線檢測的起始信號后,就知道被選中了,開始準備與主機通訊。

    當信號由低變高,是SPI通訊的停止信號,表示本次通訊結束,從機的選中狀態被取消。

  • 數據有效性

    SPI使用MOSI及MISO信號線來傳輸數據,使用SCK信號線進行數據同步,MOSI及MISO數據線在SCK的每個時鐘周期傳輸一位數據,且數據輸入輸出是同時進行的。(圖示為下降沿采集數據)

  • CPOL/CPHA及通訊模式

    時鐘極性CPOL是指SPI通訊設備處于空閑狀態時,SCK信號線的電平信號(即SPI通訊開始前、NSS線為高電平時SCK的狀態)。CPOL=0時,SCK在空閑狀態時為低電平,CPOL=1時則相反。

    時鐘相位CPHA是指數據在采用的時刻,當CPHA=0時,MOSI或MISO數據線上的信號將會在SCK時鐘線的“奇數邊沿”被采樣。當CPHA=1時,數據線在SCK的“偶數邊沿”采樣。(無關上升沿下降沿),下圖為奇數邊沿采樣。

?由CPOL及CPHA的不同狀態,SPI分成了四種模式,主機與從機需要工作在相同的模式下才可以正常通訊,實際中采用較多的是“模式0”與“模式3”。

?

二、STM32的SPI外設架構

?

STM32的SPI外設可用作通訊的主機及從機,支持最高的SCK時鐘 頻率為fpclk/2 (STM32F429型號的芯片默認fpclk1為90MHz,fpclk2為45MHz), 完全支持SPI協議的4種模式,數據幀長度可設置為8位或16位,可設置數據 MSB先行(高位先行,從左往右)或LSB先行(低位先行,從右往左)。它還支持雙線全雙工(前面小節說明的都是這種模式)、 雙線單向以及單線模式。

1-通訊引腳,2-時鐘控制邏輯,3-數據控制邏輯,4-整體控制邏輯。

(1)通訊引腳

其中SPI1\SPI4\SPI5\SPI6是APB2上的設備,最高通訊速率達到45Mbit/s,SPI2\SPI3是APB1上的設備,最高通信速率為22.5Mbit/s。其它功能上沒有差異。SPI2\SPI3引腳上上均有I2S,可用來設置音頻,但是IIS與SPI不可以共用。

(2)時鐘控制邏輯

SCK線的時鐘信號,由波特率發生器根據“控制寄存器CR1”中的BR[0:2]位控制,該位是對fpclk時鐘的分頻因子,對fpclk的分頻結果就是SCK引腳的輸出時鐘頻率。

?其中fpclk頻率是指SPI所在的APB總線頻率,APB1為fpclk1,APB2為fpclk2。為了協調通訊速度比較慢的設備。

(3)數據控制邏輯

SPI的MOSI及MISO都連接到數據移位寄存器上,數據移位寄存器的數據來源于接收緩沖區及發送緩沖區。

  • 通過寫SPI的數據寄存器DR把數據填充到發送緩沖區中。

  • 通過讀數據寄存器DR,可以獲取接收緩沖區的內容。

  • 其中數據幀長度可以通過控制寄存器DR的DFF位配置成8位及16位模式:配置LSBFIRST位可以選擇MSB先行還是LSB先行。

  • SPI 的 MOSI 及 MISO 都連接到數據移位寄存器上,數據移位寄存器的內容來源于接收緩沖區及發送緩沖區以及 MISO、MOSI 線。當向外發送數據的時候,數據移位寄存器以 “發送緩沖區”為數據源,把數據一位一位地通過數據線發送出去;當從外部接收數據的 時候,數據移位寄存器把數據線采樣到的數據一位一位地存儲到“接收緩沖區”中。

?

(4)整體控制邏輯

整體控制邏輯復制協調整個SPI外設。控制邏輯的工作模式根據我們配置的“控制寄 存器(CR1/CR2)”的參數而改變,基本的控制參數包括前面提到的 SPI 模式、波特率、LSB 先行、主從模式、單雙向模式等等。我們可以通過工作狀態寄存器讀取SPI的工作狀態,“狀態寄存器(SR)”。控制邏輯還可以根據要求,負責控制產生SPI中斷信號、DMA請求及控制NSS信號線。在實際的應用中,我們一般不使用SPI外設的標準NSS信號線,而是更簡單地使用普通GPIO,軟件控制它地電平輸出,從而產生通訊起始和停止信號。

(5)通訊過程

?TXE標志代表的是緩沖區是否為空,當TXE為0時,發送緩沖區為非空,若為1時,發送緩沖區為空。當其為空時,也就說明可以準備發送下一個數據。RXNE為接收緩沖區是否為空的標志,其中0代表接收緩沖區為空,1代表接收緩沖區非空。

  • 控制NSS信號線,產生起始信號。

  • 把要發送的數據寫入到”數據寄存器DR“中,該數據會被存儲到發送緩沖區。

  • 通訊開始,SCK時鐘開始運行。MOSI把發送緩沖區中的數據一位一位地傳輸出去;MISO則把數據一位一位地存儲進接收緩沖區中;

  • 當發送完一幀數據的時候,”狀態寄存器SR“中的"TXE標志位"會被置1,表示傳輸完一幀,發送緩沖區已空;類似的,當接收完一幀數據的時候,”RXNE標志位“會被置1,表示傳輸完一幀,接收緩沖區非空;

  • 等待到”TXE標志位“為1時,若還要繼續發送數據,則再次往”數據寄存器DR“寫入數據即可;等待到”RXENE標志位“為1時,通過讀取”數據寄存器DR“可以獲取接收緩沖區中的內容。

假如使能了TXE或RXNE中斷,TXE或RXNE置1時會產生SPI中斷信號,進入同一個中斷服務函數,到SPI中斷服務程序后,可通過檢查寄存器位來了解是哪一個事件,再分別進行處理。也可以使用DMA方式來收發”數據寄存器DR“中的數據。

需要注意的是CR寄存器中的SSM位:

?當我們讓這個寄存器置1時,我們可以通過軟件來模擬SPI,這也是比較常用的方式。

三、SPI結構體

typedef struct {uint16_t SPI_Direction; /*設置 SPI 的單雙向模式 */uint16_t SPI_Mode; /*設置 SPI 的主/從機端模式 */uint16_t SPI_DataSize; /*設置 SPI 的數據幀長度,可選 8/16 位 */uint16_t SPI_CPOL; /*設置時鐘極性 CPOL,可選高/低電平*/uint16_t SPI_CPHA; /*設置時鐘相位,可選奇/偶數邊沿采樣 */uint16_t SPI_NSS; /*設置 NSS 引腳由 SPI 硬件控制還是軟件控制*/uint16_t SPI_BaudRatePrescaler; /*設置時鐘分頻因子,fpclk/分頻數=fSCK */uint16_t SPI_FirstBit; /*設置 MSB/LSB 先行 */uint16_t SPI_CRCPolynomial; /*設置 CRC 校驗的表達式 */ } SPI_InitTypeDef;
  • SPI_Direction:有雙線全雙工、雙線只接收、單線只接收、單線只發送模式。

  • SPI_Mode:主機模式、從機模式。這兩個模式的最大區別是在于時鐘信號線SCK信號線的時序,SCK的時序由通訊中的主機產生。若被設置為從機模式,則要接受外來的SCK信號。

  • SPI_DataSize:可以選擇SPI通訊的數據幀大小為8位或者16位。

  • SPI_CPOL和SPI_CPHA:這兩個成員配置SPI的時鐘極性CPOL和時鐘相位CPHA,這兩個配置影響到SPI的通訊模式。時鐘極性CPOL成員,可以設置為高電平或者為低電平。時鐘相位CPHA成員,可以設置為在SCK奇數邊沿采集數據或者是偶數邊沿。

  • SPI_NSS:可以選擇硬件模式或軟件模式。在硬件模式中的SPI片選信號由SPI硬件自動產生,而軟件模式則需要親自把相應的GPIO端口拉高或者置低產生非片選和片選信號。

  • SPI_BaudRatePrescaler:參數可以設定為2、4、6、8、16、32、64、128、256分頻。

  • SPI_FirstBit:MSB先行(高數據在前)還是LSB先行(低位數據在前)。

  • SPI_CRCPolynomial:適用于比較復雜的環境,這是 SPI 的 CRC 校驗中的多項式,若我們使用 CRC 校驗時,就使用這個成員的參數 (多項式),來計算 CRC 的值。

四、實踐——SPI讀寫串行FLASH

?上面是我們即將改寫的FLASH芯片。容量為16M。NCS引腳也為NSS引腳,DIO為MOSI引腳,DO為MISO引腳。WP為寫保護引腳,低電平有效。HOLD為暫停通訊或結束通訊,用的很少,接為高電平。以下為引腳的連接圖。

?在FLASH中,它一共有0-255即256個塊(Block),每個塊是64KB,16M=64*255/1024。每個塊右分為0-15個扇區(Sector),每個扇區4KB。寫入數據之前,必須要擦除數據,再重新寫入數據,擦除的最小單位為扇區。設備ID為4018H,設備ID可以用來判斷設備是否連接正常,以及設備是否配套正確。擦除整個芯片的命令為:C7h/60h。擦除扇區的命令為20h。此芯片為MSB先行。以上為該芯片手冊中得出。

?

了解這款FLASH后,我們開始進行讀寫。

(1)定義引腳以及時鐘

#define FLASH_SPI SPI5 #define FLASH_SPI_CLK RCC_APB2Periph_SPI5 #define RCC_APB_CLOCK_FUN RCC_APB2PeriphClockCmd#define FLASH_SPI_CS_GPIO_PORT GPIOF #define FLASH_SPI_CS_GPIO_CLK RCC_AHB1Periph_GPIOF #define FLASH_SPI_CS_PIN GPIO_Pin_6#define FLASH_SPI_SCK_GPIO_PORT GPIOF #define FLASH_SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOF #define FLASH_SPI_SCK_PIN GPIO_Pin_7 #define FLASH_SPI_SCK_AF GPIO_AF_SPI5 #define FLASH_SPI_SCK_SOURCE GPIO_PinSource7#define FLASH_SPI_MISO_GPIO_PORT GPIOF #define FLASH_SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOF #define FLASH_SPI_MISO_PIN GPIO_Pin_8 #define FLASH_SPI_MISO_AF GPIO_AF_SPI5 #define FLASH_SPI_MISO_SOURCE GPIO_PinSource8#define FLASH_SPI_MOSI_GPIO_PORT GPIOF #define FLASH_SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOF #define FLASH_SPI_MOSI_PIN GPIO_Pin_9 #define FLASH_SPI_MOSI_AF GPIO_AF_SPI5 #define FLASH_SPI_MOSI_SOURCE GPIO_PinSource9

(2)引腳初始化(復用GPIO)

#define CS_HIGH_DISABLE() GPIO_SetBits(FLASH_SPI_CS_GPIO_PORT,FLASH_SPI_CS_PIN) #define CS_LOW_ENABLE() GPIO_ResetBits(FLASH_SPI_CS_GPIO_PORT,FLASH_SPI_CS_PIN)void FLASH_SPI_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;//1.初始化GPIO RCC_AHB1PeriphClockCmd(FLASH_SPI_CS_GPIO_CLK|FLASH_SPI_SCK_GPIO_CLK|FLASH_SPI_MISO_ GPIO_CLK|FLASH_SPI_MOSI_GPIO_CLK,ENABLE);/* 連接 引腳源*/GPIO_PinAFConfig(FLASH_SPI_SCK_GPIO_PORT,FLASH_SPI_SCK_SOURCE,FLASH_SPI_SCK_AF);/* 連接 */GPIO_PinAFConfig(FLASH_SPI_MISO_GPIO_PORT,FLASH_SPI_MISO_SOURCE,FLASH_SPI_MISO_AF);GPIO_PinAFConfig(FLASH_SPI_MOSI_GPIO_PORT,FLASH_SPI_MOSI_SOURCE,FLASH_SPI_MOSI_AF);/* 使能 SPI 時鐘 */RCC_APB_CLOCK_FUN(FLASH_SPI_CLK, ENABLE);/* GPIO初始化 */GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //復用引腳配置為輸出模式也可以進行輸入GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;/* 配置SCK引腳為復用功能 */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN ; GPIO_Init(FLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);/* 配置MISO引腳為復用功能 */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;GPIO_Init(FLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);/* 配置MOSI引腳為復用功能 */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;GPIO_Init(FLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);/*CS引腳 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //推挽輸出,本身硬件就有一個上拉/* 配置SCK引腳為復用功能 */GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN ; GPIO_Init(FLASH_SPI_CS_GPIO_PORT, &GPIO_InitStructure);//2.配置SPI工作模式SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //最快的分頻SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge ; //偶數邊沿SPI_InitStructure.SPI_CPOL = SPI_CPOL_High ; //空閑時SCK時鐘高電平SPI_InitStructure.SPI_CRCPolynomial = 0 ; //不需要使用CRC校驗SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //數據幀SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //雙向SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//高位先行SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//軟件配置SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主機SPI_Init(FLASH_SPI,&SPI_InitStructure); SPI_Cmd(FLASH_SPI,ENABLE); CS_HIGH_DISABLE(); }

為了看初始化是否成功,我們可以獲取設備ID來檢驗。獲取ID的命令為:9Fh。

?

uint32_t Read_Device_ID(void) {uint8_t temp[3];//拉低片選CS_LOW_ENABLE();Read_Write_Byte(JEDEC_ID);temp[0] = Read_Write_Byte(DUMMY); //發送任意字節,產生時序,下面同理temp[1] = Read_Write_Byte(DUMMY);temp[2] = Read_Write_Byte(DUMMY);//拉高片選CS_HIGH_DISABLE();//將數據進行組合return temp[0]<<16|temp[1]<<8|temp[2]; }

?以上的命令可以使用宏定義來方便使用:

#define DUMMY 0xFF //任意值 #define JEDEC_ID 0x9F //ID #define ERACE_SECTOR 0x20 //擦除扇區 #define READ_DATA 0x03 //讀取數據 #define READ_STATUS 0x05 //空閑 #define WRITE_ENABLE 0x06 //寫使能 #define PAGE_PROGRAM 0x02 //寫入的地址

為了防止時鐘頻率錯誤響應,我們需要檢驗標志位,取決于我們什么時候讀,什么時候寫:

//先發送再接收才會產生時序,一定要注意!!否則STM32不會產生時序,產生一下后就停止,只接受到了地址的數據 uint8_t Read_Write_Byte(uint8_t data) {time_out = SPI_FLAG_TIMEOUT;while(SPI_GetFlagStatus(FLASH_SPI,SPI_FLAG_TXE) == RESET){if((time_out--)==0) return SPI_TIMEOUT_UserCallback(0);}//發送緩沖區為空SPI_I2S_SendData(FLASH_SPI,data);time_out = SPI_FLAG_TIMEOUT;//接收緩沖區為空,死循環while(SPI_GetFlagStatus(FLASH_SPI,SPI_FLAG_RXNE) == RESET){if((time_out--)==0) return SPI_TIMEOUT_UserCallback(1);}return SPI_I2S_ReceiveData (FLASH_SPI); }

?其中的變量以及報錯函數定義:

/*等待超時時間*/ #define SPI_FLAG_TIMEOUT ((uint32_t)0x1000) #define SPI_LONG_TIMEOUT ((uint32_t)(10 * SPI_FLAG_TIMEOUT))/*信息輸出*/ #define FLASH_DEBUG_ON 0#define FLASH_INFO(fmt,arg...) printf("<<-FLASH-INFO->> "fmt"\n",##arg) #define FLASH_ERROR(fmt,arg...) printf("<<-FLASH-ERROR->> "fmt"\n",##arg) #define FLASH_DEBUG(fmt,arg...) do{\if(FLASH_DEBUG_ON)\printf("<<-FLASH-DEBUG->>[%s] [%d]"fmt"\n",__FILE__,__LINE__, ##arg);\}while(0) static uint8_t SPI_TIMEOUT_UserCallback(uint8_t errorCode) {FLASH_ERROR("SPI 等待超時!errorCode = %d",errorCode); return 0xFF; }

為了保持在運行的過程中復位不會因為掉電而亂發數據,我們需要控制Release_Power_Down,稍后會進行補充。

(3)編寫FLASH讀寫過程

//擦除過后扇區內所有的數據都應為1 void erace_setor(uint32_t addr) {//在擦除之前必須寫使能Write_Enable();Wait_for_Ready();//拉低片選CS_LOW_ENABLE();Read_Write_Byte(ERACE_SECTOR);//一次能發送24bitRead_Write_Byte((addr>>16)&0xFF);Read_Write_Byte((addr>>8)&0xFF);Read_Write_Byte(addr&0xFF); //拉高片選CS_HIGH_DISABLE();//等待內部時序(等待擦除完成) } //寫使能函數 void Write_Enable(void) {//拉低片選CS_LOW_ENABLE();Read_Write_Byte(WRITE_ENABLE); //拉高片選CS_HIGH_DISABLE(); }

在讀取的過程中,我們需要得知狀態,看它是否空閑后再寫入數據、擦除數據、讀取數據,這個函數需要在拉低片選前使用:

void Wait_for_Ready(void) {uint8_t reg_status=0x01;while(reg_status &0x01){//拉低片選CS_LOW_ENABLE();//讀狀態寄存器Read_Write_Byte(READ_STATUS);reg_status = Read_Write_Byte(DUMMY); //拉高片選CS_HIGH_DISABLE(); }}

讀取數據的函數如下(整塊數據而非單個):

void Read_buffer(uint8_t* pdata,uint32_t addr,uint32_t numByteTorRead) {Wait_for_Ready();//拉低片選CS_LOW_ENABLE();Read_Write_Byte(READ_DATA);Read_Write_Byte((addr>>16)&0xFF);Read_Write_Byte((addr>>8)&0xFF);Read_Write_Byte(addr&0xFF); while(numByteTorRead--){*pdata = Read_Write_Byte(DUMMY);pdata++;}//拉高片選CS_HIGH_DISABLE();}

完成了讀數據,接下來是寫入數據,最多寫入256個數據:

void Write_buffer(uint8_t* pdata,uint32_t addr,uint32_t numByteTorWrite) {Write_Enable();Wait_for_Ready();//拉低片選CS_LOW_ENABLE();Read_Write_Byte(PAGE_PROGRAM);Read_Write_Byte((addr>>16)&0xFF);Read_Write_Byte((addr>>8)&0xFF);Read_Write_Byte(addr&0xFF); while(numByteTorWrite--){Read_Write_Byte(*pdata);pdata++;}//拉高片選CS_HIGH_DISABLE();}

主函數:

uint8_t readBuff[4096] = {0x0}; uint8_t writeBuff[256] = {0x0}; int main(void) { uint32_t device_id = 0;uint32_t i=0;/*初始化USART 配置模式為 115200 8-N-1,中斷接收*/Debug_USART_Config();FLASH_SPI_Config();/* 發送一個字符串 */Usart_SendString( DEBUG_USART,"這是一個FLASH實驗\n");printf("這是一個FLASH實驗\n");device_id = Read_Device_ID();printf("device_id =0x%x",device_id);erace_setor(0x00);//FLASH先擦除后寫入 //讀出擦除后的數據Read_buffer(readBuff,0x00,4096); printf("\r\n*************讀出擦除后的數據**********\r\n");for(i=0;i<4096;i++)printf("0x%x ",readBuff[i]);for(i=0;i<256;i++)writeBuff[i] = i;Write_buffer(writeBuff,0x00,256);//讀出擦除后的數據Read_buffer(readBuff,0x00,256); printf("\r\n*************讀出寫入后的數據**********\r\n");for(i=0;i<256;i++)printf("0x%x ",readBuff[i]);while(1){ } }

五、看庫理清思路

下面的代碼是已經進行初始化過后,使能NSS引腳后的操作:

(1)使用SPI發送和接收一個數據

/* * @brief 使用SPI發送一個字節的數據 * @param byte:要發送的數據 * @retval 返回接收到的數據 */ u8 SPI_FLASH_SendByte(u8 byte) {SPITimeout = SPIT_FLAG_TIMEOUT;/* 等待發送緩沖區為空,TXE事件 */while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE) == RESET){if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);}/* 寫入數據寄存器,把要寫入的數據寫入發送緩沖區 */SPI_I2S_SendData(FLASH_SPI, byte);SPITimeout = SPIT_FLAG_TIMEOUT;/* 等待接收緩沖區非空,RXNE事件 */while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET){if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);}/* 讀取數據寄存器,獲取接收緩沖區數據 */return SPI_I2S_ReceiveData(FLASH_SPI); }//當使用SPI進行讀取時,我們需要先寫入,再讀出/* * @brief 使用SPI讀取一個字節的數據 * @param 無 * @retval 返回接收到的數據 */ u8 SPI_FLASH_ReadByte(void) {return (SPI_FLASH_SendByte(Dummy_Byte)); }
  • 函數u8 SPI_FLASH_SendByte(u8 byte)實現了SPI的通訊過程。

  • 上面兩個函數都不包含SPI的起始和停止信號,只是收發的主要過程,所以以上兩個函數都是拿來調用的,前后需要做好起始和停止信號的操作。

  • 通過檢測TXE,獲取發送緩沖區狀態,若發送緩沖區為空,則說明上一個數據已發送完畢,若不為空,則等待其為空后,再調用庫函數SPI_I2S_SendData把要發送的數據寫入到數據寄存器DR,寫入SPI的數據會存儲到發送緩沖區,由SPI外設發送出去。從這一點就可以說明,當你想要讀取數據時,必須先寫入,后再讀出

  • 寫入完畢后,等待RXNE事件,即接收緩沖區非空事件。由于 SPI 雙線全雙工模式下 MOSI 與 MISO 數據傳輸是同步的,當接收緩沖區非空時,表示上面的數據發送完畢,且接收緩沖區也收到新的數據。

  • 等待至接收緩沖區非空時,通過調用庫函數SPI_I2S_ReceiveData讀取寄存器DR中的數據,最后將其return。

  • 最后看一下讀取一個字節數據,它只是簡單地調用了一個任意值Dummy_Byte,然后獲取返回值,其實發送值是什么無關緊要,然后獲取其返回值。SPI接收過程和發送過程實質是一樣的,收發同時進行,關鍵在于上層應用關注的是接收還是發送。

(2)寫使能以及讀取當前的狀態

/* * @brief 向FLASH發送 寫使能 命令 * @param none * @retval none */ void SPI_FLASH_WriteEnable(void) {/* 通訊開始:CS低 */SPI_FLASH_CS_LOW();/* 發送寫使能命令*/SPI_FLASH_SendByte(W25X_WriteEnable);/*通訊結束:CS高 */SPI_FLASH_CS_HIGH(); }

FLASH芯片向內部存儲矩陣寫入數據需要消耗一定的時間,并不是在總線通訊結束的一瞬間完成的,所以需要檢驗FLASH是否空閑。FLASH芯片定義了一個狀態寄存器:

我們需要關注這個狀態寄存器的第0位BUSY是否為1,表明FLASH芯片處于忙碌狀態,也就是說這個時候它可能在進行擦除或者寫入的操作。利用指令表中的“Read Status Register”指令可以獲取FLASH芯片寄存器的內容。并校驗第0位,判斷當前是否可以寫入。判斷函數如下:

/* * @brief 等待WIP(BUSY)標志被置0,即等待到FLASH內部數據寫入完畢 * @param none * @retval none */ void SPI_FLASH_WaitForWriteEnd(void) {u8 FLASH_Status = 0;/* 選擇 FLASH: CS 低 */SPI_FLASH_CS_LOW();/* 發送 讀狀態寄存器 命令 */SPI_FLASH_SendByte(W25X_ReadStatusReg);SPITimeout = SPIT_FLAG_TIMEOUT;/* 若FLASH忙碌,則等待 */do{/* 讀取FLASH芯片的狀態寄存器 */FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte); {if((SPITimeout--) == 0) {SPI_TIMEOUT_UserCallback(4);return;}} }while ((FLASH_Status & WIP_Flag) == SET); /* 正在寫入標志 *//* 停止信號 FLASH: CS 高 */SPI_FLASH_CS_HIGH(); }

(3)FLASH扇區擦除

FLASH的存儲特性:由于 FLASH 存儲器的特性決定了它只能把原來為“1”的數據位改寫成“0”,而原 來為“0”的數據位不能直接改寫為“1”。所以這里涉及到數據“擦除”的概念,在寫入 前,必須要對目標存儲矩陣進行擦除操作,把矩陣中的數據位擦除為“1”,在數據寫入的 時候,如果要存儲數據“1”,那就不修改存儲矩陣 ,在要存儲數據“0”時,才更改該位。

擦除有以下分類:扇區擦除(Sector Erase)、塊擦除(Block Erase)、整片擦除(Chip Erase)

扇區擦除指令的第一個字節為指令編碼,緊接著發送的 4 個字節用于表示要擦除的存儲矩陣地址。要注意的是在扇區擦除指令前,還需要先發送“寫使能”指令,發送扇區擦除指令后,通過讀取寄存器狀態等待扇區擦除操作完畢。注意發送擦除地址時高位在前即可。

void SPI_FLASH_SectorErase(u32 SectorAddr) {/* 發送FLASH寫使能命令 */SPI_FLASH_WriteEnable();SPI_FLASH_WaitForWriteEnd();/* 擦除扇區 *//* 選擇FLASH: CS低電平 */SPI_FLASH_CS_LOW();/* 發送扇區擦除指令*/SPI_FLASH_SendByte(W25X_SectorErase);/*發送擦除扇區地址的高8位*/SPI_FLASH_SendByte((SectorAddr & 0xFF000000) >> 24);/*發送擦除扇區地址的中前8位*/SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);/* 發送擦除扇區地址的中后8位 */SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);/* 發送擦除扇區地址的低8位 */SPI_FLASH_SendByte(SectorAddr & 0xFF);/* 停止信號 FLASH: CS 高電平 */SPI_FLASH_CS_HIGH();/* 等待擦除完畢*/SPI_FLASH_WaitForWriteEnd(); }

(4)FLASH的頁寫入

FLASH的頁寫入命令最多一次可以傳輸256個字節數據,這個單位也是頁大小。FLASH頁寫入的時序如圖:

?

從時序圖可知,第 1 個字節為“頁寫入指令”編碼,24 字節為要寫入的“地址 A”, 接著的是要寫入的內容,最多個可以發送 256 字節數據,這些數據將會從“地址 A”開始, 按順序寫入到 FLASH 的存儲矩陣。若發送的數據超出 256 個,則會覆蓋前面發送的數據。

與擦除指令不一樣,頁寫入指令的地址并不要求按 256 字節對齊,只要確認目標存儲 單元是擦除狀態即可(即被擦除后沒有被寫入過)。所以,若對“地址 x”執行頁寫入指令后, 發送了 200 個字節數據后終止通訊,下一次再執行頁寫入指令,從“地址(x+200)”開始寫 入 200 個字節也是沒有問題的(小于 256 均可)。

/* * @brief 對FLASH按頁寫入數據,調用本函數寫入數據前需要先擦除扇區 * @param pBuffer,要寫入數據的指針 * @param WriteAddr,寫入地址 * @param NumByteToWrite,寫入數據長度,必須小于等于SPI_FLASH_PerWritePageSize * @retval 無 */ void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite) {/* 發送FLASH寫使能命令 */SPI_FLASH_WriteEnable();/* 選擇FLASH: CS低電平 */SPI_FLASH_CS_LOW();/* 寫頁寫指令*/SPI_FLASH_SendByte(W25X_PageProgram);/*發送寫地址的高8位*/SPI_FLASH_SendByte((WriteAddr & 0xFF000000) >> 24);/*發送寫地址的中前8位*/SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);/*發送寫地址的中后8位*/SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);/*發送寫地址的低8位*/SPI_FLASH_SendByte(WriteAddr & 0xFF);if(NumByteToWrite > SPI_FLASH_PerWritePageSize){NumByteToWrite = SPI_FLASH_PerWritePageSize;FLASH_ERROR("SPI_FLASH_PageWrite too large!");}/* 寫入數據*/while (NumByteToWrite--){/* 發送當前要寫入的字節數據 */SPI_FLASH_SendByte(*pBuffer);/* 指向下一字節數據 */pBuffer++;}/* 停止信號 FLASH: CS 高電平 */SPI_FLASH_CS_HIGH();/* 等待寫入完畢*/SPI_FLASH_WaitForWriteEnd(); }

先發送“寫使能”命令,接著才開始頁寫入時序,然后發送指令 編碼、地址,再把要寫入的數據一個接一個地發送出去,發送完后結束通訊,檢查 FLASH 狀態寄存器,等待 FLASH 內部寫入結束。

當我們有不定量數據寫入時,大于256時,可以用下面的函數:

/*** @brief 對FLASH寫入數據,調用本函數寫入數據前需要先擦除扇區* @param pBuffer,要寫入數據的指針* @param WriteAddr,寫入地址* @param NumByteToWrite,寫入數據長度* @retval 無*/ void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite) {u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;/*mod運算求余,若writeAddr是SPI_FLASH_PageSize整數倍,運算結果Addr值為0*/Addr = WriteAddr % SPI_FLASH_PageSize;/*差count個數據值,剛好可以對齊到頁地址*/count = SPI_FLASH_PageSize - Addr; /*計算出要寫多少整數頁*/NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;/*mod運算求余,計算出剩余不滿一頁的字節數*/NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;/* Addr=0,則WriteAddr 剛好按頁對齊 aligned */if (Addr == 0) {/* NumByteToWrite < SPI_FLASH_PageSize */if (NumOfPage == 0) {SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);}else /* NumByteToWrite > SPI_FLASH_PageSize */{/*先把整數頁都寫了*/while (NumOfPage--){SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);WriteAddr += SPI_FLASH_PageSize;pBuffer += SPI_FLASH_PageSize;}/*若有多余的不滿一頁的數據,把它寫完*/SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);}}/* 若地址與 SPI_FLASH_PageSize 不對齊 */else {/* NumByteToWrite < SPI_FLASH_PageSize */if (NumOfPage == 0) {/*當前頁剩余的count個位置比NumOfSingle小,寫不完*/if (NumOfSingle > count) {temp = NumOfSingle - count;/*先寫滿當前頁*/SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);WriteAddr += count;pBuffer += count;/*再寫剩余的數據*/SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);}else /*當前頁剩余的count個位置能寫完NumOfSingle個數據*/{ SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);}}else /* NumByteToWrite > SPI_FLASH_PageSize */{/*地址不對齊多出的count分開處理,不加入這個運算*/NumByteToWrite -= count;NumOfPage = NumByteToWrite / SPI_FLASH_PageSize;NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);WriteAddr += count;pBuffer += count;/*把整數頁都寫了*/while (NumOfPage--){SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);WriteAddr += SPI_FLASH_PageSize;pBuffer += SPI_FLASH_PageSize;}/*若有多余的不滿一頁的數據,把它寫完*/if (NumOfSingle != 0){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);}}} }

(5)從FLASH讀取數據

相對于寫入,FLASH 芯片的數據讀取要簡單得多,使用讀取指令“Read Data”即可。

發送了指令編碼及要讀的起始地址后,FLASH 芯片就會按地址遞增的方式返回存儲矩 陣的內容,讀取的數據量沒有限制,只要沒有停止通訊,FLASH 芯片就會一直返回數據。

/* * @brief 讀取FLASH數據 * @param pBuffer,存儲讀出數據的指針 * @param ReadAddr,讀取地址 * @param NumByteToRead,讀取數據長度 * @retval 無 */ void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead) {/* 選擇FLASH: CS低電平 */SPI_FLASH_CS_LOW();/* 發送 讀 指令 */SPI_FLASH_SendByte(W25X_ReadData);/* 發送 讀 地址高8位 */SPI_FLASH_SendByte((ReadAddr & 0xFF000000) >> 24);/* 發送 讀 地址中前8位 */SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);/* 發送 讀 地址中后8位 */SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);/* 發送 讀 地址低8位 */SPI_FLASH_SendByte(ReadAddr & 0xFF);/* 讀取數據 */while (NumByteToRead--){/* 讀取一個字節*/*pBuffer = SPI_FLASH_SendByte(Dummy_Byte);/* 指向下一個字節緩沖區 */pBuffer++;}/* 停止信號 FLASH: CS 高電平 */SPI_FLASH_CS_HIGH(); }

?六、FLASH存儲小數和整數

需要注意的是,存儲各種數據類型的時候,我們需要將不同的數據類型分在不同的扇區,不可以混著,主要原因是下面這個動態存儲,因為不同的字節數存儲的方式不一樣,比如說,存儲整數,我們將整數通過十六進制傳入,占兩個字節,當我們需要讀取時,四個字節四個字節的讀,即合為一個整數,若這個時候我們用浮點數的方式來運算,它就為八個字節八個字節的讀,會出錯。所以,當我們存儲不管是浮點數還是整數,存儲方式都一樣,可是你想讀出來的時候,你就應該區分他們之間的區別,不可以混為一談,怎么讀數據,還是取決于上位機的處理。

/*寫入小數數據到第一頁*/ SPI_FLASH_BufferWrite((void*)double_buffer, SPI_FLASH_PageSize*1, sizeof(double_buffer)); /*寫入整數數據到第二頁*/ SPI_FLASH_BufferWrite((void*)int_bufffer, SPI_FLASH_PageSize*2, sizeof(int_bufffer));

?SPI協議初步就學習到這啦,國慶也就結束了,好像任務量也沒有完成很多,接下來也要忙比賽啦,希望自己再接再厲。

?

總結

以上是生活随笔為你收集整理的STM32F429入门(二十一):SPI协议及SPI读写FLASH的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

久久久国产精品一区二区中文 | 亚洲天天 | 国产成人在线看 | 亚洲精品国内 | 在线一级片 | 日本激情动作片免费看 | 99av国产精品欲麻豆 | 亚洲精品黄色在线观看 | 五月婷婷毛片 | 免费观看一区二区 | 久久不射电影网 | 亚洲最新合集 | 日韩中文在线字幕 | 偷拍视频一区 | 欧美人zozo | 欧美亚洲精品在线观看 | 超级碰碰碰碰 | www.色午夜,com | 亚洲一区二区天堂 | 91丨九色丨高潮 | 日韩有码欧美 | 国产日韩精品一区二区三区 | 九九国产视频 | 天天操狠狠操网站 | 日本天天操 | 天天射天天射天天射 | 99久久精品免费看国产一区二区三区 | 天天干干| 91成人免费看片 | 97视频在线观看播放 | 天天草夜夜| 国产一区二区在线视频观看 | 国产91精品久久久久久 | 亚洲精品国产精品国自产在线 | 国产va饥渴难耐女保洁员在线观看 | av官网 | 中文字幕精品一区二区三区电影 | 国产成人一区二区三区影院在线 | 国产在线一区二区 | 黄色的视频网站 | 在线天堂视频 | 亚洲精品乱码久久久久久蜜桃欧美 | 日韩免费在线播放 | 中文字幕在线网址 | 91成人在线免费观看 | 日日爱999 | 国产99久久久国产精品成人免费 | 国产高清99 | 99精品久久精品一区二区 | 国产精品 美女 | 国产亚洲精品久久久久久无几年桃 | 区一区二区三区中文字幕 | 精品一二三四五区 | 人人狠狠综合久久亚洲 | 永久免费毛片在线观看 | 瑞典xxxx性hd极品 | 天天爱天天草 | 欧美国产日韩一区 | 欧美日韩中文字幕综合视频 | 天天插视频 | 亚洲三级视频 | 久久9999久久免费精品国产 | 中文字幕精 | 久久精品综合网 | 黄色亚洲片| 美女国产在线 | www.亚洲视频.com | 手机av资源 | 成人午夜电影在线观看 | 超碰97人人射妻 | 欧美国产日韩一区二区 | 91精品国产91久久久久福利 | 一级片色播影院 | 久久日韩精品 | 日韩激情网 | 亚洲四虎影院 | 免费黄色av电影 | 五月激情久久久 | 国产精品一区二区久久精品爱微奶 | 色婷婷精品大在线视频 | 香蕉免费 | 五月天电影免费在线观看一区 | 中文字幕九九 | 四虎成人av | 成人免费视频在线观看 | 天天色天天上天天操 | 日韩精品一区二区三区三炮视频 | 国产极品尤物在线 | 在线观看91av | 国外成人在线视频网站 | 久久国产精品久久精品 | 日韩sese | 日韩欧美v | 黄色一级动作片 | 国产欧美最新羞羞视频在线观看 | 丁香五月网久久综合 | 一区二区视频在线免费观看 | 一区二区三区在线免费 | 亚洲日本一区二区在线 | 中文字幕日韩国产 | 九九九九热精品免费视频点播观看 | 日本黄色免费电影网站 | 五月婷av| 亚洲 欧美 另类人妖 | 蜜桃视频精品 | www.精选视频.com | 日本在线观看黄色 | 日韩一二三在线 | 最新国产一区二区三区 | 九九免费视频 | 在线观看黄网站 | 女人18片 | 热久久视久久精品18亚洲精品 | 午夜久久| 久久久网 | 欧美亚洲精品一区 | www.99在线观看 | 亚洲色图激情文学 | 中文字幕在线观看国产 | 久久国产精品99国产精 | 一区二区三区四区五区在线视频 | 91日本在线播放 | 91国内产香蕉 | 精品人妖videos欧美人妖 | 粉嫩av一区二区三区四区五区 | 免费a网 | 五月天久久婷 | 日韩电影一区二区三区在线观看 | 久久色在线观看 | 色中色亚洲 | 国产精品18久久久久久久 | 欧美日韩激情视频8区 | 精品综合久久久 | 日韩电影在线视频 | 国产97在线看 | 久草网视频在线观看 | 国产美女久久久 | 久久久久 免费视频 | 久草在线视频新 | 国产黄色一级片在线 | 国产一区欧美在线 | 日韩美精品视频 | 正在播放国产精品 | 91一区啪爱嗯打偷拍欧美 | 久久久久久久久久久免费视频 | 天天操天天草 | 天天鲁一鲁摸一摸爽一爽 | 少妇搡bbbb搡bbb搡忠贞 | 激情久久小说 | 国产精品中文字幕av | 天天操天天射天天爽 | 久久五月天综合 | 另类老妇性bbwbbw高清 | 日韩在线中文字幕 | 日韩精品在线播放 | 久久久免费高清视频 | 国产小视频免费观看 | 六月丁香在线观看 | 久久精品999 | 国产九色视频在线观看 | 中文字幕在线观看视频网站 | 精品不卡av| 国产精品av在线 | 国产精品密入口果冻 | 免费网站污 | 成人a大片 | 91久久人澡人人添人人爽欧美 | 三级黄色大片在线观看 | 日韩欧美69 | 92精品国产成人观看免费 | 美女视频黄免费的久久 | 国产成人精品在线播放 | 国产精品美女在线观看 | 中文字幕丝袜一区二区 | 天天干国产| 99热手机在线 | 日韩一区二区三免费高清在线观看 | 天天操天天添天天吹 | 久久婷婷国产色一区二区三区 | 午夜精品一区二区国产 | 中文字幕传媒 | 成人天堂网 | 九九综合九九综合 | 91精品伦理 | 久久久电影网站 | 99久久日韩精品免费热麻豆美女 | 久热免费在线观看 | 日韩午夜网站 | www.久草视频 | av在线播放不卡 | 日韩一区在线播放 | 国产精品12| 国产剧情一区 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 91一区啪爱嗯打偷拍欧美 | 在线播放日韩av | 成人免费看片网址 | 成片视频在线观看 | av在线精品 | 韩日av一区二区 | 婷婷综合五月天 | 婷婷在线精品视频 | 久久精品男人的天堂 | 99草在线视频 | 亚洲综合成人婷婷小说 | 久久99国产视频 | 狠狠躁日日躁狂躁夜夜躁av | 91女神的呻吟细腰翘臀美女 | 波多野结衣在线视频免费观看 | 亚洲国产精品一区二区久久hs | 草久热| 亚洲精品久久视频 | 十八岁以下禁止观看的1000个网站 | 美女黄网站视频免费 | 久久精品久久久精品美女 | 99久久精品国产网站 | 麻豆传媒在线免费看 | 亚洲欧洲成人 | 91视频专区 | 天天操天天操天天操天天操天天操 | 青草草在线视频 | 免费在线观看黄 | 国产在线视频资源 | 亚洲成人蜜桃 | 久久免费国产视频 | 日本公妇在线观看高清 | 999成人网 | 人人澡人人澡人人 | 麻豆视频91 | 亚洲高清激情 | 91麻豆网| 久久久久 | 国产一区欧美一区 | 国产精品久久久久久久久久三级 | 91色网址| 国产精品女人网站 | 国产成人免费在线 | 国产亚洲人成网站在线观看 | 亚洲综合激情小说 | av免费在线免费观看 | 国产91影视 | 97国产精品免费 | 玖玖玖国产精品 | 欧美日韩在线观看一区二区 | 最近的中文字幕大全免费版 | 免费高清在线视频一区· | av观看在线观看 | 色婷婷狠狠18 | 欧美精品久久人人躁人人爽 | 国产网红在线观看 | 欧美成年人在线视频 | 97在线观看视频免费 | 久久经典国产 | 成人在线超碰 | 福利视频一区二区 | 亚洲激情在线观看 | 久久 地址 | 最近的中文字幕大全免费版 | 国产成人一区在线 | 婷婷久久一区二区三区 | 国产精品ⅴa有声小说 | 久久一二区 | 久草精品视频 | 最新三级在线 | 国产精品免费久久久久久 | 亚洲视频在线播放 | 色婷婷狠狠五月综合天色拍 | 国产成人一区二区在线观看 | 天天天天天天干 | 久久黄色片 | 国产精品欧美 | 9999精品视频 | www.久久久久 | 狠狠躁天天躁 | 久草在线网址 | 四虎在线视频 | 色是在线视频 | 不卡av电影在线观看 | 欧美日韩亚洲在线观看 | 国产精品久久在线观看 | 亚洲女欲精品久久久久久久18 | 涩涩爱夜夜爱 | 成 人 黄 色 免费播放 | 天天在线操 | 人人涩 | 国产精品久久久久久久午夜片 | 久久精品视频2 | 精品免费一区二区三区 | 在线观看aaa | 在线中文字幕电影 | 精品91| 一区二三国产 | 日韩精品一区二区三区免费观看 | 欧美日韩在线免费观看视频 | 在线观看中文字幕亚洲 | 狠狠亚洲 | 久久成人精品视频 | 在线观看国产日韩 | 天天草天天色 | 四虎在线影视 | 亚洲精品在线免费观看视频 | 久久国产剧场电影 | 天天操综 | 日韩爱爱片| 久久精品久久精品久久39 | 亚洲国产精品资源 | 在线国产日韩 | 成人av电影免费在线观看 | av手机在线播放 | 亚洲午夜精品久久久久久久久久久久 | 97在线观看免费高清完整版在线观看 | 中文字幕一区二区三区四区在线视频 | 午夜精品久久久 | 欧美在线视频一区二区三区 | 亚洲成人频道 | 日韩精品中字 | 国产视频在线免费观看 | 亚洲精品乱码久久久久久9色 | 亚洲免费成人av电影 | av在线免费在线 | 亚洲免费av片 | 成人久久18免费网站麻豆 | 日韩大陆欧美高清视频区 | 综合网中文字幕 | 99热最新| 久久特级毛片 | 国产小视频在线播放 | 亚洲精品人人 | 欧美 日韩 性 | 免费在线观看国产黄 | 中文字幕网站 | 国产精品久久久区三区天天噜 | 久久涩视频| 在线草| 免费麻豆视频 | 日韩丝袜 | 亚洲永久国产精品 | 欧美日韩三级在线观看 | 中文字幕有码在线观看 | 97精品国产97久久久久久粉红 | 在线观看免费 | 91爱爱电影| 人人射人人爽 | 亚洲福利精品 | 色欧美视频 | 精品99视频 | 色偷偷男人的天堂av | 日本公乱妇视频 | 九九热精品视频在线播放 | 国产精品一区专区欧美日韩 | 国产精品视频免费看 | 99精品国产免费久久久久久下载 | 最近中文字幕视频网 | 天天操天天干天天干 | 久久毛片视频 | 欧美日韩视频在线观看一区二区 | 久久观看免费视频 | 国产精品五月天 | 精品久久久网 | 欧美精品久久久久 | 99r在线视频 | 丁香激情综合久久伊人久久 | 亚洲精品在线视频 | 精品国产一区二区三区久久久蜜臀 | 99精品久久精品一区二区 | 久久激情综合网 | 国产亚洲视频系列 | 久久国产精品一区二区三区四区 | 亚洲精品av中文字幕在线在线 | 五月婷婷综合色拍 | 午夜成人影视 | 亚洲手机天堂 | 青青河边草免费直播 | 伊甸园av在线 | 成人黄色电影在线观看 | 国产很黄很色的视频 | 日韩va在线观看 | 一二区av | 午夜国产一区 | 免费大片黄在线 | 国产成人精品av | 中文字幕在线播放第一页 | 在线一级片| 国产精品1000| 亚洲黄色激情小说 | 国产成人免费观看久久久 | 国产午夜在线 | v片在线播放 | www.狠狠| 亚洲激情中文 | 国产不卡一二三区 | 亚洲国产欧美一区二区三区丁香婷 | 国产精品视频免费看 | 97超视频| 91视频国产免费 | 激情偷乱人伦小说视频在线观看 | 天天在线操 | 麻豆极品| 久久人人爽人人爽人人片 | 天天操比 | 粉嫩av一区二区三区免费 | 三级性生活视频 | 成人免费观看视频大全 | 国产精品久久久久久吹潮天美传媒 | 免费观看十分钟 | 奇米影视在线99精品 | 免费黄在线看 | 国产精品免费在线播放 | 国产精品久久久久久爽爽爽 | 久久香蕉电影 | 免费中午字幕无吗 | 中文字幕在 | 国产精品欧美一区二区三区不卡 | 91成人免费 | 久久精品—区二区三区 | 精产嫩模国品一二三区 | 亚洲动漫在线观看 | 在线观看一级视频 | 久久网站免费 | 天天综合网入口 | 欧美资源| 日韩欧美视频一区二区 | 四虎成人av | 久久精品在线 | 久久精品视频播放 | 最近的中文字幕大全免费版 | 99在线观看视频 | 激情五月综合网 | 手机av电影在线观看 | a在线一区 | 最近中文字幕在线中文高清版 | www.eeuss影院av撸 | 日本精品一区二区三区在线观看 | 天天射天天干 | 国产午夜精品免费一区二区三区视频 | 免费看毛片网站 | 免费成人在线视频网站 | 国产日产欧美在线观看 | 欧美最猛性xxxxx免费 | 最近中文字幕免费视频 | 免费视频91 | 91精品国产91p65 | 日日干 天天干 | 亚洲午夜精品一区二区三区电影院 | 精品久久99 | 草免费视频 | 91传媒91久久久 | 五月婷婷视频在线观看 | 一区二区不卡在线观看 | 久久人人爽人人爽人人片 | 精品久久网 | 成人黄大片| 中文字幕在线看视频国产 | 园产精品久久久久久久7电影 | 亚洲专区路线二 | www.夜夜爽 | 国产又黄又爽又猛视频日本 | 五月婷婷六月丁香在线观看 | 国产视频97 | 91看片淫黄大片一级在线观看 | 91av视频免费观看 | 国产精品成人自产拍在线观看 | 久草久 | 欧美日韩国产一区二 | 免费观看久久久 | 精品国产1区 | 日本特黄一级 | 日韩极品视频在线观看 | 91久久精品一区二区三区 | av三级av | 精品国自产在线观看 | 免费高清在线视频一区· | 成人av电影免费在线观看 | 国产r级在线观看 | 黄色大片av | 成人黄色毛片 | 日韩中文幕 | 美女网站在线免费观看 | 日韩av高清在线观看 | 在线国产中文字幕 | www操操操 | 欧美日韩高清一区二区 国产亚洲免费看 | 久久精品视频免费播放 | 国产精品久久久久久久久毛片 | 国产精品亚洲综合久久 | 精品影院一区二区久久久 | 欧美日韩视频一区二区 | 亚洲动漫在线观看 | 99久久日韩精品视频免费在线观看 | 狠狠干夜夜操天天爽 | 狠狠干在线| 天天综合区 | 久久精品99久久久久久2456 | 91精品久久香蕉国产线看观看 | 伊人久久电影网 | 香蕉视频色 | 九九免费在线视频 | 精品国产伦一区二区三区观看体验 | 天天天天色射综合 | 国产在线观看污片 | 日韩在线 一区二区 | 日日爽视频 | 中文字幕乱视频 | av福利在线看 | 在线观看视频黄 | 国产精彩视频 | 亚洲第一区在线观看 | 黄网站www | 美女搞黄国产视频网站 | 国产成人精品aaa | 日韩va亚洲va欧美va久久 | 成人综合婷婷国产精品久久免费 | 日韩精品一区二区三区电影 | 天天干天天拍天天操 | 深爱开心激情网 | 国内精品久久久久影院一蜜桃 | 高潮久久久久久 | 手机看片中文字幕 | 国产精品美女久久久久久2018 | 久久综合免费视频 | 亚洲综合欧美激情 | 天天射日 | 成人免费视频观看 | 综合色婷婷 | 97免费在线观看视频 | 91麻豆精品久久久久久 | 婷婷视频在线 | 波多野结衣电影一区 | 五月开心六月伊人色婷婷 | 日韩高清www| 日韩免费电影一区二区三区 | 久久久久蜜桃 | 日日干干夜夜 | 色婷婷影视 | 中文字幕a∨在线乱码免费看 | 精品亚洲成人 | 精品二区视频 | 天天躁天天操 | 91久久久久久久一区二区 | 国产特级毛片 | 日精品 | 中文字幕免费观看全部电影 | 国产精久久 | 日韩精品一区二区三区免费观看 | 亚洲精品在线观看不卡 | 在线观看的av | 97超碰国产精品女人人人爽 | 久久无码av一区二区三区电影网 | 啪啪精品| 婷婷午夜 | 国产精品黄网站在线观看 | 国产成人精品一区二区三区福利 | 国产高清永久免费 | 国产精品久久久久久久久久久久久 | 久久免费看a级毛毛片 | 国产剧情一区 | 中文字幕有码在线播放 | 中文字幕在线日亚洲9 | 日韩av女优视频 | 狠狠干电影 | 欧美亚洲另类在线视频 | 色综合久久88色综合天天免费 | 国产一区免费 | 国产成人区 | 亚洲国产精品成人av | 欧美日韩国产精品一区二区 | 国产日本亚洲高清 | 91一区二区在线 | 欧美日韩有码 | 国产无套精品久久久久久 | 视频在线一区二区三区 | 国产免费黄色 | 成年人免费观看国产 | 综合激情网... | av中文字幕av| 国产一级免费av | 99婷婷狠狠成为人免费视频 | 99精品一区 | 九九热视频在线免费观看 | 99re8这里有精品热视频免费 | 免费国产亚洲视频 | 18pao国产成视频永久免费 | 天天干天天碰 | 国产91精品一区二区麻豆网站 | 一区二区男女 | 狠狠狠狠狠操 | 久久久久国产成人精品亚洲午夜 | 久久久久在线 | 午夜神马福利 | 全久久久久久久久久久电影 | 久久久久亚洲精品成人网小说 | 日韩高清黄色 | 日韩欧美99 | 国产区久久| 久久精品国产免费 | 开心色插 | 国产福利免费在线观看 | 日韩一二三在线 | a√天堂资源 | 欧美日韩高清在线观看 | 日韩欧美国产精品 | 亚洲极色 | 五月婷婷导航 | 中文字幕在线免费观看视频 | 欧洲精品在线视频 | 丁香色综合| 日韩中文免费视频 | 人人澡超碰碰97碰碰碰软件 | 久久久久久久久久免费视频 | 超碰在线个人 | 日韩一二区在线 | 狠狠干夜夜操天天爽 | 国产精品久久久久久久久久 | 成人久久久精品国产乱码一区二区 | 国产一级二级三级在线观看 | 日韩视频中文字幕 | 99视频网址| 亚洲日韩精品欧美一区二区 | 欧日韩在线视频 | 日韩一区二区免费播放 | 激情小说网站亚洲综合网 | 日韩国产精品一区 | 久久久精品福利视频 | 亚洲黄色av网址 | 日批网站在线观看 | 国内久久看| 一区二区欧美在线观看 | 精品国模一区二区三区 | 欧美天天综合 | 国产精品一区二区久久 | 黄色一级动作片 | 182午夜在线观看 | 天天天操天天天干 | 在线观看视频中文字幕 | 成人av中文字幕 | 中文字幕在线第一页 | 国产91对白在线播 | 国产一区欧美在线 | 欧美日韩一级在线 | 色偷偷av男人天堂 | 丁香婷婷综合激情五月色 | 97免费| 处女av在线 | 精品99在线视频 | 国产黄在线 | 麻豆免费精品视频 | 久久久免费少妇 | www五月天婷婷| 国产精品自产拍在线观看蜜 | av电影亚洲| 狠狠色丁香久久综合网 | 亚洲三区在线 | 国内精品久久影院 | 国产精品自产拍在线观看蜜 | 亚洲永久精品国产 | 亚洲综合五月 | 中文字幕网站视频在线 | 狠狠操操操 | 超碰在线97国产 | 天天综合网久久综合网 | 精品亚洲成人 | 久久天天综合网 | 久久久久久久久毛片精品 | 制服丝袜欧美 | 中文字幕人成人 | 国产正在播放 | 精品久久久久久久久久久久久 | 国产精品久久片 | 在线免费黄色片 | 精品自拍sae8—视频 | 久草com| 亚洲成aⅴ人在线观看 | 久久人人爽人人爽人人片 | 国产亚洲精品福利 | 国产不卡精品视频 | 久久久久久久久久伊人 | 国产成人精品久久 | 国产精品2区 | 高清av不卡| 亚洲精品自在在线观看 | 波多野结衣电影一区二区 | 国产第一福利 | 精品中文字幕在线观看 | 五月婷香蕉久色在线看 | 日韩中文字幕网站 | 日日碰狠狠添天天爽超碰97久久 | av在线电影免费观看 | 日日射av | 91在线视频免费91 | 女人18片 | 亚洲精品久久久久久久蜜桃 | 日韩一区在线免费观看 | 久久久久久久久久久久亚洲 | 国产精品扒开做爽爽的视频 | 国产精品麻豆果冻传媒在线播放 | 99 精品 在线 | 中文字幕人成不卡一区 | 9ⅰ精品久久久久久久久中文字幕 | 色综合天天色综合 | 久久这里有精品 | 国产日韩欧美自拍 | 99精品欧美一区二区三区 | 99在线热播 | 久久精品国产免费 | 国产午夜精品一区二区三区欧美 | 中文免费在线观看 | 亚洲欧美在线观看视频 | 国产视频欧美视频 | 成年人毛片在线观看 | 在线视频免费观看 | 91视频成人免费 | 中午字幕在线观看 | 五月婷婷一区二区三区 | 日韩免费在线视频观看 | 久久精品99国产国产 | 一区二区三区免费在线观看 | 日韩免费av网址 | 久久五月婷婷丁香社区 | 99激情网| 国产在线观看污片 | 99国产精品视频免费观看一公开 | 欧美日韩一区二区在线观看 | 亚洲最新av| 九九久久久久久久久激情 | 久久精品看 | 久久成人一区二区 | 99久久婷婷国产综合亚洲 | 天天干天天拍天天操天天拍 | 天天操操 | 四虎小视频 | 国产中文字幕在线 | 黄色成人91 | 久久综合日 | 久久论理 | 999ZYZ玖玖资源站永久 | 综合精品在线 | 亚洲特级片 | 日韩欧美综合视频 | 草久久久久 | 日韩欧美99 | 天天综合导航 | 公开超碰在线 | 正在播放亚洲精品 | 欧美亚洲国产日韩 | 99综合电影在线视频 | 久久久国产精品一区二区中文 | 中文字幕在线一区观看 | 五月天九九 | 人人射人人射 | 久久久久免费看 | h久久| 免费日韩三级 | av东方在线 | 中文字幕av播放 | 一本一道波多野毛片中文在线 | 亚洲一区二区麻豆 | 麻豆视频在线观看免费 | 98涩涩国产露脸精品国产网 | 麻豆视频网址 | 美女视频国产 | 欧美另类成人 | www.天天综合 | 日韩一级网站 | 午夜.dj高清免费观看视频 | 国产艹b视频 | 国产成人一二片 | 日韩精品免费一区二区在线观看 | 成人免费电影 | 中文字幕有码在线观看 | 精品综合久久 | 在线看一区 | 国产精品成人a免费观看 | 日韩成人免费电影 | 四虎国产精品免费 | 美女福利视频 | 正在播放国产91 | 极品嫩模被强到高潮呻吟91 | 成人片在线播放 | 国产精品久久久久一区二区国产 | 国产精品久久99综合免费观看尤物 | 免费日韩 | 久久午夜影视 | 黄色一级大片在线免费看国产一 | 黄色国产区 | 亚洲精品自拍 | 亚洲精品欧洲精品 | 一区二区三区视频 | 欧美久久久久久久久久久久久 | 6080yy精品一区二区三区 | 国产v在线播放 | 一级一片免费观看 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 日日干天天操 | 99久久久久免费精品国产 | 91看片淫黄大片一级在线观看 | 在线精品观看 | 97天堂| 亚洲一级片在线看 | 精品综合久久 | av噜噜噜在线播放 | 黄色午夜网站 | 欧美精品天堂 | 亚洲激情综合 | 免费在线观看午夜视频 | 99这里只有久久精品视频 | 国产玖玖在线 | 久久九九久久九九 | 99免费精品 | 人人精久 | 国内综合精品午夜久久资源 | 天堂在线成人 | 免费久草视频 | 99这里有精品 | 国产一级免费电影 | 亚洲h色精品 | 成人国产精品久久久久久亚洲 | 久久激情视频 | 国产精品久久久久高潮 | www.99在线观看| 久久国产热| 久久久久久99精品 | 亚洲精品一区二区网址 | 日韩乱码在线 | 国产中文欧美日韩在线 | 在线观看精品一区 | 国产三级精品三级在线观看 | 日韩欧美一区二区三区视频 | 日韩三级.com| 黄色免费大片 | 欧美一二三专区 | 天天操偷偷干 | 在线免费观看欧美日韩 | 国产精品不卡在线观看 | 久久成人在线视频 | 欧美精品黑人性xxxx | 久免费 | 成年人在线观看网站 | 色婷婷视频在线 | 在线国产能看的 | 久久最新视频 | 国产成人高清av | 欧美在线视频一区二区三区 | 2017狠狠干| 美女黄视频免费 | 9999亚洲| 天天综合网 天天综合色 | 91在线成人 | 日韩精品一区二区三区水蜜桃 | 国外调教视频网站 | 久久精品免费电影 | 黄色在线免费观看网站 | 欧美乱码精品一区二区 | 91精品久| 国产亚洲永久域名 | 97视频在线播放 | 欧美另类激情 | 在线观看国产区 | 国偷自产视频一区二区久 | 欧美性生活久久 | av在线电影免费观看 | 深爱激情五月综合 | 亚洲专区视频在线观看 | av福利在线播放 | 国产免费又粗又猛又爽 | 久久久影片| 亚洲精品乱码久久久久久蜜桃不爽 | 久久精品久久久久 | 免费一级片在线 | 三级a视频 | 日韩在线观看网址 | 亚洲精品高清视频在线观看 | 五月天综合网站 | 久保带人 | 亚洲综合五月 | 在线成人性视频 | 久久综合九色综合97婷婷女人 | 天天色天天射天天综合网 | 欧洲av不卡 | 五月婷网 | 久久色视频 | 午夜精品成人一区二区三区 | 国产精品一区二区麻豆 | 蜜臀久久99静品久久久久久 | 国产专区精品视频 | 国产精品久久久久久吹潮天美传媒 | 日韩精品无码一区二区三区 | 欧美日韩一级视频 | 在线黄色av电影 | 五月的婷婷 | 91人人在线 | 91av99| 又色又爽又激情的59视频 | 99久久精品免费看国产四区 | 99精品国产高清在线观看 | 欧日韩在线视频 | 亚洲国产婷婷 | 国产精品视频不卡 | 在线免费观看视频一区二区三区 | 午夜三级理论 | 久久99免费观看 | 精品福利视频在线 | 欧美国产日韩一区二区三区 | 日韩电影在线一区二区 | 国产高清在线免费 | 精品国产一区二区三区噜噜噜 | 国产精品久久久久久电影 | 免费看一级一片 | 婷婷久久亚洲 | 亚洲国产精品久久久 | 久久久久久久久久久久亚洲 | 深爱五月网 | 日韩精品一区二 | 五月天久久综合 | 国产a国产a国产a | 日本中文字幕观看 | 骄小bbw搡bbbb揉bbbb | 五月婷婷免费 | 亚洲久草网 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 日韩在线观看一区二区三区 | 91桃色免费观看 | 少妇视频一区 | 少妇bbbb搡bbbb桶 | 国产三级国产精品国产专区50 | 97超级碰碰 | 精品国产一区二区三区日日嗨 | 美女黄视频免费 | 亚州精品天堂中文字幕 | 久久爱资源网 | 亚洲禁18久人片 | 亚洲精品综合久久 | 久久国产99| 亚洲最大的av网站 | 伊人手机在线 | 9999在线 | 超碰精品在线观看 | 午夜精品久久久久久久久久久久 | 999视频网| 玖玖视频网 | 中文字幕91视频 | 亚洲日韩中文字幕 | 少妇精品久久久一区二区免费 | 成人aⅴ视频| 亚洲国产午夜视频 | 久在线观看视频 | 人人要人人澡人人爽人人dvd | 开心色插| 久久精品人| 91污在线 | 91九色视频导航 | 日本午夜在线观看 | 日韩| av一级片在线观看 | 日本精品视频在线播放 | 亚洲 成人 欧美 | 亚洲国产中文字幕在线视频综合 | 久久这里只有精品久久 | 中文字幕一区二区三区久久蜜桃 | 日韩理论在线视频 | 免费成人在线视频网站 | 国产亚洲视频在线观看 | 在线观看视频免费大全 | 亚洲天天看 | 中文字幕 国产视频 | 久久久久久久久久国产精品 | 午夜影院一级片 | 欧美日韩天堂 | 91在线影院 | 天天拍天天色 | 免费成人在线网站 | 亚洲欧洲xxxx | 成人黄色国产 | 中文字幕丝袜 | 精品视频一区在线观看 | 99在线观看 | 久久亚洲专区 | 欧美日韩免费看 | 亚洲综合激情网 | 日韩在线观看第一页 | 成人久久久精品国产乱码一区二区 | 日韩黄在线观看 | 五月天久久久久久 | 欧美高清视频不卡网 | 免费av在线网| 欧美a级在线免费观看 | 色资源二区在线视频 | 国产一区在线免费 | 亚洲人在线视频 | 国产精品99久久久久久小说 | 久久国产区 | 婷婷久久久 | 在线观看国产一区二区 | av电影在线观看完整版一区二区 | 国产日韩精品在线观看 | 热久久免费视频 | 色综合久久88色综合天天人守婷 | 黄色资源在线 | 国产视频精品久久 |