導航:首頁 > 源碼編譯 > 串口通訊源碼

串口通訊源碼

發布時間:2023-05-18 02:49:39

android_studio手機藍牙串口通信源代碼

初涉android的藍牙操作,按照固定MAC地址連接獲取Device時,程序始終是異常終止,查了好多天代碼都沒查出原因。今天改了一下API版本,突然就成功連接了。總結之後發現果然是個坑爹之極的錯誤。

為了這種錯誤拚命查原因浪費大把時間是非常不值得的,但是問題不解決更是揪心。可惜我網路了那麼多,都沒有給出確切原因。今天特此mark,希望後來者遇到這個問題的時候能輕松解決。

下面是我的連接過程,中間崩潰原因及解決辦法。

1:用AT指令獲得藍牙串口的MAC地址,地址是簡寫的,按照常理猜測可得標准格式。

2:開一個String adress= "************" //MAC地址, String MY_UUID= "************"//UUID根據通信而定,網上都有。

3:取得本地Adapter用getDefaultAdapter(); 遠程的則用getRemoteDevice(adress); 之後便可用UUID開socket進行通信。

如果中途各種在getRemoteDevice處崩潰,大家可以查看一下當前的API版本,如果是2.1或以下版本的話,便能確定是API版本問題,只要換成2.2或者以上就都可以正常運行了~ 這么坑爹的錯誤的確很為難初學者。 唉·········· 為這種小trick浪費很多時間真是難過。

(另外有個重要地方,別忘了給manifest裡面加以下兩個藍牙操作許可權哦~)

Ⅱ 求vc 串口通信源碼

我這邊有,已經成功應用於項目中!
//送到窗口的消息 WPARAM 埠號
#define ON_COMM_RECEIVE WM_USER+2009
#define ON_COMM_ERROR WM_USER+2010
#define ON_COMM_CTS WM_USER+2011
#define ON_COMM_DSR WM_USER+2012
#define ON_COMM_BREAK WM_USER+2013
#define ON_COMM_TXEMPTY WM_USER+2014
#define ON_COMM_RING WM_USER+2015
#define ON_COMM_RLSD WM_USER+2016
// changed 2011.4.07 收到特定字元事件 而不是收到任何字元 EV_RXCHAR-->EV_RXFLAG
#define DEFALUT_COM_MASK_EVENT EV_RXFLAG | EV_ERR | EV_CTS | EV_DSR | EV_BREAK | EV_TXEMPTY | EV_RING | EV_RLSD

class CCom
{
public:
//------------------------------Construction-----------------------------------
//第1個參數為是否在打開串口時啟動監視線程物跡, 第2個參數為IO方式 阻塞方式(0)/ 非同步重疊方式(默認)
CCom(BOOL bAutoBeginThread = TRUE, DWORD dwIOMode = FILE_FLAG_OVERLAPPED);
virtual ~CCom();

//----------------------------------Operations----------------------------------
//打開串口 預設 9600, 8, n, 1
BOOL Open(DWORD dwPort);
//打開串口 預設 baud_rate, 8, n, 1
BOOL Open(DWORD dwPort, DWORD dwBautRate);
//打開串口, 使用類似"9600, 8, n, 1"的設置和明字元串設置串口
BOOL Open(DWORD dwPort, char* szSetStr);
//讀取串口 dwBufferLength個字元到 Buffer 返回實際讀到的字元數 可讀任意數據
DWORD Read(LPVOID Buffer, DWORD dwBufLength, DWORD dwWaitTime = 10);
//讀取串口 dwBufferLength - 1 個字元到 szBuffer 返回ANSI C 模式字元串指針 適合一般字元通訊
char* ReadString(char* szBuffer, DWORD dwBufferLength, DWORD dwWaitTime = 20);
//讀串口 同步應用
DWORD ReadSync(LPVOID Buffer, DWORD dwBufferLength);
//寫串口 可寫任意數據 "abcd" or "\x0\x1\x2"
DWORD Write(LPVOID Buffer, DWORD dwBufferLength, DWORD dwWaitTime = 20); // changed 2011.4.1 增加了第三個默認參數

//寫串口 寫ANSI C 模式字元串指針
DWORD Write(const char* szBuffer);
//寫串口 同步應用
DWORD WriteSync(LPVOID Buffer, DWORD dwBufferLength);
//寫串口 szBuffer 可以輸出格式字元串 包含緩沖區長度
DWORD Write(char* szBuffer, DWORD dwBufferLength, char* szFormat, ...);
//寫串口 szBuffer 可以輸罩棚並出格式字元串 不檢查緩沖區長度 小心溢出
DWORD Write(char* szBuffer, char* szFormat);
//關閉串口 同時也關閉關聯線程
virtual void Close();

struct InnerLock
{
CCom* ptr;
InnerLock(CCom* p) : ptr(p)
{
ptr->Lock();
}
~InnerLock()
{
ptr->UnLock();
}
};
//鎖定資源
void Lock()
{
::EnterCriticalSection(&m_mutex);
}
void UnLock()
{
::LeaveCriticalSection(&m_mutex);
}
//DTR 電平控制
BOOL SetDtr(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETDTR : CLRDTR) !=0 : FALSE;
}
//RTS 電平控制
BOOL SetRts(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETRTS : CLRRTS) != 0 : FALSE;
}

BOOL SetBreak(BOOL OnOrOff)
{
return IsOpen()? EscapeCommFunction(m_hComHandle, OnOrOff? SETBREAK : CLRBREAK) != 0 : FALSE;
}
//輔助線程式控制制 建監視線程
BOOL BeginThread();
//暫停監視線程
inline BOOL SuspendThread()
{
return IsThreadRunning()? ::SuspendThread(m_hThreadHandle) != 0xFFFFFFFF : FALSE;
}
//恢復監視線程
inline BOOL ResumeThread()
{
return IsThreadRunning()? ::ResumeThread(m_hThreadHandle) != 0xFFFFFFFF : FALSE;
}
//終止線程
BOOL EndThread(DWORD dwWaitTime = 100);

//----------------------------------Attributes----------------------------------
//判斷串口是或打開
inline BOOL IsOpen() {return m_hComHandle != INVALID_HANDLE_VALUE;}
//獲得串口句炳
HANDLE GetHandle() {return m_hComHandle;}
//獲得串口序號
const int GetPortID() {return m_dwPort;}
//獲得串口全名
const char* GetPortName() {return m_szComStr;}
//獲得串口參數 DCB
DCB* GetState()
{
return IsOpen() && ::GetCommState(m_hComHandle, &m_DCB) == TRUE ? &m_DCB : NULL;
}
//設置串口參數 DCB
BOOL SetState(DCB* pDCB = NULL)
{
return IsOpen() ? SetCommState(m_hComHandle, pDCB == NULL? &m_DCB : pDCB) == TRUE : FALSE;
}
//設置串口參數:波特率,停止位,等 支持設置字元串 "9600, 8, n, 1"
BOOL SetState(char* szSetStr);
//設置串口參數:波特率,停止位,等
BOOL SetState(DWORD dwBautRate, DWORD dwByteSize = 8, DWORD dwParity = NOPARITY, DWORD dwStopBits = ONESTOPBIT);
//獲得超時結構
LPCOMMTIMEOUTS GetTimeouts()
{
return IsOpen()&&::GetCommTimeouts(m_hComHandle, &m_ComTimeOuts) == TRUE ? &m_ComTimeOuts : NULL;
}
//設置超時
BOOL SetTimeouts(LPCOMMTIMEOUTS lpCO)
{
return IsOpen()? ::SetCommTimeouts(m_hComHandle, lpCO) == TRUE : FALSE;
}
//設置串口的I/O緩沖區大小
BOOL SetBufferSize(DWORD dwInputSize, DWORD dwOutputSize)
{
return IsOpen()? ::SetupComm(m_hComHandle, dwInputSize, dwOutputSize) == TRUE : FALSE;
}
//清除接受緩沖區
void ClearInputBuffer()
{
if(IsOpen())
PurgeComm(m_hComHandle, PURGE_RXABORT|PURGE_RXCLEAR);
}
//清除發送緩沖區
void ClearOutputBuffer()
{
if (IsOpen())
PurgeComm(m_hComHandle, PURGE_TXABORT|PURGE_TXCLEAR);
}
//關聯消息的窗口句柄
inline void SetWnd(HWND hWnd)
{
assert(::IsWindow(hWnd));
m_hNotifyWnd = hWnd;
}
//設定發送通知, 接受字元最小值
inline void SetNotifyNum(DWORD dwNum)
{
m_dwNotifyNum = dwNum;
}
//線程是否運行
inline BOOL IsThreadRunning() {return m_hThreadHandle != NULL;}
//獲得線程句柄
inline HANDLE GetThread()
{
return m_hThreadHandle;
}
//設置要監視的事件, 打開前設置有效
void SetMaskEvent(DWORD dwEvent = DEFALUT_COM_MASK_EVENT)
{
m_dwMaskEvent = dwEvent;
}
//獲得讀緩沖區的字元數
int GetInputSize()
{
COMSTAT Stat;
DWORD dwError;
return ::ClearCommError(m_hComHandle, &dwError, &Stat) == TRUE? Stat.cbInQue : (DWORD)-1L;
}

//Attributes
protected:
volatile DWORD m_dwPort; //串口號
volatile HANDLE m_hComHandle; //串口句柄
char m_szComStr[20]; //保存Com1類似的字元串

DCB m_DCB; //定義波特率,停止位,等
COMMTIMEOUTS m_ComTimeOuts; //超時結構

DWORD m_dwIOMode; //0,同步 默認 FILE_FLAG_OVERLAPPED 重疊I/O 非同步
OVERLAPPED m_overlappedRead, m_overlappedWrite;

volatile HANDLE m_hThreadHandle; //輔助線程
volatile HWND m_hNotifyWnd; //通知窗口
volatile DWORD m_dwNotifyNum;//接受多少位元組(>=m_dwNotifyNum)發送通知消息
volatile DWORD m_dwMaskEvent; //監視的事件
volatile BOOL m_bRunFlag; //線程運行循環標志
BOOL m_bAutoBeginThread; //open() 自動BeginThread();
OVERLAPPED m_overlappedWait;

protected:
//初始化
virtual void Init();
//析構
virtual void Destroy();
//綁定串口
void BindCommPort(DWORD dwPort);
//打開串口
virtual BOOL OpenCommPort();
//設置串口
virtual BOOL SetUpPort();
//---------------------------------------threads callback-----------------------------------------------------
//線程收到消息自動調用, 如窗口句柄有效, 送出消息, 包含串口編號, 均為虛函數可以在基層類中擴展
virtual DWORD ThreadFunc();
virtual void OnReceive();
virtual void OnCts();
virtual void OnDsr();
virtual void OnRing();
virtual void OnRlsd();
virtual void OnBreak();
virtual void OnTxEmpty();
virtual void OnError();

private:
CCom(const CCom&);
CCom& operator = (const CCom&);
CRITICAL_SECTION m_mutex;

#ifdef _MT
static UINT APIENTRY CommThreadProc(LPVOID lpPara)
#else
static DWORD WINAPI CommThreadProc(LPVOID lpPara)
#endif
{
return ((CCom*)lpPara)->ThreadFunc();
}
};
#endif

#endif // !defined(AFX_COM_H__5427C4C8_CC6C_4135_9607_AF8BF6C1C679__INCLUDED_)

Ⅲ 【急求】mfc 實現串口編程的源代碼

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); //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));//發送數據
}
運行程序,在發送編輯框中隨意輸入點什麼,單擊發送按鈕,我們通過把RS232的2.3兩口短接,在一台電腦上顯示串口的收發數據!
最後說明一下,由於用到VC控制項,在沒有安裝VC的計算機上運行時要從VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目錄下的System子目錄中(win2000為System32)並再進行注冊設置

Ⅳ 求c++串口通信實例源代碼

推薦看書

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

需要 pdf 文檔 可以聯系
希望能解決您的問題。

閱讀全文

與串口通訊源碼相關的資料

熱點內容
液壓油可壓縮嗎 瀏覽:944
源泉cad加密文件 瀏覽:125
銀河v10驅動重編譯 瀏覽:889
電腦上文件夾右擊就會崩潰 瀏覽:689
右美維持演算法 瀏覽:938
php基礎編程教程pdf 瀏覽:219
穿越之命令與征服將軍 瀏覽:351
android廣播重復 瀏覽:832
像阿里雲一樣的伺服器 瀏覽:318
水冷空調有壓縮機嗎 瀏覽:478
訪問日本伺服器可以做什麼 瀏覽:433
bytejava詳解 瀏覽:450
androidjava7 瀏覽:385
伺服器在山洞裡為什麼還有油 瀏覽:887
天天基金app在哪裡下載 瀏覽:975
伺服器軟路由怎麼做 瀏覽:293
冰箱壓縮機出口 瀏覽:229
OPT最佳頁面置換演算法 瀏覽:645
網盤忘記解壓碼怎麼辦 瀏覽:853
文件加密看不到裡面的內容 瀏覽:654