青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

山寨:不是最好的,是最適合我們的!歡迎體驗山寨 中文版MSDN

Blog @ Blog

當華美的葉片落盡,生命的脈絡才歷歷可見。 -- 聶魯達

常用鏈接

統計

積分與排名

BBS

Blog

Web

最新評論

Win32串口操作的技巧

1.開啟一個 Serial Port:

  利用一般開啟檔案的 CreatFile() 即可開啟 serial port device用 CreateFile() API.

HANDLE CreateFile(
                  LPCTSTR lpFileName, 
// pointer to name of the file
                  DWORD dwDesiredAccess, // access (read-write) mode
                  DWORD dwShareMode, // share mode
                  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
                  DWORD dwCreationDistribution, // how to create
                  DWORD dwFlagsAndAttributes, // file attributes
                  HANDLE hTemplateFile // handle to file with attributes to copy
                  );
        lpFileName 為 "COM1" 或是 "COM2"
  dwDersiredAccess 一般為 GENERIC_READ|GENERIC_WRITE
  dwShareMode "必須"為 0, 即不能共享, 但同一個 process 中的不同 thread 在一開啟之后就可以共享.
  lpSecurityAttributes 一般為 NULL
  dwCreateionDistributon 在這里"必須"為 OPEN_EXISTING
  dwFlagsAndAttributes 定義了開啟的屬性, 若是設成 FILE_FLAG_OVERLAPPED 則可使用異步的 I/O.
  hTemplateFile "必須"為 NULL
  傳回檔案 handle
  設定 Serial Port 傳送及接收緩沖區的大小

  在開啟完 serial port 之后, 可以藉由呼叫 SetupComm() 來進行配置傳送時的緩沖區及接收時的緩沖區. 如果沒有呼叫 SetupComm() 的話, Win95 會配置內定的緩沖區

BOOL SetupComm(
               HANDLE hFile, 
// handle of communications device
               DWORD dwInQueue, // size of input buffer
               DWORD dwOutQueue // size of output buffer
               );

  2.關閉 Serial Port file

  利用一般的 CloseHandle() 即可.

BOOL CloseHandle(
                 HANDLE hObject 
// handle to object to close
                 )
  3.取得 Seial Port 的信息

  在 Win32 里頭, 將一些通訊時會用到的信息用 COMMPROP 這個結構來表示. (當然不僅僅是 Serial Port) 可以用 GetCommProperties() 來取得:

BOOL GetCommProperties(
                       HANDLE hFile, 
// handle of communications device
                       LPCOMMPROP lpCommProp // address of communications properties structure
                       );
      COMMPROP 長的像這個樣子:
typedef struct _COMMPROP // cmmp
    WORD wPacketLength; // packet size, in bytes
    WORD wPacketVersion; // packet version
    DWORD dwServiceMask; // services implemented
    DWORD dwReserved1; // reserved
    DWORD dwMaxTxQueue; // max Tx bufsize, in bytes
    DWORD dwMaxRxQueue; // max Rx bufsize, in bytes
    DWORD dwMaxBaud; // max baud rate, in bps
    DWORD dwProvSubType; // specific provider type
    DWORD dwProvCapabilities; // capabilities supported
    DWORD dwSettableParams; // changable parameters
    DWORD dwSettableBaud; // allowable baud rates
    WORD wSettableData; // allowable byte sizes
    WORD wSettableStopParity; // stop bits/parity allowed
    DWORD dwCurrentTxQueue; // Tx buffer size, in bytes
    DWORD dwCurrentRxQueue; // Rx buffer size, in bytes
    DWORD dwProvSpec1; // provider-specific data
    DWORD dwProvSpec2; // provider-specific data
    WCHAR wcProvChar[1]; // provider-specific data
}
 COMMPROP;
  在這里, lpCommProp 需要 programmer 自行配置空間. 有趣的問題是, 系統在這個結構之后會需要額外的空間. 但是配置者也就是 programmer 卻不知道系統會需要多少. 很簡單的做法是配置一大塊絕對會夠的空間. 另一個聰明的做法是執行兩次 GetCommProperties() , 第一次只配置 sizeof(COMMPROP) 這么大的空間, 因為還沒有開始執行一些動作, 所以系統并不會嘗試著在后面填東西, 所以不會出問題. 接著執行第一次的 GetCommProperties(), 得到結果, 取出結構中的 wPacketLength, 這個 member 代表實際上需要的大小, 然后依據這個大小重新配置一個新的. 這樣的話 , 就不會有浪費任何空間的問題了.

  至于上述 COMMPROP 結構的成員所代表的意思, on-line help 中應該寫的都滿清楚的 .

  4.設定及取得通訊狀態

 

  你可以利用 COMMPROP 來取得一些狀態, 但是當你想改變目前的設定時你需要兩個 API 來完成:

BOOL GetCommState(
                  HANDLE hFile, 
// handle of communications device
                  LPDCB lpDCB // address of device-control block structure
                  );

BOOL SetCommState(
                  HANDLE hFile, 
// handle of communications device
                  LPDCB lpDCB // address of device-control block structure
                  );

  你可以用 GetCommState() 來取得目前 Serial Port 的狀態, 也可以用 SetCommState() 來設定 Serial Port 的狀態.

  DCB 的結構就請自行翻閱 help 啰.

  另外, programmer 最常控制的幾個設定就是 baud rate, parity method, data bits, 還有 stop bit. BuildCommDCB() 提供了對于這幾個常見設定的控制.

BOOL BuildCommDCB(
                  LPCTSTR lpDef, 
// pointer to device-control string
                  LPDCB lpDCB // pointer to device-control block
                  );
lpDef 長的像這樣: "baud=2400 parity=N data=8 stop=1"

  5.通訊設定對話盒

  Win32 API 中提供了一個開啟通訊設定對話盒的 API: CommConfigDialog(), 當呼叫這個 API 時, 會蹦現一個可供設定 Baud Rate, Data Bits, Parity .. 等信息的對話盒, programmer 可以利用它來讓使用者設定一些信息, 并且取得結果.

BOOL CommConfigDialog(
                      LPTSTR lpszName, 
// pointer to device name string
                      HWND hWnd, // handle to window
                      LPCOMMCONFIG lpCC // pointer to comm. configuration structure
                      );
  其中 lpCC 被用來存放設定值的結果.
typedef struct _COMM_CONFIG {
    DWORD dwSize;
    WORD wVersion;
    WORD wReserved;
    DCB dcb;
    DWORD dwProviderSubType;
    DWORD dwProviderOffset;
    DWORD dwProviderSize;
    WCHAR wcProviderData[
1];
}
 COMMCONFIG, *LPCOMMCONFIG;

  在我們呼叫 CommConfigDialog() 之前, dwSize 要設為 sizeof(COMMCONFIG), wVersion 的值在這邊似乎不重要(我不清楚, VC5 的 on-line help 說可以設為 1, 我手中的 book 的范例是設為 0x100), 呼叫完 CommConfigDialog() 之后, 成員 dcb 中的 BaudRate, ByteSize, StopBits, Parity 就是使用者的設定.

  6.Timeout 的機制

  因為傳輸時并不會維持一個絕對穩定的速率. 因為傳輸品質的關系, programer 會需要 timeout 的機制來協助他們做一些控制. 在 Win32 通訊 Timeout 的機制中, timeout 的性質共分為兩類, 先來看看 COMMTIMEOUTS 這個結構:

typedef struct _COMMTIMEOUTS // ctmo
    DWORD ReadIntervalTimeout;
    DWORD ReadTotalTimeoutMultiplier;
    DWORD ReadTotalTimeoutConstant;
    DWORD WriteTotalTimeoutMultiplier;
    DWORD WriteTotalTimeoutConstant;
}
 COMMTIMEOUTS,*LPCOMMTIMEOUTS;
  programmer 可以利用 GetCommTimeouts() 和 SetCommTimeouts() 來讀取或是設定目前的 timeout 值.
BOOL GetCommTimeouts(
                     HANDLE hFile, 
// handle of communications device
                     LPCOMMTIMEOUTS lpCommTimeouts // address of comm. time-outs structure
                     );

BOOL SetCommTimeouts(
                     HANDLE hFile, 
// handle of communications device
                     LPCOMMTIMEOUTS lpCommTimeouts // address of communications time-out structure
                     );
第一種 timeout 的機制稱為 interval timeout, 從字面上的意義很容易可以理解這種 timeout 的機制是讀取字符之間的間隔時間的 timeout, 只有讀取字符時才能夠使用interval timeout. 也就是在這個結構中的 ReadIntervalTimeout, 單位為 ms, 當讀取完一個字符后, 超過了 ReadIntervalTimeout 的值, 卻還沒有讀到下一個字符時, timeout 就發生了.

  第二種 timeout 的機制稱為 total timeout, 顧名思義即是傳輸的總時間的 timeout . 在這種 timeout 的機制下, Win32 提供了一個具有彈性的方式來設定 total timeout. 以讀取的 total timeout 為例, 利用 ReadTotalTimeoutMultiplier 和 ReadTotalTimeoutConstant 構成了一個線性的上限值. 什么意思呢? 實際上的 total timeout 應該是這樣的一個式子:

  ReadTotalTimeout = ReadTotalTimeOutMultiplier * BytesToRead + ReadTotalTimeoutConstant

  WriteTotalTimeout 用同樣的公式來計算. 這樣的話, 不僅可以用一個固定的值來做為 timeout 值, 也可以用條線來做為 timeout 的值, 而隨著要讀取或是要寫的 bytes 數而變動.

  如果不想使用 timeout, 就把 COMMTIMEOUTS 里頭的資料成員都填為 0.

  如果你將 ReadIntervalTimeout 設為 MAXDWORD, 且將 ReadTotalTimeOutMultiplier 和 ReadTotalTimeoutConstant 都設為 0 的話, 那么讀取時, 如果 receive queue 里頭并沒有資料, 讀取的動作將會馬上返回, 而不會停滯在讀取的動作.

  這里有一個和 BuildCommDCB() 很像的 API 叫 BuildCommDCBAndTimeouts():


BOOL BuildCommDCBAndTimeouts(
                             LPCTSTR lpDef, 
// pointer to the device-control string
                             LPDCB lpDCB, // pointer to the device-control block
                             LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm. time-out structure
                             );

  lpDef 一樣是控制字符串, 可以給像 BuildCommDCB() 中的 lpDef 那樣格式的字符串, 但是多了 "TO=XXX" 這個設定. 如果 "TO=ON", 這個 API 會依據 lpCommTimeouts 里頭的值來設定讀和寫的 timeout 值. 如果 "TO=OFF", 則會設定這個 device 沒有 timeout. 如果是 "ON" 和 "OFF" 之外的其它值, 則 lpCommTimeouts 的設定將會被忽略.

  對了, 在設定完 timeout 值之后, 記得要檢查 COMMPROP 里的 dwProvCapabilities 中的 PCF_INTTIMEOUTS 和 PCF_TOTALTIMEOUTS 兩個 flags 是否有被 set, 以確認 interval timeout 和 total timeout 是否有支持.
  7.讀取資料

 

  從 serial port 里頭讀取資料就跟讀取一般的檔案一樣, 使用 ReadFile() 來達成.

BOOL ReadFile(
              HANDLE hFile, 
// handle of file to read
              LPVOID lpBuffer, // address of buffer that receives data
              DWORD nNumberOfBytesToRead, // number of bytes to read
              LPDWORD lpNumberOfBytesRead, // address of number of bytes read
              LPOVERLAPPED lpOverlapped // address of structure for data
              );

  要注意的是, nNumberOfBytesToRead 設定的是一次最多的讀取量, 很有可能所讀取的值(檢查 lpNumberOfBytesRead)小于這個值. 通常在錯誤發生或是 timeout 發生時這個 API 就會返回.

  PurgeComm() 這個 API 可以用來終止目前正在進行的讀或寫的動作, 也可以 flush 掉 I/O buffer 內等待讀或寫的資料.

 

BOOL PurgeComm(
               HANDLE hFile, 
// handle of communications resource
               DWORD dwFlags // action to perform
               );

其中 dwFlags 共有四種 flags:

  PURGE_TXABORT: 終止目前正在進行的(背景)寫入動作
  PURGE_RXABORT: 終正目前正在進行的(背景)讀取動作
  PURGE_TXCLEAR: flush 寫入的 buffer
  PURGE_RXCLEAR: flush 讀取的 buffer
  而使用 FlushFileBuffers() 可以確保所有的資料都被送出, 這個 API 才會返回.

  另外一個有趣的 API 是 ClearCommError(), 從字面上的意思看來, 它是用來清除錯誤情況用的, 但是實際上它還可以拿來取得目前通訊設備的一些信息.

 

BOOL ClearCommError(
                    HANDLE hFile, 
// handle to communications device
                    LPDWORD lpErrors, // pointer to variable to receive error codes
                    LPCOMSTAT lpStat // pointer to buffer for communications status
                    );

呼叫這個 API 之后, 關于通訊設備的一些信息會被儲存在 lpStat 中, COMSTAT 的結構如下:


typedef 
struct _COMSTAT // cst
    DWORD fCtsHold : 1// Tx waiting for CTS signal
    DWORD fDsrHold : 1// Tx waiting for DSR signal
    DWORD fRlsdHold : 1// Tx waiting for RLSD signal
    DWORD fXoffHold : 1// Tx waiting, XOFF char rec'd
    DWORD fXoffSent : 1// Tx waiting, XOFF char sent
    DWORD fEof : 1// EOF character sent
    DWORD fTxim : 1// character waiting for Tx
    DWORD fReserved : 25// reserved
    DWORD cbInQue; // bytes in input buffer
    DWORD cbOutQue; // bytes in output buffer
}
 COMSTAT, *LPCOMSTAT

藉由 fCtsHold, fDsrHold, fRlsdHold, fXoffHold, fXoffSent 可以知道目前因為什么因素而使通訊阻礙住了.( 跟 handshaking 和 flow control 有關) cbInque 和 cbOutQue 則可以顯示出還有多少 bytes 在讀取或是寫入 queue 中.

  8.寫入資料

  和讀取資料一樣, programmer 可以使用 WriteFile() 來將資料寫入 serial port.

BOOL WriteFile(
               HANDLE hFile, 
// handle to file to write to
               LPCVOID lpBuffer, // pointer to data to write to file
               DWORD nNumberOfBytesToWrite, // number of bytes to write
               LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
               LPOVERLAPPED lpOverlapped // pointer to structure needed for overlapped I/O
               );

  關于通訊設備的寫入有三個很有趣的 API, 它們分別是 SetCommBreak(), ClearCommBreak, 和 TransmitCommChar().

 

BOOL SetCommBreak(
                  HANDLE hFile 
// handle of communications device
                  );

BOOL ClearCommBreak(
                    HANDLE hFile 
// handle to communications device
                    );

BOOL TransmitCommChar(
                      HANDLE hFile, 
// handle of communications device
                      char cChar // character to transmit
                      );

  SetCommBreak() 是用來暫停目前的傳輸作業, 它會使 buffer 中的資料都不再被送出, 這個時候, program 可以去做些雜七雜八的事, 之后, 再利用 ClearCommBreak() 回復傳輸作業.

  TransmitCommChar() 是用來立即性的趕在所有 buffer 數據被送出去之前, 傳輸一個字符的數據出去, 即使 buffer 中還有資料. 換句話說, 這個字符有最高的優先權被送出去.

  9.事件驅動式的 I/O

  在 Win32 里頭, 對于通訊設備的 I/O 可以用像是事件驅動式的方法來達成. 主要是利用一個叫 WaitCommEvent() 的 API. 呼叫這個 API 之后, 會一直 block 到設定的事件發生之后才會返回. 我們先來看看如何設定事件, 再回過頭來看 WaitCommEvent() .

  programer 可以用 GetCommMask() 和 SetCommMask() 來取得或是設定目前設定的通訊事件.

 

BOOL GetCommMask(
                 HANDLE hFile, 
// handle of communications device
                 LPDWORD lpEvtMask // address of variable to get event mask
                 );

BOOL SetCommMask(
                 HANDLE hFile, 
// handle of communications device
                 DWORD dwEvtMask // mask that identifies enabled events
                 );

  可以設定的事件有 EV_BREAK, EV_CTS, EV_DSR, EV_ERR, EV_RING, EV_RLSD, EV_RXCHAR, EV_RXFLAG, EV_TXEMPTY.(其意義請自行參考 help), 當然, 你可以把它們 or 起來成為組合的事件.

  在設定完想要處理的事件之后, 可以使用 WaitCommEvent()

BOOL WaitCommEvent(
                   HANDLE hFile, 
// handle of communications device
                   LPDWORD lpEvtMask, // address of variable for event that occurred
                   LPOVERLAPPED lpOverlapped, // address of overlapped structure
                   );

  WaitCommEvent() 會一直 block 到你所設定的通訊事件發生為止. 所以當 WaitCommEvent() 返回時, 你可以由 lpEvtMask 取得究竟是那一事件發生, 再來決定要如何處理.

  舉例來說, 可以用 SetCommMask() 設定事件為 EV_RXCHAR, 那么在呼叫 WaitCommEvent() 時, 它會等到有字符可供讀取時才會返回, 那么在它返回之后, 可以檢查一下 lpEvtMask 中是否 set 了 EV_RXCHAR, 如果是的話就可以用 ReadFile() 去讀取. 這樣的話, 可以避免掉某些情形之下, 需要做 polling 所引起效率不彰的問題.

  10.錯誤的處理

  前面提過的 ClearnCommError() 可以用來取得目前發生錯誤的原因.(請參見 help)

  11.硬件的控制命令

  Win32 中提供了 EscapeCommFunction() 允許 programer 對幾個硬件訊號做控制.

BOOL EscapeCommFunction(
                        HANDLE hFile, 
// handle to communications device
                        DWORD dwFunc // extended function to perform
                        );

  其中 dwFunc 可以是:

CLRDTR : 讓 DTR OFF
CLRRTS : 讓 RTS OFF
SETDTR : 讓 DTR ON
SETRTS : 讓 RTS ON
SETXOFF : "仿真" 接收到 XOFF 字符
SETXON : "仿真" 接收到 XON 字符
SETBREAK : 和 SetCommBreak() 的意思相同
CLRBREAK : 和 ClearCommBreak() 的意思相同

posted on 2008-01-08 11:34 isabc 閱讀(2464) 評論(0)  編輯 收藏 引用 所屬分類: 串口通信

廣告信息(免費廣告聯系)

中文版MSDN:
歡迎體驗

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久福利一区| 亚洲福利视频二区| 午夜精品久久久久久久久久久久久 | 国产精品久久国产精品99gif| 一区二区av在线| 99精品黄色片免费大全| 欧美午夜无遮挡| 欧美中文字幕在线视频| 久久国产成人| 日韩亚洲精品在线| 亚洲一区二区三区精品视频 | 欧美一区国产一区| 在线免费高清一区二区三区| 亚洲黄网站黄| 国产农村妇女毛片精品久久麻豆| 久久精品国产亚洲高清剧情介绍| 久久久美女艺术照精彩视频福利播放 | 久久频这里精品99香蕉| 亚洲免费播放| 欧美一区二区三区视频免费| 亚洲欧洲日产国码二区| 亚洲午夜一区| 亚洲国产专区| 亚洲影院免费观看| 亚洲另类一区二区| 午夜亚洲视频| 亚洲天堂视频在线观看| 久久国产精品第一页| 一本一本a久久| 久久一区二区三区国产精品 | 狠狠v欧美v日韩v亚洲ⅴ| 亚洲国产视频一区二区| 国产精品一区二区黑丝| 亚洲三级电影在线观看| 韩日欧美一区| 亚洲一区观看| 艳妇臀荡乳欲伦亚洲一区| 欧美专区中文字幕| 亚洲欧美日韩天堂| 欧美理论视频| 亚洲国产91| 亚洲电影免费| 久久精品国产清高在天天线 | 亚洲国产专区校园欧美| 亚洲一区二区三区在线视频 | 国产精品高潮呻吟久久av无限| 免费精品视频| 国产亚洲一级高清| 亚洲一区999| 一区二区三区 在线观看视频| 久久精品视频在线免费观看| 午夜精品一区二区在线观看| 欧美日韩精品免费看| 欧美刺激性大交免费视频| 韩国免费一区| 久久国产日韩欧美| 久久噜噜亚洲综合| 激情av一区二区| 欧美一区在线看| 久久久久在线| 黄色成人在线网站| 久久成人国产精品| 久久精品一区| 国内精品久久久久久 | 欧美a级片网站| 欧美激情视频免费观看| 亚洲黄色成人网| 模特精品在线| 亚洲人成网站色ww在线| 一区二区欧美亚洲| 欧美日韩成人综合| 这里只有精品在线播放| 亚洲欧美日韩在线不卡| 国产精品老女人精品视频| 亚洲欧美另类国产| 久久只精品国产| 亚洲青色在线| 欧美无砖砖区免费| 亚洲欧美美女| 免费观看欧美在线视频的网站| 在线成人av| 欧美日韩国产二区| 亚洲图片欧洲图片av| 久久国内精品自在自线400部| 国产在线精品一区二区夜色| 久久午夜羞羞影院免费观看| 亚洲高清一区二| 亚洲一区二区精品在线| 国产婷婷97碰碰久久人人蜜臀| 久久精品国产亚洲高清剧情介绍| 鲁大师成人一区二区三区| 亚洲欧洲精品一区二区三区波多野1战4 | 欧美人与禽性xxxxx杂性| 夜夜爽www精品| 久久福利一区| 亚洲精品在线看| 国产噜噜噜噜噜久久久久久久久| 欧美中文字幕视频在线观看| 男人的天堂亚洲在线| 亚洲视频电影图片偷拍一区| 国产视频自拍一区| 欧美电影免费观看高清| 亚洲一区在线免费观看| 免费在线国产精品| 亚洲在线一区二区三区| 在线看视频不卡| 国产精品视频免费一区| 美女主播一区| 午夜精彩国产免费不卡不顿大片| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲电影下载| 欧美伊久线香蕉线新在线| 亚洲国产三级| 国产丝袜美腿一区二区三区| 欧美精品在线播放| 久久躁日日躁aaaaxxxx| 亚洲女同性videos| 日韩视频免费| 亚洲国产激情| 免费成人毛片| 久久国产婷婷国产香蕉| 一区二区欧美日韩视频| 亚洲国产成人在线视频| 国产午夜精品视频| 欧美亚洲成人网| 欧美精品黄色| 欧美1区2区3区| 久久久久在线观看| 欧美在线国产| 香蕉成人久久| 亚洲尤物在线视频观看| 亚洲欧洲综合| 亚洲高清资源| 亚洲福利久久| 亚洲电影成人| 亚洲第一搞黄网站| 欧美国产视频一区二区| 久久综合亚洲社区| 久久久精品一区| 久久精品欧美日韩| 久久精品青青大伊人av| 欧美在线观看一区| 欧美在线free| 久久精品国产亚洲精品| 久久精品理论片| 久久久人成影片一区二区三区| 久久精品99国产精品日本| 欧美在线一级视频| 久久九九国产精品| 久久天天狠狠| 欧美顶级大胆免费视频| 亚洲高清视频在线| 亚洲精品中文字幕有码专区| 亚洲精品久久久久中文字幕欢迎你 | 久久av一区二区三区漫画| 欧美一级片一区| 久久久久欧美精品| 欧美粗暴jizz性欧美20| 亚洲国产日韩精品| 一区二区三区四区蜜桃| 亚洲一区二区在线视频| 欧美一二三区在线观看| 久久看片网站| 欧美激情精品久久久久久变态| 欧美激情一区二区三区| 欧美午夜视频在线| 国产尤物精品| 亚洲精品一区二区三区av| 亚洲一区二区av电影| 久久精品国产99国产精品澳门 | 亚洲小说欧美另类婷婷| 欧美亚洲免费电影| 欧美777四色影视在线| 亚洲欧洲日产国产综合网| 一区二区三区久久| 久久国产一区二区| 欧美日韩国产二区| 国产亚洲欧美日韩一区二区| 亚洲精品日韩精品| 性久久久久久| 亚洲大黄网站| 欧美一区二区三区久久精品| 免费短视频成人日韩| 国产精品亚洲欧美| 在线观看久久av| 午夜日韩av| 欧美激情一区二区三区在线| 亚洲在线第一页| 欧美激情在线播放| 激情国产一区| 午夜精品免费视频| 亚洲国产美女精品久久久久∴| 亚洲一区二区在线播放| 欧美激情一区二区三级高清视频| 国产农村妇女精品一区二区| 亚洲麻豆视频| 免费亚洲电影在线| 欧美一区二区成人| 国产精品久久一区二区三区| 亚洲精品欧美激情|