當前位置:首頁 » 編程軟體 » vc串口通信編程

vc串口通信編程

發布時間: 2022-10-20 12:08:28

❶ 如何在vc6.0中為實現串口通信

首先創建一個VC6.0基於對話框的程序,然後在資源視圖中,Project --- > Add To Project ---> compoents and controls...,如下圖所示

在彈出的窗口選擇「Registered ActiveX Controls」,雙擊進入該文件夾,如下圖所示

在列表中找到「Microsoft Communications Control, version 6.0」,點擊「Insert」按鈕,如下圖所示

接下來就會在資源視圖中看到一個電話圖標,如下圖所示

右鍵該電話圖標,選擇「ClassWizard...」,如下圖所示

在Member Variables下為該控制項添加一個控制項變數,如下圖所示

在Message Maps下為該控制項添加OnComm消息,如下圖所示

在OnInitDialog()函數中,加入窗口控制項初始化函數,如下圖所示

在OnComm() 函數中,加入串口消息處理函數,處理串口接收的數據,如下圖所示

❷ VC編寫的串口通信程序

這東西自己網路一下 「VC 串口通信 原碼」 就有了。
另一方法:到你附近的書店裡買本關於 VC 串口通信 類的書,帶光碟的,裡面就有了。

❸ 使用C/C++在VC6下編寫簡單串口通信程序

http://hi..com/yiweisky99/blog/item/4f57cbf52d092729720eecba.html

❹ 怎樣用VC++實現串口通信編程(怎樣快速學會)

推薦 入門書 看看

Visual C++_Turbo C串口通信編程實踐

需要 pdf 電子文檔 可以 聯系

❺ RS422串口通信VC編程問題

盡量不要用MSComm,裡面很多東西工控上都不穩定。

VC直接用 CreateFile("\\\\.\\com12"..)打開串口,用SetCommState進行串口設置,再用WriteFile和ReadFile讀寫即可,非常簡單,少繞一個大彎子,因為MSComm本身就是用CreateFile/ReadFile/WriteFile寫的

❻ 如何用VC進行串口編程

1、新建MFC對話框工程如下

雙擊兩個Button按鈕;

代碼中顯示如下:

[cpp] view plain print?

  • voidCMSCommTestDlg::OnBnClickedBtnopen()

  • {

  • //TODO:

  • }

  • voidCMSCommTestDlg::OnBnClickedBtnsend()

  • {

  • //TODO:

  • }

  • voidCMSCommTestDlg::OnOncommMscomm1()

  • {

  • //TODO:Addyourmessagehandlercodehere

  • }

  • void CMSCommTestDlg::OnBnClickedBtnopen()

  • {

  • // TODO: Add your control notification handler code here

  • }

  • void CMSCommTestDlg::OnBnClickedBtnsend()

  • {

  • // TODO: Add your control notification handler code here

  • }

  • void CMSCommTestDlg::OnOncommMscomm1()

  • {

  • // TODO: Add your message handler code here

  • }


  • 5、將上面代碼補全如下:

    [cpp] view plain print?

  • voidCMSCommTestDlg::OnClickedBtnopen()

  • {

  • //TODO:

  • //如果埠已經開啟,那麼先關閉

  • if(m_comm1.get_PortOpen())

  • {

  • m_comm1.put_PortOpen(FALSE);

  • }

  • m_comm1.put_CommPort(3);//選擇com3,可以根據具體情況更改

  • m_comm1.put_InBufferSize(1024);//設置輸入緩沖區的大小,Bytes

  • m_comm1.put_OutBufferSize(1024);//設置輸出緩沖區的大小,Bytes

  • m_comm1.put_Settings(_T("9600,n,8,1"));//波特率9600,無校驗,8個數據位,停止位1

  • m_comm1.put_InputMode(1);//1:表示以二進制方式檢索數據

  • m_comm1.put_RThreshold(1);//參數1表示每當串口接收緩沖區中有多於或等於1個字元時將引發一個接收數據的OnComm事件

  • m_comm1.put_InputLen(0);//設置當前接收區長度是0

  • if(!m_comm1.get_PortOpen())

  • {

  • m_comm1.put_PortOpen(TRUE);

  • }

  • else

  • {

  • AfxMessageBox(_T("Cannotopenserialport!"));

  • }

  • m_comm1.get_Input();//先預讀緩沖區以清除殘留數據

  • UpdateData(FALSE);

  • }

  • voidCMSCommTestDlg::OnClickedBtnsend()

  • {

  • //TODO:

  • UpdateData(TRUE);

  • m_comm1.put_Output(COleVariant(m_sTXDATA));//發送數據

  • }

  • voidCMSCommTestDlg::OnOncommMscomm1()

  • {

  • //TODO:Addyourmessagehandlercodehere

  • VARIANTvariant_inp;

  • COleSafeArraysafearray_inp;

  • LONGlen,k;

  • BYTErxdata[2048];

  • CStringstrtemp;

  • if(m_comm1.get_CommEvent()==2)//事件值為2表示緩沖區內有字元

  • {

  • variant_inp=m_comm1.get_Input();//讀緩沖區

  • safearray_inp=variant_inp;//VARIANT型變數轉換為ColeSafeArray型變數

  • len=safearray_inp.GetDim();//得到有效數據長度

  • for(k=0;k<len;k++)

  • {

  • safearray_inp.GetElement(&k,rxdata+k);//轉換為BYTE型數組

  • }

  • for(k=0;k<len;k++)//將數組轉換為CString型變數

  • {

  • BYTEbt=*(char*)(rxdata+k);//字元型

  • strtemp.Format(_T("%c"),bt);//將字元送入臨時變數strtemp存放

  • m_sRXDATA+=strtemp;//接收到的數據放到編輯框對應的變數中

  • }

  • }

  • SetDlgItemText(IDC_EDIT_RXDATA,m_sRXDATA);

  • }

❼ VC串口通信問題

串口的操作可以有兩種操作方式:同步操作方式和重疊操作方式(又稱為非同步操作方式)。同步操作時,API函數會阻塞直到操作完成以後才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而重疊操作方式,API函數會立即返回,操作在後台進行,避免線程的阻塞。

無論那種操作方式,一般都通過四個步驟來完成:
(1) 打開串口
(2) 配置串口
(3) 讀寫串口
(4) 關閉串口

(1) 打開串口

Win32系統把文件的概念進行了擴展。無論是文件、通信設備、命名管道、郵件槽、磁碟、還是控制台,都是用API函數CreateFile來打開或創建的。該函數的原型為:
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;
(2)、配置串口
在打開通訊設備句柄後,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要用DCB結構來作為緩沖區。
一般用CreateFile打開串口後,可以調用GetCommState函數來獲取串口的初始配置。要修改串口的配置,應該先修改DCB結構,然後再調用SetCommState函數設置串口。
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 清除輸入緩沖區

(3)、讀寫串口
我們使用ReadFile和WriteFile讀寫串口,下面是兩個函數的聲明:

BOOL ReadFile(

HANDLE hFile, //串口的句柄

// 讀入的數據存儲的地址,
// 即讀入的數據將存儲在以該指針的值為首地址的一片內存區
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead, // 要讀入的數據的位元組數

// 指向一個DWORD數值,該數值返回讀操作實際讀入的位元組數
LPDWORD lpNumberOfBytesRead,

// 重疊操作時,該參數指向一個OVERLAPPED結構,同步操作時,該參數為NULL。
LPOVERLAPPED lpOverlapped
);
BOOL WriteFile(

HANDLE hFile, //串口的句柄

// 寫入的數據存儲的地址,
// 即以該指針的值為首地址的nNumberOfBytesToWrite
// 個位元組的數據將要寫入串口的發送數據緩沖區。
LPCVOID lpBuffer,

DWORD nNumberOfBytesToWrite, //要寫入的數據的位元組數

// 指向指向一個DWORD數值,該數值返回實際寫入的位元組數
LPDWORD lpNumberOfBytesWritten,

// 重疊操作時,該參數指向一個OVERLAPPED結構,
// 同步操作時,該參數為NULL。
LPOVERLAPPED lpOverlapped
);

在用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。這說明重疊操作還未完成。
您可以觀察返回的字元串,其中有和儀表顯示值相同的部分,您可以進行相應的字元串操作取出儀表的顯示值。
打開ClassWizard,為靜態文本框IDC_DISP添加CString類型變數m_disp,同時添加WM_CLOSE的相應函數: void CRS485CommDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CloseHandle(hCom); //程序退出時關閉串口
CDialog::OnClose();
}

程序的相應部分已經在代碼內部作了詳細介紹。連接好硬體部分,編譯運行程序,細心體會串口同步操作部分。
常式2

打開VC++6.0,新建基於對話框的工程RS485Comm,在主對話框窗口IDD_RS485COMM_DIALOG上添加兩個按鈕,ID分別為IDC_SEND和IDC_RECEIVE,標題分別為「發送」和「接收」;添加一個靜態文本框IDC_DISP,用於顯示串口接收到的內容。在RS485CommDlg.cpp文件中添加全局變數:

HANDLE hCom; //全局變數,
串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函數添加如下代碼:

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

SetupComm(hCom,100,100); //輸入緩沖區和輸出緩沖區的大小都是100

COMMTIMEOUTS TimeOuts;
//設定讀超時
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//在讀一次輸入緩沖區的內容後讀操作就立即返回,
//而不管是否讀入了要求的字元。

//設定寫超時
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
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);

分別雙擊IDC_SEND按鈕和IDC_RECEIVE按鈕,添加兩個按鈕的響應函數: void CRS485CommDlg::OnSend()
{
// TODO: Add your control notification handler code here
OVERLAPPED m_osWrite;
memset(&m_osWrite,0,sizeof(OVERLAPPED));
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

char lpOutBuffer[7];
memset(lpOutBuffer,''\0'',7);
lpOutBuffer[0]=''\x11'';
lpOutBuffer[1]=''0'';
lpOutBuffer[2]=''0'';
lpOutBuffer[3]=''1'';
lpOutBuffer[4]=''0'';
lpOutBuffer[5]=''1'';
lpOutBuffer[6]=''\x03'';

DWORD dwBytesWrite=7;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hCom,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hCom,lpOutBuffer,
dwBytesWrite,& dwBytesWrite,&m_osWrite);

if(!bWriteStat)
{
if(GetLastError()==ERROR_IO_PENDING)
{
WaitForSingleObject(m_osWrite.hEvent,1000);
}
}

}

void CRS485CommDlg::OnReceive()
{
// TODO: Add your control notification handler code here
OVERLAPPED m_osRead;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

COMSTAT ComStat;
DWORD dwErrorFlags;

char str[100];
memset(str,''\0'',100);
DWORD dwBytesRead=100;//讀取的位元組數
BOOL bReadStat;

ClearCommError(hCom,&dwErrorFlags,&ComStat);
dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);
bReadStat=ReadFile(hCom,str,
dwBytesRead,&dwBytesRead,&m_osRead);
if(!bReadStat)
{
if(GetLastError()==ERROR_IO_PENDING)
//GetLastError()函數返回ERROR_IO_PENDING,表明串口正在進行讀操作
{
WaitForSingleObject(m_osRead.hEvent,2000);
//使用WaitForSingleObject函數等待,直到讀操作完成或延時已達到2秒鍾
//當串口讀操作進行完畢後,m_osRead的hEvent事件會變為有信號
}
}

PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
m_disp=str;
UpdateData(FALSE);
}

打開ClassWizard,為靜態文本框IDC_DISP添加CString類型變數m_disp,同時添加WM_CLOSE的相應函數: void CRS485CommDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
CloseHandle(hCom); //程序退出時關閉串口
CDialog::OnClose();
}

這是我看過的一個資料。打開、設置和讀寫串口的方法都說的很詳細了。由於網路知道回答問題是有長度限制的。有些例子被我刪了。如果需要就加我QQ。給你發信息了。

熱點內容
便宜的免費雲伺服器 發布:2025-05-17 11:08:50 瀏覽:775
中國頂級dhcp解析伺服器地址 發布:2025-05-17 11:06:27 瀏覽:32
php轉義html 發布:2025-05-17 11:04:00 瀏覽:566
鋼筋籠加密區規范 發布:2025-05-17 10:59:50 瀏覽:3
我的世界網易手機版主播伺服器房號 發布:2025-05-17 10:40:59 瀏覽:226
豎編譯 發布:2025-05-17 09:56:08 瀏覽:229
編程畫飛機 發布:2025-05-17 09:54:03 瀏覽:803
手機如何解鎖密碼屏幕鎖怎麼刪除 發布:2025-05-17 09:52:04 瀏覽:125
網路無法訪問網頁 發布:2025-05-17 09:51:40 瀏覽:651
雲存儲box估值 發布:2025-05-17 09:47:11 瀏覽:514