亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

基于Windows API的VC++串口通信詳解

2019-11-08 01:20:07
字體:
來源:轉載
供稿:網友
在Win32下,可以使用兩種編程方式實現串口通信,其一是使用ActiveX控件,這種方法程序簡單,但欠靈活。其二是調用Windows的API函數,這種方法可以清楚地掌握串口通信的機制,并且自由靈活。本文我們只介紹API串口通信部分。 串口的操作可以有兩種操作方式:同步操作方式和重疊操作方式(又稱為異步操作方式)。同步操作時,API函數會阻塞直到操作完成以后才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而重疊操作方式,API函數會立即返回,操作在后臺進行,避免線程的阻塞。 無論那種操作方式,一般都通過四個步驟來完成: (1) 打開串口 (2) 配置串口 (3) 讀寫串口 (4) 關閉串口

1、打開串口

Win32系統把文件的概念進行了擴展。無論是文件、通信設備、命名管道、郵件槽、磁盤、還是控制臺,都是用API函數CreateFile來打開或創建的。

CreateFile函數的原型為:

HANDLE CreateFile( LPCTSTR lpFileName, DWord dwDesiredaccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);lpFileName:將要打開的串口邏輯名,如“COM1”; dwDesiredAccess:指定串口訪問的類型,可以是讀取、寫入或二者并列; dwShareMode:指定共享屬性,由于串口不能共享,該參數必須置為0; lpSecurityAttributes:引用安全性屬性結構,缺省值為NULL; dwCreationDistribution:創建標志,對串口操作該參數必須置為OPEN_EXISTING; dwFlagsAndAttributes:屬性描述,用于指定該串口是否進行異步操: = FILE_FLAG_OVERLAPPED,表示使用異步的I/O;= 0,表示同步I/O操作; hTemplateFile:對串口而言該參數必須置為NULL。

同步I/O方式打開串口的示例代碼:

HANDLE hCom; //全局變量,串口句柄 hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允許讀和寫 0, //獨占方式 NULL, OPEN_EXISTING, //打開而不是創建 0, //同步方式 NULL); if(hCom==(HANDLE)-1) { AfxMessageBox("打開COM失敗!"); return FALSE; } return TRUE;

重疊I/O(異步方式)打開串口的示例代碼:

HANDLE hCom; //全局變量,串口句柄 hCom =CreateFile("COM1", //COM1口 GENERIC_READ|GENERIC_WRITE, //允許讀和寫 0, //獨占方式 NULL, OPEN_EXISTING, //打開而不是創建 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重疊方式 NULL); if(hCom ==INVALID_HANDLE_VALUE) { AfxMessageBox("打開COM失敗!"); return FALSE; } return TRUE;

2、配置串口

在打開通訊設備句柄后,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要用DCB結構來作為緩沖區。 一般用CreateFile打開串口后,可以調用GetCommState函數來獲取串口的初始配置。要修改串口的配置,應先修改DCB結構,再調用SetCommState函數設置串口。

(1)DCB結構包含了串口的各項參數設置,下面僅介紹幾個該結構常用的變量:

typedef struct _DCB { ……… //波特率,指定通信設備的傳輸速率。這個成員可以是實際波特率值或者下面的常量值之一: DWORD BaudRate; CBR_110,CBR_300, //CBR_600,CBR_1200,CBR_2400,CBR_4800,CBR_9600,CBR_19200, CBR_38400,CBR_56000, CBR_57600,CBR_115200, //CBR_128000,CBR_256000, CBR_14400 DWORD fParity; // 指定奇偶校驗使能。若此成員為1,允許奇偶校驗檢查 BYTE ByteSize; // 通信字節位數,4—8 BYTE Parity; //指定奇偶校驗方法。此成員可以有下列值: EVENPARITY 偶校驗;NOPARITY 無校驗;MARKPARITY 標記校驗; //ODDPARITY 奇校驗 BYTE StopBits; //指定停止位的位數。此成員可以有下列值: ONESTOPBIT 1位停止位;TWOSTOPBITS 2位停止位; //ONE5STOPBITS 1.5位停止位}

(2)GetCommState函數可以獲得COM口的設備控制塊,從而獲得相關參數:

BOOL GetCommState( HANDLE hFile, //標識通訊端口的句柄 LPDCB lpDCB //指向一個設備控制塊(DCB結構)的指針 );

(3)SetCommState函數設置COM口的設備控制塊:

BOOL SetCommState( HANDLE hFile, LPDCB lpDCB );

(4)SetupComm函數設置串行口的輸入和輸出緩沖區的大?。?/strong>

除了在DCB中設置外,程序一般還需要設置I/O緩沖區的大小和超時。Windows用I/O緩沖區來暫存串口輸入和輸出的數據。如果通信的速率較高,則應該設置較大的緩沖區。調用SetupComm函數可以設置串行口的輸入和輸出緩沖區的大小。 BOOL SetupComm( HANDLE hFile, // 通信設備的句柄 DWORD dwInQueue, // 輸入緩沖區的大?。ㄗ止潝担? DWORD dwOutQueue // 輸出緩沖區的大?。ㄗ止潝担?);

(5)GetCommTimeouts函數查詢超時:

在用ReadFile和WriteFile讀寫串行口時,需要考慮超時問題。超時的作用是在指定的時間內沒有讀入或發送指定數量的字符,ReadFile或WriteFile的操作仍然會結束。 要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。 讀寫串口的超時有兩種:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延??偝瑫r是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。用COMMTIMEOUTS結構可以規定讀寫操作的超時。 COMMTIMEOUTS結構的定義為:typedef struct _COMMTIMEOUTS { DWORD ReadIntervalTimeout; //讀間隔超時 DWORD ReadTotalTimeoutMultiplier; //讀時間系數 DWORD ReadTotalTimeoutConstant; //讀時間常量 DWORD WriteTotalTimeoutMultiplier; // 寫時間系數 DWORD WriteTotalTimeoutConstant; //寫時間常量 } COMMTIMEOUTS,*LPCOMMTIMEOUTS; COMMTIMEOUTS結構的成員都以毫秒為單位。 總超時的計算公式是:總超時=時間系數×要求讀/寫的字符數+時間常量。 例如,要讀入10個字符,那么讀操作的總超時的計算公式為:讀總超時=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant。 可以看出:間隔超時和總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。 如果所有寫超時參數均為0,那么就不使用寫超時。如果ReadIntervalTimeout為0,那么就不使用讀間隔超時。如果ReadTotalTimeoutMultiplier和 ReadTotalTimeoutConstant 都為0,則不使用讀總超時。如果讀間隔超時被設置成MAXDWORD并且讀時間系數和讀時間常量都為0,那么在讀一次輸入緩沖區的內容后讀操作就立即返回,而不管是否讀入了要求的字符。間,而不是ReadFile和WriteFile的返回時間。

(6)PurgeComm()函數清空緩沖區:

在讀寫串口之前,還要用PurgeComm()函數清空緩沖區,該函數原型: BOOL PurgeComm( HANDLE hFile, //串口句柄 DWORD dwFlags // 需要完成的操作 ); 參數dwFlags指定要完成的操作,可以是下列值的組合: PURGE_TXABORT 中斷所有寫操作并立即返回,即使寫操作還沒有完成; PURGE_TXCLEAR 清除輸出緩沖區; PURGE_RXCLEAR 清除輸入緩沖區;

配置串口的示例代碼:

SetupComm(hCom,1024,1024); //輸入緩沖區和輸出緩沖區的大小都是1024COMMTIMEOUTS TimeOuts; //設定讀超時 TimeOuts.ReadIntervalTimeout=1000; TimeOuts.ReadTotalTimeoutMultiplier=500; TimeOuts.ReadTotalTimeoutConstant=5000; //設定寫超時 TimeOuts.WriteTotalTimeoutMultiplier=500; TimeOuts.WriteTotalTimeoutConstant=2000; SetCommTimeouts(hCom,&TimeOuts); //設置超時 DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率為9600 dcb.ByteSize=8; //每個字節有8位 dcb.Parity=NOPARITY; //無奇偶校驗位 dcb.StopBits=TWOSTOPBITS; //兩個停止位 SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR | PURGE_RXCLEAR);

3、讀寫串口

(1)ReadFile函數讀串口:

BOOL ReadFile( HANDLE hFile, //串口的句柄 LPVOID lpBuffer,// 讀入的數據存儲的地址:即讀入的數據將存儲在以該指針的值為首地址的一片內存區 DWORD nNumberOfBytesToRead, // 要讀入的數據的字節數 LPDWORD lpNumberOfBytesRead,// 指向一個DWORD數值,該數值返回讀操作實際讀入的字節數 LPOVERLAPPED lpOverlapped// 重疊操作時,該參數指向一個OVERLAPPED結構,同步操作時,該參數為NULL );

(2)WriteFiel函數寫串口:

BOOL WriteFile( HANDLE hFile, //串口的句柄 LPCVOID lpBuffer, // 寫入的數據存儲的地址:即以該指針的值為首地址的nNumberOfBytesToWrite個字節的數據將要寫入 //串口的發送數據緩沖區。 DWORD nNumberOfBytesToWrite, //要寫入的數據的字節數 LPDWORD lpNumberOfBytesWritten,// 指向指向一個DWORD數值,該數值返回實際寫入的字節數 LPOVERLAPPED lpOverlapped// 重疊操作時,該參數指向一個OVERLAPPED結構;同步操作時,該參數為NULL。 ); 在用ReadFile和WriteFile讀寫串口時,既可以同步執行,也可以重疊執行。在同步執行時,函數直到操作完成后才返回。這意味著同步執行時線程會被阻塞,從而導致效率下降。在重疊執行時,即使操作還未完成,這兩個函數也會立即返回,費時的I/O操作在后臺進行。 ReadFile和WriteFile函數是同步還是異步由CreateFile函數決定,如果在調用CreateFile創建句柄時指定了FILE_FLAG_OVERLAPPED標志,那么調用ReadFile和WriteFile對該句柄進行的操作就應該是重疊的;如果未指定重疊標志,則讀寫操作應該是同步的。ReadFile和WriteFile函數的同步或者異步應該和CreateFile函數相一致。 ReadFile函數只要在串口輸入緩沖區中讀入指定數量的字符,就算完成操作。而WriteFile函數不但要把指定數量的字符拷入到輸出緩沖區,而且要等這些字符從串行口送出去后才算完成操作。 如果操作成功,這兩個函數都返回TRUE。需要注意的是,當ReadFile和WriteFile返回FALSE時,不一定就是操作失敗,線程應該調用GetLastError函數分析返回的結果。例如,在重疊操作時如果操作還未完成函數就返回,那么函數就返回FALSE,而且GetLastError函數返回ERROR_IO_PENDING。這說明重疊操作還未完成。

同步方式讀寫串口的代碼示例:

//同步讀串口

char str[100]; DWORD wCount;//讀取的字節數 BOOL bReadStat; bReadStat=ReadFile(hCom,str,100,&wCount,NULL); if(!bReadStat) { AfxMessageBox("讀串口失敗!"); return FALSE; } return TRUE;

//同步寫串口

char lpOutBuffer[100]; DWORD dwBytesWrite=100; COMSTAT ComStat; DWORD dwErrorFlags; BOOL bWriteStat; ClearCommError(hCom,&dwErrorFlags,&ComStat); bWriteStat=WriteFile(hCom,lpOutBuffer,dwBytesWrite,& dwBytesWrite,NULL); if(!bWriteStat) { AfxMessageBox("寫串口失敗!"); } PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

(3)等待讀寫操作完成函數WaitForSingleObject和GetOverlappedResult:

在重疊操作時,操作還未完成函數就返回。 重疊I/O非常靈活,它也可以實現阻塞(例如我們可以設置一定要讀取到一個數據才能進行到下一步操作)。有兩種方法可以等待操作完成:一種方法是用象WaitForSingleObject這樣的等待函數來等待OVERLAPPED結構的hEvent成員;另一種方法是調用GetOverlappedResult函數等待,后面將演示說明。 下面我們先簡單說一下OVERLAPPED結構和GetOverlappedResult函數:

OVERLAPPED結構:包含了重疊I/O的一些信息,定義如下:

typedef struct _OVERLAPPED { DWORD Internal; DWORD InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent; } OVERLAPPED; 在使用ReadFile和WriteFile重疊操作時,線程需要創建OVERLAPPED結構以供這兩個函數使用。線程通過OVERLAPPED結構獲得當前的操作狀態,該結構最重要的成員是hEvent。hEvent是讀寫事件。當串口使用異步通訊時,函數返回時操作可能還沒有完成,程序可以通過檢查該事件得知是否讀寫完畢。 當調用ReadFile, WriteFile 函數的時候,該成員會自動被置為無信號狀態;當重疊操作完成后,該成員變量會自動被置為有信號狀態。

GetOverlappedResult函數:

BOOL GetOverlappedResult( HANDLE hFile, //串口的句柄 LPOVERLAPPED lpOverlapped,//指向重疊操作開始時指定的OVERLAPPED結構 LPDWORD lpNumberOfBytesTransferred,//指向一個32位變量,該變量的值返回實際讀寫操作傳輸的字節數。 BOOL bWait// 該參數用于指定函數是否一直等到重疊操作結束:如果該參數為TRUE,函數直到操作結束才返回; //如果該參數為FALSE,函數直接返回,這時如果操作沒有完成,通過調用GetLastError()函數會 //返回ERROR_IO_INCOMPLETE。 ); 該函數返回重疊操作的結果,用來判斷異步操作是否完成,它是通過判斷OVERLAPPED結構中的hEvent是否被置位來實現的。

異步方式讀寫串口的代碼示例:

//異步讀串口:用WaitForSingleObject函數來等待OVERLAPPED結構的hEvent成員

char lpInBuffer[1024]; DWORD dwBytesRead=1024; COMSTAT ComStat; DWORD dwErrorFlags; OVERLAPPED m_osRead; memset(&m_osRead,0,sizeof(OVERLAPPED)); m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); ClearCommError(hCom,&dwErrorFlags,&ComStat); dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue); if(!dwBytesRead) { return FALSE; }BOOL bReadStatus; bReadStatus=ReadFile(hCom,lpInBuffer, dwBytesRead,&dwBytesRead,&m_osRead); if(!bReadStatus) { //如果ReadFile函數返回FALSE if(GetLastError()==ERROR_IO_PENDING) { //GetLastError()函數返回ERROR_IO_PENDING,表明串口正在進行讀操作 WaitForSingleObject(m_osRead.hEvent,2000); //使用WaitForSingleObject函數等待,直到讀操作完成或延時已達到2秒鐘, //當串口讀操作進行完畢后,m_osRead的hEvent事件會變為有信號 PurgeComm(hCom,PURGE_TXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); return dwBytesRead; } return 0; } PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); return dwBytesRead; 對以上代碼再作簡要說明:在使用ReadFile 函數進行讀操作前,應先使用ClearCommError函數清除錯誤。ClearCommError函數的原型如下: BOOL ClearCommError( HANDLE hFile, // 串口句柄 LPDWORD lpErrors, // 指向接收錯誤碼的變量 LPCOMSTAT lpStat // 指向通訊狀態緩沖區 ); 該函數獲得通信錯誤并報告串口的當前狀態,同時,該函數清除串口的錯誤標志以便繼續輸入、輸出操作。 參數lpStat指向一個COMSTAT結構,該結構返回串口狀態信息。 COMSTAT結構 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; 本文只用到了cbInQue成員變量,該成員變量的值代表輸入緩沖區的字節數。 最后用PurgeComm函數清空串口的輸入輸出緩沖區。 這段代碼用WaitForSingleObject函數來等待OVERLAPPED結構的hEvent成員,下面我們再演示一段調用GetOverlappedResult函數等待的異步讀串口示例代碼:

//異步讀串口:用GetOverlappedResult函數來等待

char lpInBuffer[1024]; DWORD dwBytesRead=1024; BOOL bReadStatus; DWORD dwErrorFlags; COMSTAT ComStat; OVERLAPPED m_osRead; ClearCommError(hCom,&dwErrorFlags,&ComStat); if(!ComStat.cbInQue) return 0; dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue); bReadStatus=ReadFile(hCom, lpInBuffer,dwBytesRead, &dwBytesRead,&m_osRead); if(!bReadStatus) { //如果ReadFile函數返回FALSE if(GetLastError()==ERROR_IO_PENDING) { GetOverlappedResult(hCom, &m_osRead,&dwBytesRead,TRUE); // GetOverlappedResult函數的最后一個參數設為TRUE,函數會一直 //等待,直到讀操作完成或由于錯誤而返回。 } } return dwBytesRead;

//異步寫串口:

char buffer[1024]; DWORD dwBytesWritten=1024; DWORD dwErrorFlags; COMSTAT ComStat; OVERLAPPED m_osWrite; BOOL bWriteStat; bWriteStat=WriteFile(hCom,buffer,dwBytesWritten, &dwBytesWritten,&m_OsWrite); if(!bWriteStat) { if(GetLastError()==ERROR_IO_PENDING) { WaitForSingleObject(m_osWrite.hEvent,1000); return dwBytesWritten; } return 0; } return dwBytesWritten;

4、關閉串口

利用API函數關閉串口非常簡單,只需使用CreateFile函數返回的句柄作為參數調用CloseHandle即可:BOOL CloseHandle( HANDLE hObject; //handle to object to close);
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久国产精彩视频| 精品视频在线观看日韩| 欧美肥老妇视频| 在线播放日韩专区| 欧美一区二粉嫩精品国产一线天| 日韩在线观看网址| 成人精品久久一区二区三区| 另类色图亚洲色图| 精品偷拍各种wc美女嘘嘘| 成人伊人精品色xxxx视频| 中文字幕综合在线| 2019中文字幕在线观看| 国产精品久久久久久久久粉嫩av| 欧美怡红院视频一区二区三区| 欧美成人黄色小视频| 日韩美女免费观看| 久久精品国产69国产精品亚洲| 日本久久久久久久久| 国模私拍一区二区三区| 亚洲精品国产拍免费91在线| 亚洲成人精品在线| 国产视频欧美视频| 国产精品r级在线| 欧美精品免费看| 日本免费一区二区三区视频观看| 欧美性69xxxx肥| 91黑丝高跟在线| 欧美中文在线字幕| 精品成人久久av| zzijzzij亚洲日本成熟少妇| 国产不卡在线观看| 久久6免费高清热精品| 久久久久久成人| 欧美在线视频网| 日韩美女主播视频| 国产精品户外野外| 国外成人在线视频| 亚洲午夜精品久久久久久久久久久久| 亚洲天堂一区二区三区| 欧美高清电影在线看| 精品美女久久久久久免费| 亚洲国产成人久久综合一区| 不卡伊人av在线播放| 国产精品男人的天堂| 91chinesevideo永久地址| 不卡av电影在线观看| 欧美成人免费网| 欧美美女15p| 亚洲激情视频网| 亚洲激情国产精品| 色综合色综合久久综合频道88| 久久成年人视频| 中文字幕视频在线免费欧美日韩综合在线看| 热re91久久精品国99热蜜臀| 亚洲第一天堂无码专区| 久久精品免费播放| 国产亚洲xxx| 91精品国产高清久久久久久久久| 欧美大片在线免费观看| 国产欧美一区二区| 国产视频精品自拍| 91亚洲精品视频| 中文字幕在线看视频国产欧美在线看完整| www.美女亚洲精品| 日韩av不卡在线| 中文字幕久久久av一区| 久久天天躁狠狠躁老女人| 日韩av中文字幕在线播放| 2019亚洲男人天堂| 精品久久久久久久久久久久| 国产一区二区黑人欧美xxxx| 欧美黑人巨大精品一区二区| 欧美怡春院一区二区三区| 亚洲最大激情中文字幕| 尤物九九久久国产精品的分类| 国产一区二区成人| 久久五月情影视| 国产精品久久久久久搜索| 久久人91精品久久久久久不卡| 久久久免费电影| 日韩不卡在线观看| 欧美贵妇videos办公室| 久久久久久国产精品美女| 人人做人人澡人人爽欧美| 欧美日韩在线视频观看| 欧美另类69精品久久久久9999| 亚洲精品国产美女| 2021国产精品视频| 国产欧美一区二区| 国产精品一区二区久久久久| 欧美黑人性视频| 国产精品入口免费视频一| 日韩av在线免播放器| 国产精品久久久久福利| 性欧美亚洲xxxx乳在线观看| 97国产精品免费视频| 亚洲欧洲日产国产网站| 亚洲 日韩 国产第一| 日韩av中文字幕在线免费观看| 日本国产一区二区三区| 国外成人性视频| 性欧美xxxx视频在线观看| 国产精品视频永久免费播放| 欧美日本国产在线| 久久欧美在线电影| 国产成人福利视频| 在线精品视频视频中文字幕| 98精品国产自产在线观看| 欧美大片网站在线观看| 韩国v欧美v日本v亚洲| 亚洲精品456在线播放狼人| 午夜精品一区二区三区在线| 国产精品国模在线| 国产成人免费av| 精品久久久久久久大神国产| 欧美大片在线看免费观看| 中文字幕日韩高清| 久久久久久久影院| 成人国产精品色哟哟| 国产精品日韩欧美| 亚洲视频在线观看网站| 国产亚洲欧美日韩一区二区| 国产丝袜一区二区三区免费视频| 怡红院精品视频| 欧美成人性色生活仑片| 日韩欧亚中文在线| 欧美三级免费观看| 日本在线观看天堂男亚洲| 91在线观看欧美日韩| 国产欧美在线观看| 久久999免费视频| 国产香蕉一区二区三区在线视频| 91高清在线免费观看| 亚洲一区中文字幕| 中文在线不卡视频| 久久香蕉精品香蕉| 91精品国产综合久久久久久久久| 国产日韩欧美影视| 久久精品亚洲热| 欧美精品18videos性欧| 91青草视频久久| 欧美日韩国产在线播放| 亚洲bt欧美bt日本bt| 欧美日韩xxxxx| 色综合伊人色综合网站| 国产综合香蕉五月婷在线| 国产伊人精品在线| 久久人91精品久久久久久不卡| 欧美性69xxxx肥| 成人福利网站在线观看| 在线视频一区二区| 亚洲免费视频一区二区| 夜夜嗨av一区二区三区免费区| 韩国国内大量揄拍精品视频| 亚洲成人教育av| 精品国产31久久久久久| 亚洲第一精品久久忘忧草社区| 亚洲va久久久噜噜噜| 欧美日韩亚洲精品内裤| 国产成人在线一区二区| 亚洲香蕉成视频在线观看| 国产成人自拍视频在线观看| 亚洲国产精品久久久久秋霞蜜臀| 国产精品偷伦视频免费观看国产|