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

山寨:不是最好的,是最適合我們的!歡迎體驗山寨 中文版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 閱讀(2455) 評論(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>
            欧美日韩在线播放三区| 美女视频网站黄色亚洲| 国产精品va在线| 亚洲天堂av综合网| 亚洲午夜电影在线观看| 国产精品免费看片| 久久爱www久久做| 久久九九精品99国产精品| 在线观看91精品国产麻豆| 亚洲国产精品ⅴa在线观看 | 亚洲欧美在线一区| 欧美在线3区| 亚洲日韩视频| 国产伦精品一区二区三区在线观看| 亚洲欧美日韩视频二区| 久久爱www久久做| 亚洲国产一区二区视频| 中文国产成人精品久久一| 国产无遮挡一区二区三区毛片日本| 久久一区二区三区四区| 欧美激情中文字幕一区二区| 亚洲免费在线播放| 久久综合激情| 性欧美大战久久久久久久免费观看| 欧美一区二区日韩| 99re这里只有精品6| 亚洲在线网站| 亚洲精品中文字幕女同| 欧美影视一区| 在线一区二区三区做爰视频网站| 欧美一区二区大片| 一卡二卡3卡四卡高清精品视频| 亚洲伊人网站| 亚洲精品综合精品自拍| 午夜国产精品视频| 免费成人av在线| 欧美在线视频一区二区| 欧美精品在线看| 美国十次成人| 国产色综合久久| 一区二区三区欧美视频| 亚洲国产精品成人一区二区 | 美女视频网站黄色亚洲| 欧美一区二区三区在线观看| 欧美日韩国产系列| 亚洲日本在线视频观看| 亚洲一区精品在线| 性色av香蕉一区二区| 亚洲视频在线观看网站| 女女同性精品视频| 男同欧美伦乱| 韩日成人在线| 性欧美1819性猛交| 亚洲欧美网站| 欧美午夜不卡| 99国产精品99久久久久久粉嫩| 91久久在线观看| 久久综合九色综合久99| 麻豆成人91精品二区三区| 国产亚洲欧美色| 欧美一级大片在线免费观看| 欧美一区午夜视频在线观看| 国产精品免费久久久久久| 一区二区三区视频在线看| 一区二区高清| 欧美日韩一区二区在线| 99re热精品| 亚洲欧美www| 国产精品一卡二| 亚洲欧美成人网| 久久久亚洲影院你懂的| 狠狠做深爱婷婷久久综合一区| 久久久精品一区二区三区| 美女久久一区| 91久久午夜| 欧美日韩国产精品专区| 日韩一级在线| 欧美日本精品在线| 夜夜躁日日躁狠狠久久88av| 亚洲欧美日韩精品久久亚洲区 | 欧美视频在线视频| 宅男精品视频| 久久精品亚洲一区| 一区在线播放| 欧美精品1区2区| 亚洲一区二区在线看| 久久一区二区三区av| 亚洲成色777777女色窝| 欧美日本亚洲视频| 亚洲尤物影院| 欧美成va人片在线观看| 中文国产成人精品| 国产日本欧美在线观看| 免费在线观看一区二区| 夜夜嗨av色一区二区不卡| 久久久久久久久久久久久9999| 亚洲福利一区| 欧美日韩在线播放一区二区| 老司机精品视频一区二区三区| 亚洲国产日韩一级| 国产精品福利在线观看| 久久精品99国产精品日本| 亚洲福利视频免费观看| 亚洲影视综合| 亚洲国产一二三| 国产精品免费一区二区三区观看| 久久夜色精品国产噜噜av| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 亚洲夫妻自拍| 午夜在线成人av| 亚洲高清视频在线| 国产精品欧美风情| 玖玖玖国产精品| 亚洲一级二级| 激情久久中文字幕| 欧美另类综合| 久久久久网址| 亚洲欧美日韩久久精品| 日韩视频在线播放| 欧美电影美腿模特1979在线看| 欧美影视一区| 亚洲一区二区三| 99re6这里只有精品视频在线观看| 国产一二精品视频| 国产精品理论片| 欧美精品一区在线发布| 欧美mv日韩mv国产网站| 久久精品一二三| 欧美一区二区| 欧美在线观看视频一区二区| 亚洲天堂av图片| 亚洲视频精品| 一区二区三区日韩在线观看| 日韩亚洲欧美精品| 亚洲精选91| 日韩亚洲国产精品| 亚洲久久一区二区| 亚洲激情女人| 亚洲日本一区二区| 亚洲精美视频| 亚洲毛片一区二区| 亚洲精品视频啊美女在线直播| 亚洲国产精品综合| 国产亚洲一区在线| 国产精品试看| 国产精品主播| 国产一区二区精品丝袜| 国产酒店精品激情| 国产一区二区三区在线观看网站| 国产午夜亚洲精品羞羞网站| 国产精品免费看| 国产亚洲精品aa午夜观看| 国产午夜精品视频免费不卡69堂| 国产日韩欧美精品综合| 国产综合激情| 亚洲激情在线观看| 99精品福利视频| 亚洲欧美日本精品| 久久国产66| 欧美va天堂在线| 亚洲国产你懂的| 在线亚洲免费视频| 性视频1819p久久| 久久尤物电影视频在线观看| 欧美国产在线电影| 国产精品视频xxxx| 国模一区二区三区| 亚洲精品日产精品乱码不卡| 亚洲一区999| 久久精品水蜜桃av综合天堂| 亚洲第一精品电影| 亚洲深夜福利在线| 久久久国产精彩视频美女艺术照福利| 欧美不卡在线视频| 国产精品成人va在线观看| 久久久一二三| 国产精品久久久久久户外露出| 国产性天天综合网| 亚洲欧洲免费视频| 欧美一区二区成人6969| 美女精品在线观看| 亚洲午夜羞羞片| 免费成人性网站| 国产乱码精品一区二区三区av| 一区二区在线观看视频| 一区二区三区蜜桃网| 久久频这里精品99香蕉| 日韩一区二区精品在线观看| 久久久999精品免费| 国产精品久久久久久久第一福利 | 国产一区二区三区在线观看免费| 91久久极品少妇xxxxⅹ软件| 销魂美女一区二区三区视频在线| 女人天堂亚洲aⅴ在线观看| 一区二区日韩欧美| 欧美精品www| 在线看视频不卡| 久久久国产91| 亚洲在线观看视频| 欧美视频在线视频|