當前位置:編程學習大全網 - 編程語言 - VC 或 C C++中是否由函數可以做計算機上位機通訊程序

VC 或 C C++中是否由函數可以做計算機上位機通訊程序

(1) 打開串口

Win32系統把文件的概念進行了擴展。無論是文件、通信設備、命名管道、郵件槽、磁盤、還是控制臺,都是用API函數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函數設置串口。

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位停止位

………

} DCB;

winbase.h文件中定義了以上用到的常量。如下:

#define NOPARITY 0

#define ODDPARITY 1

#define EVENPARITY 2

#define ONESTOPBIT 0

#define ONE5STOPBITS 1

#define TWOSTOPBITS 2

#define CBR_110 110

#define CBR_300 300

#define CBR_600 600

#define CBR_1200 1200

#define CBR_2400 2400

#define CBR_4800 4800

#define CBR_9600 9600

#define CBR_14400 14400

#define CBR_19200 19200

#define CBR_38400 38400

#define CBR_56000 56000

#define CBR_57600 57600

#define CBR_115200 115200

#define CBR_128000 128000

#define CBR_256000 256000

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

HANDLE hFile, //標識通訊端口的句柄

LPDCB lpDCB //指向壹個設備控制塊(DCB結構)的指針

);

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

BOOL SetCommState(

HANDLE hFile,

LPDCB lpDCB

);

除了在BCD中的設置外,程序壹般還需要設置I/O緩沖區的大小和超時。Windows用I/O緩沖區來暫存串口輸入和輸出的數據。如果通信的速率較高,則應該設置較大的緩沖區。調用SetupComm函數可以設置串行口的輸入和輸出緩沖區的大小。 BOOL SetupComm(

HANDLE hFile,// 通信設備的句柄

DWORD dwInQueue,// 輸入緩沖區的大小(字節數)

DWORD dwOutQueue// 輸出緩沖區的大小(字節數)

);

在用ReadFile和WriteFile讀寫串行口時,需要考慮超時問題。超時的作用是在指定的時間內沒有讀入或發送指定數量的字符,ReadFile或WriteFile的操作仍然會結束。

要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充壹個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某壹個COMMTIMEOUTS結構的內容來設置超時。

讀寫串口的超時有兩種:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延。總超時是指讀寫操作總***花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。用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在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是ReadFile和WriteFile的返回時間。

配置串口的示例代碼: SetupComm(hCom,1024,1024); //輸入緩沖區和輸出緩沖區的大小都是1024

COMMTIMEOUTS 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);

在讀寫串口之前,還要用PurgeComm()函數清空緩沖區,該函數原型: BOOL PurgeComm(

HANDLE hFile,//串口句柄

DWORD dwFlags// 需要完成的操作

);

參數dwFlags指定要完成的操作,可以是下列值的組合: PURGE_TXABORT 中斷所有寫操作並立即返回,即使寫操作還沒有完成。

PURGE_RXABORT 中斷所有讀操作並立即返回,即使讀操作還沒有完成。

PURGE_TXCLEAR 清除輸出緩沖區

PURGE_RXCLEAR 清除輸入緩沖區

  • 上一篇:清華大學信息與計算科學專業學哪些課程?求詳情。謝謝。。。
  • 下一篇:戶外激光燈安裝就是有這麽神奇!
  • copyright 2024編程學習大全網