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

vc串口編程

發布時間: 2022-06-25 01:24:49

❶ 請教,VC++ 串口編程問題。

如果你使用的是底層api的話

可以起一個新線程,用於監聽串口
同時使用ClearCommError查詢串口是否有數據到來

具體步驟如下:

1、創建一個非同步讀/寫的串口

HANDLE m_hComm;
m_hComm=CreateFile( m_port, GENERIC_READ |GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL);

m_port為埠號
FILE_FLAG_OVERLAPPED是關鍵

2、配置串口:包括超時、DCB、讀寫緩沖區

3、啟動新線程
CWinThread* m_pCommThread;
m_pCommThread=AfxBeginThread(ThreadComm,pInfo,THREAD_PRIORITY_NORMAL,0,0); //開啟串口線程

ThreadComm為線程回調函數
pInfo 為封裝有所有要向線程傳遞的參數的結構體(類)指針

4、在線程回調函數中
循環查詢串口是否有數據到來
DWORD dwError //串口錯誤碼
COMSTAT cs; //串口狀態結構體
while(pDoc->IsSerailOpen() //串口處於打開狀態下)
{
ClearCommError(hComm,&dwError,&cs);
//調用ClearCommError,如果串口有數據到來,即串口讀緩沖區中有數據
//則串口讀緩沖區中的數據長度將存入cs.cbInQue變數(unsigned long型)
//如串口讀緩沖區中無數據,則cs.cbInQue為0
//對cs.cbInQue作判斷即可得知串口是否收到數據。
if(cs.cbInQue)
{
//串口有數據到來,進行處理
//一般是通過發送自定義消息的方式,交由新的消息響應函數去處理
}
}

以上的代碼是我曾經一個項目的部分代碼,篇幅原因略去了一些代碼
另外給你一個鏈接,你可以參考一下
http://hi..com/xtxycy/blog/item/66827a7766637813b051b9ee.html

❷ 如何用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++寫串口調試助手

1.建立項目
2.在項目中插入MSComm控制項
3.利用ClassWizard定義CMSComm類控制變數
4.在對話框中添加控制項
5.添加串口事件消息處理函數OnComm()
6.打開和設置串口參數
7.發送數據
8.發送十六進制字元
9.在接收框中以十六進制顯示
10.如何設置自動發送
11.什麼是VARIANT數據類型?如何使用VARIANT數據類型?


1.建立項目:打開VC++6.0,建立一個基於對話框的MFC應用程序SCommTest(與我源代碼一致,等會你會方便一點);

2.在項目中插入MSComm控制項 選擇Project菜單下Add To Project子菜單中的 Components and Controls…選項,在彈出的對話框中雙擊Registered ActiveX Controls項(稍等一會,這個過程較慢),則所有注冊過的ActiveX控制項出現在列表框中。 選擇Microsoft Communications Control, version 6.0,,單擊Insert按鈕將它插入到我們的Project中來,接受預設的選項。(如果你在控制項列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安裝VC6時沒有把ActiveX一項選上,重新安裝VC6,選上ActiveX就可以了),

這時在ClassView視窗中就可以看到CMSComm類了,(注意:此類在ClassWizard中看不到,重構clw文件也一樣),並且在控制項工具欄Controls中出現了電話圖標(如圖1所示),現在要做的是用滑鼠將此圖標拖到對話框中,程序運行後,這個圖標是看不到的。

3.利用ClassWizard定義CMSComm類控制對象 打開ClassWizard->Member Viariables選項卡,選擇CSCommTestDlg類,為IDC_MSCOMM1添加控制變數:m_ctrlComm,這時你可以看一看,在對話框頭文件中自動加入了//{{AFX_INCLUDES() #i nclude "mscomm.h" //}}AFX_INCLUDES (這時運行程序,如果有錯,那就再從頭開始)。

4.在對話框中添加控制項 向主對話框中添加兩個編輯框,一個用於接收顯示數據ID為IDC_EDIT_RXDATA,另一個用於輸入發送數據,ID為IDC_EDIT_TXDATA,再添加一個按鈕,功能是按一次就把發送編輯框中的內容發送一次,將其ID設為IDC_BUTTON_MANUALSEND。別忘記了將接收編輯框的Properties->Styles中把Miltiline和Vertical Scroll屬性選上,發送編輯框若你想輸入多行文字,也可選上Miltiline。

再打開ClassWizard->Member Viariables選項卡,選擇CSCommTestDlg類, 為IDC_EDIT_RXDATA添加CString變數m_strRXData, 為IDC_EDIT_TXDATA添加CString變數m_strTXData。說明: m_strRXData和m_strTXData分別用來放入接收和發送的字元數據。

5.添加串口事件消息處理函數OnComm() 打開ClassWizard->Message Maps,選擇類CSCommTestDlg,選擇IDC_MSCOMM1,雙擊消息OnComm,將彈出的對話框中將函數名改為OnComm,(好記而已)OK。

這個函數是用來處理串口消息事件的,如每當串口接收到數據,就會產生一個串口接收數據緩沖區中有字元的消息事件,我們剛才添加的函數就會執行,我們在OnComm()函數加入相應的處理代碼就能實現自已想要的功能了。請你在函數中加入如下代碼:

void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //設置BYTE數組 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值為2表示接收緩沖區內有字元
{ ////////以下你可以根據自己的通信協議加入處理代碼
variant_inp=m_ctrlComm.GetInput(); //讀緩沖區
safearray_inp=variant_inp; //VARIANT型變數轉換為ColeSafeArray型變數
len=safearray_inp.GetOneDimSize(); //得到有效數據長度
for(k=0;k<len;k )
safearray_inp.GetElement(&k,rxdata k);//轉換為BYTE型數組
for(k=0;k<len;k ) //將數組轉換為Cstring型變數
{
BYTE bt=*(char*)(rxdata k); //字元型
strtemp.Format("%c",bt); //將字元送入臨時變數strtemp存放
m_strRXData =strtemp; //加入接收編輯框對應字元串
}
}
UpdateData(FALSE); //更新編輯框內容
}

到目前為止還不能在接收編輯框中看到數據,因為我們還沒有打開串口,但運行程序不應該有任何錯誤,不然,你肯定哪兒沒看仔細,因為我是打開VC6對照著做一步寫一行的,運行試試。沒錯吧?那麼做下一步:

6.打開串口和設置串口參數 你可以在你需要的時候打開串口,例如在程序中做一個開始按鈕,在該按鈕的處理函數中打開串口。現在我們在主對話框的CSCommTestDlg::OnInitDialog()打開串口,加入如下代碼:

// TODO: Add extra initialization here
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);

m_ctrlComm.SetCommPort(1); //選擇com1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打開串口
else
AfxMessageBox("cannot open serial port");

m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,無校驗,8個數據位,1個停止位

m_ctrlComm.SetInputMode(1); // 以二進制方式檢取數據
m_ctrlComm.SetRThreshold(1);
//參數1表示每當串口接收緩沖區中有多於或等於1個字元時將引發一個接收數據的OnComm事件
m_ctrlComm.SetInputLen(0); //設置當前接收區數據長度為0
m_ctrlComm.GetInput();//先預讀緩沖區以清除殘留數據

現在你可以試試程序了,將串口線接好後(不會接?去看看我寫的串口接線基本方法),打開串口調試助手,並將串口設在com2,選上自動發送,也可以等會手動發送。再執行你編寫的程序,接收框里應該有數據顯示了。

7.發送數據 先為發送按鈕添加一個單擊消息即BN_CLICKED處理函數,打開ClassWizard->Message Maps,選擇類CSCommTestDlg,選擇IDC_BUTTON_MANUALSEND,雙擊BN_CLICKED添加OnButtonManualsend()函數,並在函數中添加如下代碼:

void CSCommTestDlg::OnButtonManualsend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //讀取編輯框內容
m_ctrlComm.SetOutput(COleVariant(m_strTXData));//發送數據
}

運行程序,在發送編輯框中隨意輸入點什麼,單擊發送按鈕,啊!看看,在另一端的串口調試助手(或別的調試工具)接收框里出現了什麼。

如果你真是初次涉獵串口編程,又一次成功,那該說聲謝謝我了,因為我第一次做串口程序時可費勁了,那時網上的資料也不好找。開開玩笑,謝謝你的支持,有什麼好東西別忘了給我寄一份。

最後說明一下,由於用到VC控制項,在沒有安裝VC的計算機上運行時要從VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目錄下的System子目錄中(win2000為System32)

8.發送十六進制字元
在主對話框中加入一個復選接鈕,ID為IDC_CHECK_HEXSEND Caption: 十六進制發送,再利用ClassWizard為其添加控制變數:m_ctrlHexSend;
在ClassView中為SCommTestDlg類添加以下兩個PUBLIC成員函數,並輸入相應代碼;

//由於這個轉換函數的格式限制,在發送框中的十六制字元應該每兩個字元之間插入一個空隔
//如:A1 23 45 0B 00 29
//CByteArray是一個動態位元組數組,可參看MSDN幫助
int CSCommTestDlg::String2Hex(CString str, CByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen=0;
int len=str.GetLength();
senddata.SetSize(len/2);
for(int i=0;i<len;)
{
char lstr,hstr=str[i];
if(hstr==' ')
{
i ;
continue;
}
i ;
if(i>=len)
break;
lstr=str[i];
hexdata=ConvertHexChar(hstr);
lowhexdata=ConvertHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else
hexdata=hexdata*16 lowhexdata;
i ;
senddata[hexdatalen]=(char)hexdata;
hexdatalen ;
}
senddata.SetSize(hexdatalen);
return hexdatalen;
}

//這是一個將字元轉換為相應的十六進制值的函數
//好多C語言書上都可以找到
//功能:若是在0-F之間的字元,則轉換為相應的十六進制字元,否則返回-1
char CSCommTestDlg::ConvertHexChar(char ch)
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
return ch-'A' 10;
else if((ch>='a')&&(ch<='f'))
return ch-'a' 10;
else return (-1);
}

再將CSCommTestDlg::OnButtonManualsend()修改成以下形式:
void CSCommTestDlg::OnButtonManualsend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //讀取編輯框內容
if(m_ctrlHexSend.GetCheck())
{
CByteArray hexdata;
int len=String2Hex(m_strTXData,hexdata); //此處返回的len可以用於計算發送了多少個十六進制數
m_ctrlComm.SetOutput(COleVariant(hexdata)); //發送十六進制數據
}
else
m_ctrlComm.SetOutput(COleVariant(m_strTXData));//發送ASCII字元數據

}
現在,你先將串口線接好並打開串口調試助手V2.1,選上以十六制顯示,設置好相應串口,然後運行我們這個程序,在發送框中輸入00 01 02 03 A1 CC等十六進制字元,並選上以十六進制發送,單擊手動發送,在串口調試助手的接收框中應該可以看到00 01 02 03 A1 CC了。

9.在接收框中以十六進制顯示
這就容易多了: 在主對話框中加入一個復選接鈕,IDC_CHECK_HEXDISPLAY Caption: 十六進制顯示,再利用ClassWizard為其添加控制變數:m_ctrlHexDiaplay。 然後修改CSCommTestDlg::OnComm()函數:
void CSCommTestDlg::OnComm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //設置BYTE數組 An 8-bit integerthat is not signed.
CString strtemp;
if(m_ctrlComm.GetCommEvent()==2) //事件值為2表示接收緩沖區內有字元
{
variant_inp=m_ctrlComm.GetInput(); //讀緩沖區
safearray_inp=variant_inp; //VARIANT型變數轉換為ColeSafeArray型變數
len=safearray_inp.GetOneDimSize(); //得到有效數據長度
for(k=0;k<len;k )
safearray_inp.GetElement(&k,rxdata k);//轉換為BYTE型數組
for(k=0;k<len;k ) //將數組轉換為Cstring型變數
{
BYTE bt=*(char*)(rxdata k); //字元型
if(m_ctrlHexDisplay.GetCheck())
strtemp.Format("X ",bt); //將字元以十六進制方式送入臨時變數strtemp存放,注意這里加入一個空隔
else
strtemp.Format("%c",bt); //將字元送入臨時變數strtemp存放

m_strRXData =strtemp; //加入接收編輯框對應字元串
}
}
UpdateData(FALSE); //更新編輯框內容
}
測試:在串口調試助手發送框中輸入00 01 02 03 A1 CC等十六進制字元,並選上以十六進制發送,單擊手動發送,在本程序運行後選上以十六進制顯示,在串口調試助手中單擊手動發送或自動發送,則在本程序的接收框中應該可以看到00 01 02 03 A1 CC了。

10.如何設置自動發送
最簡單的設定自動發送周期是用SetTimer()函數,這在數據採集中很有用,在控制中指令的傳送也可能用到定時發送。
方法是:在ClassWizard中選上MessageMap卡,然後在Objects IDs選中CSCommTestDlg類,再在Messages框中選上WM_TIMER消息,單擊ADD_加入void CSCommTestDlg::OnTimer(UINT nIDEvent) 函數,這個函數是放入「時間到」後要處理的代碼:
void CSCommTestDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
OnButtonManualsend();
CDialog::OnTimer(nIDEvent);
}
再在在主對話框中加入一個復選接鈕,ID為IDC_CHECK_AUTOSEND Caption: 自動發送(周期1秒),再利用ClassWizard為其添加BN_CLICK消息處理函數void CSCommTestDlg::OnCheckAutosend():
void CSCommTestDlg::OnCheckAutosend()
{
// TODO: Add your control notification handler code here
m_bAutoSend=!m_bAutoSend;
if(m_bAutoSend)
{
SetTimer(1,1000,NULL);//時間為1000毫秒
}
else
{
KillTimer(1); //取消定時
}
}
其中:m_bAutoSend為BOOL型變數,在CLASSVIEW中為CSCommTestDlg類加入,並在構造函數中初始化:
m_bAutoSen=FALSE;
現在可以運行程序測試了。

❹ VC++串口編程問題

在MSDN中幫你查了一下,好像需要一個LicenseKey。
另外,在C++中我們一般用::CreateFile API 函數打開串口,自己讀,如果需要我可以給你我讀取串口的方法。
/*
Copyright (c) 1994
*/
WCHAR pwchLicenseKey[] =
{
0x0043, 0x006F, 0x0070, 0x0079, 0x0072, 0x0069,
0x0067, 0x0068, 0x0074, 0x0020, 0x0028, 0x0063,
0x0029, 0x0020, 0x0031, 0x0039, 0x0039, 0x0034,
0x0020
};
// Create the license string
BSTR bStrLicense = ::SysAllocStringLen(pwchLicenseKey,
sizeof(pwchLicenseKey)/sizeof(WCHAR));

// Create the CMSComm object with run-time license data
CMSComm * pComm = new CMSComm;
pComm->Create(NULL, WS_VISIBLE, CRect(0,0,0,0),
this, 999, NULL, FALSE, bStrLicense);

❺ vc串口編程問題(oncomm函數)

全局變數 int i=0;
void CPC_MCU1Dlg::OnOnCommMscomm1()
{
i++;
CString str1;
str1.Format("讀取了%d個字元",i);
MessageBox(str1);
}
手邊沒有單片機開發板 你改成上面的試試 是提示十次嗎 而且提示的內容是不是讀取了1個字元
讀取了2個字元 如果沒有提示十次 那先看看提示的是什麼內容

❻ vc++串口編程

我這里有例子
怎麼給你呢
給你一個簡單的初始化串口的代碼:
HANDLE
hCom=CreateFile("COM2",
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,1024,1024);
COMMTIMEOUTS
TimeOuts;
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=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=1;
//1個停止位
SetCommState(hCom,&dcb);
PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
////////////////////////////////////////////////
CKeyBoardDlg::EnableWindow(false);

❼ vc++ modbus協議的串口怎麼編程

跟普通編程一樣,主要就是給串口發送數據和串口接收數據。數據就是遵循modbus協議的指令。

❽ 如何用C語言在VC+裡面編程使串口調試工具能接收到傳輸的內容

在VC++中有兩種方法可以進行串口通訊。一種是利用Microsoft公司提供的ActiveX控制項 Microsoft Communications Control。另一種是直接用VC++訪問串口。
具體的方法在這http://blog.hehehehehe.cn/a/1480.htm

❾ VC中WriteFile()函數串口編程如何確定是否正

你在本機上的一個串口用WriteFile()向另一個串口發數據,用串口調試助手在另一個串口接收,即可看到你收到的內容,從而驗證WriteFile()發送的數據是否正確。

❿ VC下用CSerialPort類進行串口編程,怎樣對連續的一幀一幀數據進行實時處理

幀頭有幾個位元組
先讀第一個位元組,判斷是幀頭,再讀第二個位元組,再判斷。。。,讀完幀頭,再讀800個位元組,總之就是讀幀頭,之後讀完整個幀。一整個幀都讀到了,之後就是解析了。
也可以串口有多少讀多少,讀完一次,去分析讀到的數據緩沖區中是否有完整的幀,有就處理掉。
實時處理對半個幀的話,就需要設置標記,標識當前解析到幀的哪個部位了

熱點內容
php房產網 發布:2025-02-13 18:18:06 瀏覽:85
源碼資源吧 發布:2025-02-13 18:14:39 瀏覽:79
java培訓價錢 發布:2025-02-13 17:59:33 瀏覽:974
c語言中變數類型 發布:2025-02-13 17:52:20 瀏覽:258
ftp導出報錯 發布:2025-02-13 17:41:20 瀏覽:997
腳本下載教程 發布:2025-02-13 17:39:06 瀏覽:235
解壓密碼re 發布:2025-02-13 17:39:02 瀏覽:558
linuxdump內存 發布:2025-02-13 17:37:30 瀏覽:57
游戲客戶端源碼 發布:2025-02-13 17:37:19 瀏覽:594
win7打開文件夾聲音 發布:2025-02-13 17:35:03 瀏覽:606