色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于N32G435的高負載串口通信

國民技術股份有限公司 ? 2022-09-22 17:28 ? 次閱讀

一、前言

單片機中,USART通信是最常用也是最先去接觸的串口外設,在小數據量應用中一般不需要考慮USART串口(以下簡稱為串口)的高負載能力,比如打印一下log,接收幾個其他設備的指令或者發送幾個指令控制其他設備。但是在高速的大數據量的通信場合,串口可能會承載較高的數據負載,如果不合理地進行單片機的資源利用,則有可能造成各種問題。比如使用串口接收中斷接收大量的數據,頻繁地進入中斷,會占用太多的CPU資源。這時可能會想到【空閑中斷+DMA傳輸完成中斷】的方式接收大量數據,但是這是一個極具風險的行為,假設一下,DMA數據傳輸結束之后,此時CPU開始讀取DMA緩存中的數據,此時又有新的數據進來,新的數據就會覆蓋之前的數據導致異常。

二、如何啟用串口的DMA功能

在討論如何實現串口的高負載通信之前,我們得先明白如何啟用串口的DMA通信。

DMA(DirectMemoryAccess)直接儲存器訪問,是一個CPU用于數據從一個地址空間到另一個地址空間的搬運組件,該過程無需CPU的干預,不占用CPU的資源,可以使單片機這種單線程CPU實現“偽多線程”。只需在數據搬運結束后通知CPU即可。

在國民技術的資料中是有串口+DMA的例程的,但是官方為了用戶調試方便,例程相對簡單,就是實現了兩個MCU串口間的DMA通信,在開發時具有一定借鑒意義,但是不具備高負載能力,同時移植性不是很好,這里我在例程的基礎上進行簡化,同時例程不具備的功能也會一一展開。

1.串口+DMA發送

#defineTxBufferSize1 (countof(TxBuffer1) - 1)

#definecountof(a) (sizeof(a) / sizeof(*(a)))

USART_InitTypeUSART_InitStructure;

uint8_tTxBuffer1[20] ={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a};

首先是定義一些相關的變量,數據和結構體啥的,TxBufferSize1發送數量,TxBuffer1[20]發送的數組。

/**

*[url=home.php?mod=space&uid=247401]@brief[/url] Configures thedifferent system clocks.

*/

voidRCC_Configuration(void)

{

/*DMA clock enable */

RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA,ENABLE);

/*Enable GPIO clock */

RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB,ENABLE);

/*Enable USARTy and USARTz Clock */

RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1,ENABLE);

}

/**

*[url=home.php?mod=space&uid=247401]@brief[/url] Configures thedifferent GPIO ports.

*/

voidGPIO_Configuration(void)

{

GPIO_InitTypeGPIO_InitStructure;

/*Initialize GPIO_InitStructure */

GPIO_InitStruct(&GPIO_InitStructure);

/*Configure USARTy Tx as alternate function push-pull */

GPIO_InitStructure.Pin = GPIO_PIN_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Alternate= GPIO_AF0_USART1;

GPIO_InitPeripheral(GPIOB,&GPIO_InitStructure);

/*Configure USARTy Rx as alternate function push-pull and pull-up */

GPIO_InitStructure.Pin = GPIO_PIN_7;

GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;

GPIO_InitStructure.GPIO_Alternate= GPIO_AF0_USART1;

GPIO_InitPeripheral(GPIOB,&GPIO_InitStructure);

}

對相關的時鐘和串口的引腳進行初始化,這里是直接用的官方例程,只不過將官方例程的宏定義換成了實際的值,便于看代碼,不然還需跳轉,但是官方的例程這方面的可移植性會更好。

voidDMA_Configuration(void)

{

DMA_InitTypeDMA_InitStructure;

/*USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */

DMA_DeInit(DMA_CH4);

DMA_StructInit(&DMA_InitStructure);

DMA_InitStructure.PeriphAddr = (USART1_BASE + 0x04);

DMA_InitStructure.MemAddr = (uint32_t)TxBuffer1;

DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;

DMA_InitStructure.BufSize = TxBufferSize1;

DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;

DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;

DMA_InitStructure.PeriphDataSize= DMA_PERIPH_DATA_SIZE_BYTE;

DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;

DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;

DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;

DMA_Init(DMA_CH4,&DMA_InitStructure);

DMA_RequestRemap(DMA_REMAP_USART1_TX,DMA, DMA_CH4, ENABLE);

}

DMA的初始化采用NORMAL模式,即只發送一次,當計數器為0時便不再搬運數據。

voidUART_Init(USART_Module* USARTx,uint32_t BaudRate)

{

/*USARTy and USARTz configuration ---------------------------*/

USART_StructInit(&USART_InitStructure);

USART_InitStructure.BaudRate = BaudRate;

USART_InitStructure.WordLength = USART_WL_8B;

USART_InitStructure.StopBits = USART_STPB_1;

USART_InitStructure.Parity = USART_PE_NO;

USART_InitStructure.HardwareFlowControl= USART_HFCTRL_NONE;

USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;

/*Configure USARTy and USARTz */

USART_Init(USARTx,&USART_InitStructure);

/*Enable USARTy DMA Rx and TX request */

USART_EnableDMA(USARTx,USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE);

/*Enable the USARTy and USARTz */

USART_Enable(USARTx,ENABLE);

}

串口的初始化。

voidDMA_send(uint8_t* pBuffer,uint16_t BufferLength)

{

DMA_EnableChannel(DMA_CH4,DISABLE);

DMA_SetCurrDataCounter(DMA_CH4,BufferLength);

DMA_EnableChannel(DMA_CH4,ENABLE);

while(USART_GetFlagStatus(USART1, USART_FLAG_TXDE) == RESET)

{

}

}

DMA的發送函數,先失能DMA通道,再重新設置傳輸長度,再使能DMA通道,這里是檢測while是檢測串口的發送完成編制位,在官方的demo中檢測的是DMA的通道完成標志,這個在這里面是不可以的,因為DMA的搬運速度是遠大于串口的通信速度的,如果檢測DMA通道完成標志,會導致DMA已經將數據搬運到串口的數據寄存器,但是因為串口的速度不夠,導致此時數據還未送出,而因為例程只循環一次,在測試例程時看不出問題,但是這里會出問題。

intmain(void)

{

/*System Clocks Configuration */

RCC_Configuration();

/*Configure the GPIO ports */

GPIO_Configuration();

/*Configure the DMA */

DMA_Configuration();

UART_Init(USART1,115200);

while(1)

{

DMA_send(TxBuffer1,20);

Delay(10000000);

}

}

最后在主函數調用各初始化函數,在while(1)中循環發送便可實現最簡單的串口+DMA發送。

875f42f4-39f0-11ed-b180-dac502259ad0.png

2.串口+DMA接收

在上面發送的基礎上我們加上DMA的接收功能,此處需要解釋一下下面的操作:為了對應手冊,上面的串口發送DMA通道原來是CH4,我下面全部改成CH1。

uint8_tRxBuffer1[20];

定義一個數組用于接收串口數據。

USART_ConfigInt(USARTx,USART_INT_IDLEF, ENABLE);

添加串口中斷定義。

voidNVIC_Configuration(void)

{

NVIC_InitTypeNVIC_InitStructure;

/*Enable the USARTz Interrupt */

NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

添加NVIC配置。

voidDMA_Configuration(void)

{

DMA_InitTypeDMA_InitStructure;

/*USARTy TX DMA1 Channel (triggered by USARTy Tx event) Config */

DMA_DeInit(DMA_CH1);

DMA_StructInit(&DMA_InitStructure);

DMA_InitStructure.PeriphAddr= (USART1_BASE + 0x04);

DMA_InitStructure.MemAddr= (uint32_t)TxBuffer1;

DMA_InitStructure.Direction= DMA_DIR_PERIPH_DST;

DMA_InitStructure.BufSize= TxBufferSize1;

DMA_InitStructure.PeriphInc= DMA_PERIPH_INC_DISABLE;

DMA_InitStructure.DMA_MemoryInc= DMA_MEM_INC_ENABLE;

DMA_InitStructure.PeriphDataSize= DMA_PERIPH_DATA_SIZE_BYTE;

DMA_InitStructure.MemDataSize= DMA_MemoryDataSize_Byte;

DMA_InitStructure.CircularMode= DMA_MODE_NORMAL;

DMA_InitStructure.Priority= DMA_PRIORITY_VERY_HIGH;

DMA_InitStructure.Mem2Mem= DMA_M2M_DISABLE;

DMA_Init(DMA_CH1,&DMA_InitStructure);

DMA_RequestRemap(DMA_REMAP_USART1_TX,DMA, DMA_CH1, ENABLE);

DMA_DeInit(DMA_CH2);

DMA_InitStructure.PeriphAddr= (USART1_BASE + 0x04);

DMA_InitStructure.MemAddr= (uint32_t)RxBuffer1;

DMA_InitStructure.Direction= DMA_DIR_PERIPH_SRC;

DMA_InitStructure.BufSize= TxBufferSize1;

DMA_Init(DMA_CH2,&DMA_InitStructure);

DMA_RequestRemap(DMA_REMAP_USART1_RX,DMA, DMA_CH2, ENABLE);

}

添加DMA的接收,并將通道設置為CH2。

voidDMA_Revice(uint16_t BufferLength)

{

DMA_EnableChannel(DMA_CH2,DISABLE);

DMA_SetCurrDataCounter(DMA_CH2,BufferLength);

DMA_EnableChannel(DMA_CH2,ENABLE);

}

添加DMA接收函數

voidUSART1_IRQHandler(void)

{

if(USART_GetIntStatus(USART1, USART_INT_IDLEF) != RESET)

{

/*軟件先讀USART_STS,再讀USART_DAT清除空閑中斷標志。*/

USART1->STS;

USART1->DAT;

for(inti=0;i<20;i++)

{

TxBuffer1[i]= RxBuffer1[i];

}

DMA_send(20);

DMA_Revice(20);

}

}

添加串口中斷函數,在串口中斷函數中將接收的數據傳給DMA發送數組,再通過DMA的方式發送出來用于校驗結果。

87819e58-39f0-11ed-b180-dac502259ad0.png

通過串口助手可觀測數據正確。至此,常見的串口+DMA的發送與接收完成。后文將實現高負載的通信。

三、高負載情況下的DMA如何實現

在串口數據量較大時,一般使用雙BUF,很多單片機有硬件雙緩沖,DMA的目標儲存區域有兩個,當一次完整的數據傳輸結束后,也就是counter值變為0時,DMA會自動將數據指向另一塊區域。這樣用戶就有時間去處理剛存滿的buf,而不會被覆蓋。就是“乒乓緩存”。

普通DMA

8794a61a-39f0-11ed-b180-dac502259ad0.png

DMA雙緩沖

87b6f90e-39f0-11ed-b180-dac502259ad0.png

大致流程如下:

1.串口有數據到來,DMA現將數據儲存在內存1,完成后通知CPU過來處理數據。

2.此時DMA不停下,開始將后續的數據搬運到內存2。

3.內存2的數據搬運完成,通知CPU開始處理內存2中的數據。

4.如果數據傳輸還未結束,此時DMA會將數據儲存在內存1。如此循環,直至沒有數據到來。

但是遺憾的是N32G435這塊芯片不具備雙緩沖模式,那么我們可以主動控制DMA跳轉內存區域。利用“傳輸過半中斷”來模擬雙緩沖模式。

大致流程如下:

1.DMA完成搬運一半的數據時,產生一個傳輸過半中斷,此時我們讓CPU來處理上一半數據。

2.DMA數據搬運未停止,此時繼續搬運后一半數據,此操作不會影響前面一半的數據處理。

3.DMA數據搬運完,觸發傳輸完成中斷,這時CPU可以處理后半數據。

4.如果數據傳輸還未結束,DMA繼續將數據向前半搬運,如此循環。

87c9e38e-39f0-11ed-b180-dac502259ad0.png

代碼講解如下:

以下代碼完整流程如下:

1.配置串口波特率2.5M,DMA的BufSize設置為40,開啟傳輸過半中斷,傳輸完成中斷,串口空閑中斷。

2.啟動DMA接收。

3.通過串口助手發送80個數據到串口。

4.當DMA接收數組接收到20個數據觸發傳輸過半中斷,跳轉中斷函數將20個數據存放到數組中。

5.此時DMA仍在運行,但是數據存放在DMA接收數組的后20個地址空間。

6.當DMA接收數組填滿,觸發DMA傳輸完成中斷,跳轉中斷函數將后20個數據保存,此時DMA一共搬運了40個數據。

7.DMA繼續搬運數據到接收數組里,此時會覆蓋之前的前二十個數據,跳轉到步驟4.

8.接收完80個數據,此時觸發串口空閑中斷,將接收到的數據打印出來。

在上面代碼基礎上做如下操作:

1.將DMACH2通道設置為循環模式,測試階段將BufSize設置為40,開啟傳輸過半中斷和傳輸完成中斷。同時為了測試高速場景,串口波特率設置為2.5M:

DMA_DeInit(DMA_CH2);

DMA_InitStructure.PeriphAddr= (USART1_BASE + 0x04);

DMA_InitStructure.MemAddr= (uint32_t)buffer;

DMA_InitStructure.Direction= DMA_DIR_PERIPH_SRC;

DMA_InitStructure.BufSize= 40;

DMA_InitStructure.CircularMode= DMA_MODE_CIRCULAR;

DMA_Init(DMA_CH2,&DMA_InitStructure);

DMA_RequestRemap(DMA_REMAP_USART1_RX,DMA, DMA_CH2, ENABLE);

DMA_ConfigInt(DMA_CH2,DMA_INT_HTX,ENABLE);//半傳輸中斷

DMA_ConfigInt(DMA_CH2,DMA_INT_TXC,ENABLE);//傳輸完成中斷

DMA_ClearFlag(DMA_FLAG_HT2,DMA);//清除標志位,避免第一次傳輸出錯

DMA_ClearFlag(DMA_FLAG_TC2,DMA);

DMA_ClrIntPendingBit(DMA_INT_HTX2,DMA);

DMA_ClrIntPendingBit(DMA_INT_TXC2,DMA);

2.NVIC設置DMA通道中斷

voidNVIC_Configuration(void)

{

NVIC_InitTypeNVIC_InitStructure;

/*Enable the USARTz Interrupt */

NVIC_InitStructure.NVIC_IRQChannel= USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority= 1;

NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;

NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel= DMA_Channel2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;

NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

3.添加DMA的CH2中斷函數,num為全局變量,目的是將所有的數據保存進buf數組:

voidDMA_Channel2_IRQHandler(void)

{

//傳輸半滿

if(DMA_GetIntStatus(DMA_INT_HTX2,DMA)== SET)

{

DMA_ClrIntPendingBit(DMA_INT_HTX2,DMA);

DMA_ClearFlag(DMA_FLAG_HT2,DMA);

for(inti=0;i<20;i++)

{

buf[num]= buffer[i];

num++;

}

}

//傳輸滿

if(DMA_GetIntStatus(DMA_INT_TXC2,DMA)== SET)

{

DMA_ClrIntPendingBit(DMA_INT_TXC2,DMA);

DMA_ClearFlag(DMA_FLAG_TC2,DMA);

for(inti=20;i<40;i++)

{

buf[num]= buffer[i];

num++;

}

}

}

4.在串口空閑中斷中將收到的數據全部打印出來。

voidUSART1_IRQHandler(void)

{

if(USART_GetIntStatus(USART1, USART_INT_IDLEF) != RESET)

{

/*軟件先讀USART_STS,再讀USART_DAT清除空閑中斷標志。*/

USART1->STS;

USART1->DAT;

for(inti=0;i<80;i++)

{

TxBuffer1[i]= buf[i];

}

DMA_send(80);

num=0;

}

}

5.測試結果如下,在2.5M波特率的情況下保持數據完整。

87df6632-39f0-11ed-b180-dac502259ad0.png

寫在最后

這次主要討論了一種高負載情況下如何緩解CPU壓力的方法,所言所寫不盡完善,例如不定數據接收,就可以通過DMA_GetCurrDataCounter(DMA_CH2);函數進行傳輸數據的統計計算,這點大家可以自由發揮,現實可能遇到的問題是多種多樣的,主要在于關鍵能力的拓展。更多的還需要根據實際情況靈活配置。

閱讀原文:https://bbs.21ic.com/icview-3209220-1-1.html

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 通信
    +關注

    關注

    18

    文章

    6037

    瀏覽量

    136093
收藏 人收藏

    評論

    相關推薦

    【正點原子STM32H7R3開發套件試用體驗】按鍵、串口通信

    { if ((times % 5000) == 0) { printf(\"\\\\r\\\\n正點原子 H7R3開發板 串口通信實驗\\\\r\\\\n\"
    發表于 12-30 16:53

    串口通信原理解析 串口與并口的區別

    在計算機硬件和通信領域,串口(Serial Port)和并口(Parallel Port)是兩種常見的數據傳輸接口。它們在數據傳輸方式、速度、應用場景等方面有著明顯的區別。 串口通信
    的頭像 發表于 12-27 09:50 ?346次閱讀

    串口通信的開發環境配置

    串口通信的開發環境配置涉及多個方面,包括選擇編程語言、安裝必要的庫或驅動程序、配置串口參數等。以下是一個基于Python的串口通信開發環境配
    的頭像 發表于 11-22 09:21 ?273次閱讀

    使用Python進行串口通信的案例

    當然!以下是一個使用Python進行串口通信的簡單示例。這個示例展示了如何配置串口、發送數據以及接收數據。我們將使用 pyserial 庫,這是一個非常流行的用于串口
    的頭像 發表于 11-22 09:11 ?246次閱讀

    串口通信與并口通信的區別

    在計算機和電子設備的數據傳輸領域,串口通信(Serial Communication)和并口通信(Parallel Communication)是兩種基本的通信方式。它們各自有著獨特的
    的頭像 發表于 11-22 09:04 ?747次閱讀

    串口通信協議解析 串口通信應用實例

    串口通信協議解析 串口通信協議是指規定了數據包的內容,內容包含了起始位、主體數據、校驗位及停止位,雙方需要約定一致的數據包格式才能正常收發數據的有關規范。以下是
    的頭像 發表于 11-21 17:03 ?565次閱讀

    串口屏如何與主控制器進行通信

    一、串口通信基礎 串口通信是一種通過串行數據傳輸的方式進行通信的方法。在串口
    的頭像 發表于 11-20 09:32 ?215次閱讀
    <b class='flag-5'>串口</b>屏如何與主控制器進行<b class='flag-5'>通信</b>?

    為什么通信要使用虛擬串口串口助手?

    串口助手和虛擬串口是什么?串口助手和虛擬串口串口通信中很常見。
    的頭像 發表于 11-15 01:04 ?1158次閱讀
    為什么<b class='flag-5'>通信</b>要使用虛擬<b class='flag-5'>串口</b>和<b class='flag-5'>串口</b>助手?

    干貨篇:低功耗4G模組Air780E的串口通信

    ? 今天我們來講解低功耗4G模組Air780E的串口通信的基本用法,小伙伴們,學起來吧!
    的頭像 發表于 10-05 14:38 ?583次閱讀
    干貨篇:低功耗4<b class='flag-5'>G</b>模組Air780E的<b class='flag-5'>串口</b><b class='flag-5'>通信</b>

    用AT32F435CGU7做了個通訊板,用串口調試助手看到,電路板有輸出,但是亂碼,為什么?

    我用AT32F435CGU7做了個通訊板,采用UART2與計算機進行通訊。結果,用串口調試助手看到,電路板有輸出,但是亂碼。我用串口本該發送 char send_str[]=”where are you!\\
    發表于 09-27 08:19

    串口通信的基本概念

    串口通信(Serial Communications)的基本概念可以歸納為以下幾個方面:
    的頭像 發表于 06-12 09:28 ?700次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>通信</b>的基本概念

    什么是串口通信?它有哪些特點和應用?

    在現代電子通信和計算機領域中,串口通信(Serial Communications)扮演著至關重要的角色。它是一種按位(bit)發送和接收字節的通信方式,能夠實現數據的遠距離傳輸和高效
    的頭像 發表于 05-23 16:23 ?2539次閱讀

    VC++串口通信詳解

    電子發燒友網站提供《VC++串口通信詳解.doc》資料免費下載
    發表于 03-24 09:36 ?0次下載

    UART串口通信協議是什么?

    UART (Universal Asynchronous Receiver/Transmitter) 是一種通信接口協議,用于實現串口通信。它是一種簡單的、可靠的、廣泛應用的串口
    的頭像 發表于 03-19 17:26 ?1427次閱讀

    QT串口通信的簡單使用

    QT串口通信是上位機和下位機通信常用的通信方式, 也是學習QT必須學會的基礎知識, 這篇就簡單介紹一下QT串口
    的頭像 發表于 01-15 09:27 ?2064次閱讀
    QT<b class='flag-5'>串口</b><b class='flag-5'>通信</b>的簡單使用
    主站蜘蛛池模板: 激情女人花| 久久久视频2019午夜福利| 久久99精品国产99久久6男男| 无限资源在线观看高清| 国产互换后人妻的疯狂VIDEO| 色戒床震视频片段| 国产精品99精品无码视亚| 午夜亚洲WWW湿好爽| 狠狠色狠狠色狠狠五月ady| 一边亲着一面膜下的免费过程 | https黄视| 日本免费xxx| 国产精品人妻无码久久久蜜桃 | 学生妹被爆插到高潮无遮挡| 国产中文字幕乱码免费| 影888午夜理论不卡| 免费视频精品38| 动漫美女人物被黄漫在线看| 午夜福利理论片高清在线| 花蝴蝶在线观看中字| 4399日本电影完整版在线观看免费 | 色琪琪无码成人AV视频| 国产又色又爽又刺激在线播放| 亚洲一区在线观看无码欧美| 美女叉腿掰阴大胆艺术照| 范冰冰hdxxxx| 亚洲人视频在线| 欧美阿v在线天堂| 国产精品野外AV久久久| 岳的奶大又白又胖| 人妻中文字幕无码系列| 果冻传媒APP免费网站在线观看| 最近韩国HD免费观看国语| 日韩精品一区二区中文| 黑人寄宿羽月希产后奶水| 97视频在线免费播放| 卫生间被教官做好爽HH视频| 久久视热频这里只精品| 大地影院免费观看视频| 艳鉧动漫1~6全集观看在线| 日本成熟bbxxxxxxxx|