gps模塊接USB口連接在電腦上 怎么用C語言 連接串口 并讀取里面的資料
請大佬詳細告知 小白求教
uj5u.com熱心網友回復:
搜“serial庫”uj5u.com熱心網友回復:
#ifndef _COMM_H_
#define _COMM_H_
#define WM_FOUNDCOMM WM_USER+1 //自定義訊息WM_FOUNDCOMM,收到該訊息表示串口已經找到
#define WM_READCOMM WM_USER+2 //自定義訊息WM_READCOMM,收到該訊息緩沖區有資料, 可以讀取
extern void FindComm(); //申明為外部函式
extern void OpenComm(int nBaud, int nData, int nStop, int nCal);
extern void CloseComm();
extern UINT ThreadFunc(LPVOID pParam); //申明全域執行緒處理函式
extern CString DisplayCString2Hex(CString Data, bool Blank_allow);
extern CString DisplayHex2CString(CString Data);
extern int ConvertHexC2String(CString str, CByteArray &senddata);
extern bool ComIsOK; //申明為外部變數
extern HANDLE hCom;
extern CString strcomname;
#endif
#include "stdafx.h"
#include "commassist.h"
#include "commassistDlg.h"
#include "comm.h"
char ConvertHexChar(char ch);
HANDLE hCom; //串口句柄
CString strcomname; //串口名,如"COM1"
bool ComIsOK; //串口打開狀態標識,為真表示已打開,否則未打開
//============自動尋找串口函式=================================
//函式功能:通過掃描注冊表來找出當前所有物理串口
//輸入引數:無
//回傳型別:無
//說 明:若搜索成功,則每搜到一個串口便發送訊息通知主對話框,并將串口號以WPARAM傳遞
void FindComm()
{
//列舉當前系統中的串口
LONG result = 0;
HKEY key = NULL;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, //需要打開的主鍵的名稱
"HARDWARE\\DEVICEMAP\\SERIALCOMM", //需要打開的子鍵的名稱, 設備串口
0, //保留必須設定為0
KEY_READ, //安全訪問標記也就是權限
&key); //得到的將要打開鍵的句柄當不再需要句柄
//必須呼叫 RegCloseKey 關閉它
if (result)
{
AfxMessageBox("無法獲取串口請確認是否安裝并連接串口!"); return;
}
TCHAR portname[250]; //串口名
TCHAR data[250];
DWORD portnamelen = 0; //串口名長度
DWORD datalen = 0;
int index = 0;
while (1) //找完COM后跳出
{
portnamelen = 255;
datalen = 255;
result = RegEnumValue(key, //Long一個已打開項的句柄或者指定一個標準項名
index++, //Long欲獲取值的索引。注意第一個值的索引編號為零
portname, //String用于裝載位于指定索引處值名的一個緩沖區
&portnamelen, //Long用于裝載lpValueName緩沖區長度的一個變數。
//一旦回傳它會設為實際載入緩沖區的字符數量
NULL, //Long未用設為零
NULL, //Long用于裝載值的型別代碼的變數
(LPBYTE)data, //Byte用于裝載值資料的一個緩沖區
&datalen); //Long用于裝載lpData緩沖區長度的一個變數。
//一旦回傳它會設為實際載入緩沖區的字符數量
if (result) break;
//發送訊息,WM_USER+1為自定義訊息,即找到串口的,并將串口號"COMx"通過WPARAM引數傳送給主對話框視窗
//::AfxGetMainWnd()->m_hWnd,獲得主對話框句柄
//(WPARAM)(LPCTSTR)data,型別轉換
::SendMessage(::AfxGetMainWnd()->m_hWnd, WM_FOUNDCOMM, (WPARAM)(LPCTSTR)data, 0);
}
RegCloseKey(key); //呼叫 RegCloseKey 關閉打開鍵的句柄
}
//============自動尋找串口函式結束==================
//==========串口打開函式===========================
//功 能:打開串口,將已打開的串口句柄賦值給hCom,給出串口打開狀態ComIsOK,完成串
//輸入引數:波特率,資料位,停止位,校驗位
//回傳型別:無
void OpenComm(int nBaud, int nData, int nStop, int nCal)
{
hCom = CreateFile(strcomname, //串口號
GENERIC_READ | GENERIC_WRITE, //允許讀或寫
0, //獨占方式
NULL,
OPEN_EXISTING, //打開而不是創建
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,//重疊方式,用于異步通信
NULL);
if (hCom == INVALID_HANDLE_VALUE)
{
AfxMessageBox("打開COM失敗串口不存在或已被占用!");
ComIsOK = false;
return;
}
ComIsOK = true;
SetCommMask(hCom, EV_TXEMPTY | EV_RXCHAR); //設定事件掩碼,暫時沒用上
SetupComm(hCom, 1024, 1024); //設定輸入緩沖區和輸出緩沖區的大小都是1024
COMMTIMEOUTS TimeOuts;
//設定讀超時
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutConstant = 0;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
//設定寫超時
TimeOuts.WriteTotalTimeoutConstant = 500;
TimeOuts.WriteTotalTimeoutMultiplier = 100;
if (SetCommTimeouts(hCom, &TimeOuts) == false)
{
CloseHandle(hCom);
ComIsOK = false;
return;
}
//串口屬性配置
DCB dcb;
GetCommState(hCom, &dcb);
dcb.BaudRate = nBaud; //dcb.BaudRate=9600; //波特率為9600
dcb.ByteSize = nData; //dcb.ByteSize=8; //每個位元組為8位
dcb.StopBits = nStop; //dcb.StopBits=ONESTOPBIT; //1位停止位
dcb.Parity = nCal; //dcb.Parity=NOPARITY; //無奇偶檢驗位 第 18 頁 共 39 頁
SetCommState(hCom, &dcb);
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
if (SetCommState(hCom, &dcb) == false)
{
CloseHandle(hCom);
ComIsOK = false;
return;
}
return;
}
//==========串口打開函式結束=====================
//==========串口關閉控制函式=====================
void CloseComm()
{
CloseHandle(hCom);
hCom = NULL;
ComIsOK = false;
}
//==========串口關閉控制函式結束==================
//==========串口監聽執行緒函式======================
UINT ThreadFunc(LPVOID pParam)
{
// CCommassistDlg* pdlg = (CCommassistDlg*)pParam; //定義指標指向主對話框
COMSTAT ComStat;
DWORD dwErrorFlags;
while (ComIsOK)
{
DWORD dwBytesRead = 100;
ClearCommError(hCom, &dwErrorFlags, &ComStat);
dwBytesRead = min(dwBytesRead, (DWORD)ComStat.cbInQue);
if (!dwBytesRead)
{
Sleep(10);//continue;//使用continue時打開串口后CPU占用率非常高
}
else ::SendMessage(::AfxGetMainWnd()->m_hWnd, WM_READCOMM, 1, 0); //發 送訊息, 已讀到
}
return 0;
}
//==========串口監聽執行緒函式結束===============
//=================字串轉16進制顯示==========
//字串轉16進制顯示的函式
//傳入引數Data為字串
//Blank_allow為空格允許標志,為真則代表允許加入空格
//函式回傳為CString的結果sResult
CString DisplayCString2Hex(CString Data, bool Blank_allow)
{
CString sResult;
CString sTemp;
int Data_Length;
Data_Length = Data.GetLength();
if (Data_Length == 0) return "";
char *pchar = new char[Data_Length]; //用了new分配記憶體空間,要記得釋放
strncpy(pchar, Data, Data_Length);
for (int i = 0; i<Data_Length; i++)
{
sTemp.Format("%02X", pchar[i]);
if (Blank_allow)
{
if (i == Data_Length - 1) sResult = sResult + sTemp; //去掉最后一個空格
else
sResult = sResult + sTemp + " ";
}
else sResult = sResult + sTemp;
}
delete pchar; //釋放記憶體空間
return sResult;
}
//===============函式結束============================
//=================16進制轉字串======================
//16進制轉字串,輸入16進制的字串,輸出轉換為16進制碼
//傳入引數str為字串,判斷輸入是否按照16進制格式輸入
int ConvertHexC2String(CString str, CByteArray &senddata)
{
//先判斷輸入字串是否2個字符一組
int str_Length, iLength;
int hexdata, l_data;
char hstr, lstr;
char cTemp;
str_Length = str.GetLength();
iLength = 0;
senddata.SetSize(str_Length / 2); //預先設定陣列長度,不設定時,允許有錯
char *ppchar = new char[str_Length];
strncpy(ppchar, str, str_Length);
for (int i = 0; i<str_Length;)
{
cTemp = ppchar[i];
if (cTemp == ' ')
{
//iLength--;
i++;
continue; //如檢測到空格則跳過繼續下一次回圈
}
else
{
hstr = ppchar[i]; //取出字符作為16進制高位
i++;
lstr = ppchar[i]; //取出下一個字符作為16進制低位
if (lstr == ' ') //若取出的低位為空格則不符合16進制2個一組的格式終止回圈
{
AfxMessageBox("請按照16進制每2個字符一組的方式輸入",MB_ICONERROR);
break;
}
else
{
hexdata = ConvertHexChar(hstr); //高位轉換為相應的0進制
l_data = ConvertHexChar(lstr); //低位轉換為相應的10進制
if ((hexdata == -1) || (l_data == -1))
{
AfxMessageBox("請按照16進制字符要求輸入", MB_ICONERROR);
break;
}
else hexdata = hexdata * 16 + l_data; //安裝16進制方式高位低位合并
senddata[iLength] = (char)hexdata; //int整型數轉換為char字符型并存入陣列senddata[]
i++; //進入下一次回圈
iLength++; //成功轉換一組(2個)字符記錄長度加1
}
}
}
senddata.SetSize(iLength);
delete ppchar;
return iLength;
}
//===============函式結束===========================
char ConvertHexChar(char ch)
{
//將一個字符轉換為相應的十六進制
if ((ch >= '0') && (ch <= '9'))
return ch - 48;//0x30;
else if ((ch >= 'A') && (ch <= 'F'))
return ch - 'A' + 10;
else if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
else
return (-1);
}
//=================16進制轉字串顯示=====================
//16進制轉字串顯示的函式
//傳入引數Data為16進制的字串
//函式回傳為CString的結果sResult
CString DisplayHex2CString(CString Data)
{
CString sResult;
CString sTemp;
int Data_Length;
Data_Length = Data.GetLength();
if (Data_Length == 0) return "";
char *pchar = new char[Data_Length]; //用了new分配記憶體空間,要記得釋放
strncpy(pchar, Data, Data_Length);
for (int i = 0; i<Data_Length; i++)
{
sTemp.Format("%02X", pchar[i]);
sResult = sResult + sTemp;
}
delete pchar; //釋放記憶體空間
return sResult;
}
//===============函式結束=============================
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/196237.html
標籤:C語言
上一篇:COC或VIM 命令轉換格式
下一篇:QT自定義QCombox
