当前位置:网站首页>[MFC development] serial port communication example
[MFC development] serial port communication example
2022-07-22 04:23:00 【Taozi825232603】
I just learned a little bit about serial port recently , Specific about “ A serial port ”、“USB”、“HID” And other related words , You can go to Baidu by yourself , Or read a book .
Here I will share a simple operation , stay MFC in , Use the program to realize the communication between the upper computer and the lower computer . What about the upper computer , This is the computer , What about the next computer , I choose a treasure that I can buy USB Relay . If you don't know what the relay is, you can baidu , I won't go into details either .
This USB What about the relay , It can be used as in the red circle “A0 01 01 A2” To achieve communication , This is 16 It's binary .
If you have a serial port debugging assistant , You can open it , hold USB Plug the relay into the computer , Then follow the operation on the following figure , You will hear “ Crack ” A voice , The relay is closed . The same goes for closing the relay . It will be “ Crack ” A voice .
————————————————————————————————
So next , We will use MFC To complete such an operation .
Workflow :1、 Find the serial port --------->2、 Open the serial port ----------->3、 send out “ open ”( Here are “ Crack ”)----------->4、 send out “ Turn off ”( It's also here “ Crack ”)-------->5、 Turn off the serial port
First , We create a MFC,
Put this in the dialog 5 Button .
They correspond to each other 5 A function .
The header function is added :
#include "Dbt.h"
#include "setupapi.h"
————————— Look for the relay ———————————
Then first, look for the relay , Generally, there are two automatic methods ,1、 Traverse USB equipment 2、 Traverse the registry
You can refer to here :https://blog.csdn.net/wangningyu/article/details/78696221
Traverse the registry , There are also two kinds of ,
One is in \HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM Look under this path , Only those with device access can be found COM mouth , Can't see who is connected
The other way , Is in \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB , Use the corresponding PID VID look for ( There is a small problem with this method , That's me USB After the device is plugged into different ports on the computer , Will be registered leaving traces , When I use the program to find it, I can only find the top one , That is, the one who was registered for the first time )
Everyone wants to know their USB Where is the relay inserted , It's also very simple. , Right click manually “ This computer ” open “ management ”, Click on the left “ Device manager ”, Last point “ port ”
You can see that this relay is COM5.
Specifically, how do you want to find your device , You can choose according to the situation .
I used :( If you find something wrong , You can interrupt to have a look )
/************************************************************************/
// According to... In the registry PID、VID Information reading
/************************************************************************/
int COpen_COMDlg::SearchRelayCOM(CString strVidPid)
{
DWORD dwIndex = 0;
HKEY hKey;
TCHAR CommName[_MAX_FNAME] = { 0x00 };
DWORD lcbName = _MAX_FNAME;
DWORD lValue = MAX_PATH;
TCHAR szValue[MAX_PATH];
LONG lRtn = 0;
CString strTemp, strName, strKey;
int nPort = -1;
int nStart = -1;
int nEnd = -1;
// Read PID Corresponding port
strTemp.Format(_T("SYSTEM\\CurrentControlSet\\Enum\\USB\\%s"), strVidPid);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strTemp, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
dwIndex = 0;
while (RegEnumKey(hKey, dwIndex++, CommName, lcbName) == ERROR_SUCCESS)
{
// Read PID Corresponding port
strKey.Format(_T("SYSTEM\\CurrentControlSet\\Enum\\USB\\%s\\%s\\Device Parameters"), strVidPid, CommName);
RegCloseKey(hKey);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
lRtn = RegQueryValueEx(hKey, _T("PortName"), NULL, &lValue, (LPBYTE)szValue, &lValue);
if (lRtn == ERROR_SUCCESS)
{
// Looking for serial port information
strName.Format(_T("%s"), szValue);
// Can we find COM( Theoretically, it can )
nStart = strName.Find(_T("COM"), 0);
//nEnd = strName.Find(_T(")"), 0);
//if (nStart == -1 || nEnd == -1)
if (nStart == -1)
{
RegCloseKey(hKey);
return -1;
}
//strTemp = strName.Mid(nStart + 3, nEnd - nStart);
strTemp = strName.Mid(nStart+3, 1);
nPort = _tstoi(LPCTSTR(strTemp));
RegCloseKey(hKey);
return nPort;
}
}
lValue = MAX_PATH;
lcbName = MAX_PATH;
}
RegCloseKey(hKey);
}
return nPort;
}
———————— Turn on the relay ————————
The previous step , We assume that we already know where the relay is COM The number of the mouth
So here , We can use this code to open a port , Mainly used CreateFile This function . By the way, I also allocated the buffer size in this function , A timeout structure is also set 、 In the end, I set up DCB.( You can refer to 《 Computer advanced interface technology 》 This book )
void COpen_COMDlg::OnBnClickedOpen()
{
DWORD dwError;
DCB dcb;
COMMTIMEOUTS Timeouts;
CString str;
str.Format(_T("\\\\.\\COM%d"), RelayPort);
//str.Format(_T("\\\\.\\COM6"));
hCom = CreateFile( str, //str.GetBuffer(50),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0, // FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if(hCom != INVALID_HANDLE_VALUE)
{
GetDlgItem(IDC_OPEN)->EnableWindow(FALSE);
GetDlgItem(IDC_START)->EnableWindow(TRUE);
GetDlgItem(IDC_CLOSE)->EnableWindow(TRUE);
AfxMessageBox(_T(" Serial port opened successfully !"));
}
else
{
dwError = GetLastError();
AfxMessageBox(_T(" Failed to open serial port !"));
return;
}
SetupComm(hCom, 1024, 1024); // Allocate buffer
// Set the timeout structure
Timeouts.ReadIntervalTimeout = 1000;
Timeouts.ReadTotalTimeoutMultiplier = 500;
Timeouts.ReadTotalTimeoutConstant = 500;
Timeouts.WriteTotalTimeoutConstant = 500;
Timeouts.WriteTotalTimeoutMultiplier = 500;
SetCommTimeouts(hCom, &Timeouts);
// Configure serial interface ( That is, change the device control block DCB Member variable value of )
GetCommState(hCom, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONE5STOPBITS;
SetCommState(hCom, &dcb);
}
————————— send out “ open ”——————————
The serial port has been opened by us , Then we'll send it here “ open ”
Use this function :( I shared this function from a VR Look at the source code of the device , His code is quite complete , Unfortunately, the web link cannot be found , I'm sorry )
BOOL COpen_COMDlg::ComSendPacket(unsigned char *sendbuffer, int length)
{
DWORD dwBytesWrite = length;
DWORD dwErrorFlags;
BOOL bWriteStat;
if (!sendbuffer)
return FALSE;
ResetEvent(ComWriteOverlapped.hEvent);
// Clear the output buffer of the serial port
PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR); // Immediately interrupt all writes and return immediately , Even if the write operation has not been completed | Clear output buffer
ClearCommError(hCom, &dwErrorFlags, &ComWriteStat);
bWriteStat = WriteFile(hCom, sendbuffer, dwBytesWrite, &dwBytesWrite, &ComWriteOverlapped);
if (!bWriteStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(ComWriteOverlapped.hEvent, 2000);
}
else
{
ClearCommError(hCom, &dwErrorFlags, &ComWriteStat);
// Clear the output buffer of the serial port
PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR); // Immediately interrupt all writes and return immediately , Even if the write operation has not been completed | Clear output buffer
ResetEvent(ComWriteOverlapped.hEvent);
AfxMessageBox(_T(" Serial port failed to send data !"));
return FALSE;
}
}
ClearCommError(hCom, &dwErrorFlags, &ComWriteStat);
// Clear the output buffer of the serial port
PurgeComm(hCom, PURGE_TXABORT | PURGE_TXCLEAR); // Immediately interrupt all writes and return immediately , Even if the write operation has not been completed | Clear output buffer
ResetEvent(ComWriteOverlapped.hEvent);
return TRUE;
}
And then we give “ Send on ” Button to add an event :
void COpen_COMDlg::OnBnClickedStart()
{
unsigned char OpenRelay[] = { 0xA0, 0x01, 0x01, 0xA2 };
while (!ComSendPacket(OpenRelay, 4))
{
AfxMessageBox(_T(" Resending !"));
}
AfxMessageBox(_T(" Serial port sends data successfully !"));
}
So this is actually where , You generate a project , use 3 Buttons can be heard “ Crack ” The sound of . At this time, the relay operation indicator will also light up .
——————————— send out “ Turn off ”————————
Basically the same as the previous step , Change to :
unsigned char CloseRelay[] = { 0xA0, 0x01, 0x00, 0xA1 };
while (!ComSendPacket(CloseRelay, 4))
that will do .
—————————— Turn off the serial port ——————————
Now suppose we don't want to play this serial port , Then we should get together and break up with him .
void COpen_COMDlg::OnBnClickedClose()
{
// Disable all events on the serial port
SetCommMask(hCom, 0);
// Clear the data terminal ready signal
EscapeCommFunction(hCom, CLRDTR);
// Discard the output or input buffer characters of the communication resource and terminate the pending read on the communication resource 、 Write operation
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(hCom);
hCom = NULL;
AfxMessageBox(_T(" The serial port is closed successfully !"));
return;
}
That's it .
——————————.h In file ————————————
We add :
private:
int SearchRelayCOM(CString strVidPid);
BOOL ComSendPacket(unsigned char *sendbuffer, int length);
int RelayPort;
HANDLE hCom;
OVERLAPPED ComWriteOverlapped;
COMSTAT ComWriteStat;
public:
afx_msg void OnBnClickedFind();
afx_msg void OnBnClickedOpen();
afx_msg void OnBnClickedClose();
afx_msg void OnBnClickedStart();
afx_msg void OnBnClickedOver();
that will do . Let's try it , Listen to the relay crazily “ Crack ”/“ Crack ”/“ Crack ”………
Don't say the , Just finished double 11, Ah …………T T
边栏推荐
- C # use timer and ProgressBar controls to make a countdown timer
- defineExpose ,父组件获取子组件中的属性值
- libpng error: iTXt: chunk data is too large error: PNG unsigned integer out of range
- 13.onkeydown,up和onkeypress的区别?
- Quickly determine whether a file has a virus
- How to recover the problems that appear when you first write a blog - use the CSDN markdown editor template
- Defineexpose, the parent component gets the attribute value in the child component
- ionic4学习笔记4--新增一个tab页面
- Welcome to the CSDN markdown editor template
- oracle ebs form表单常用对象及其关系
猜你喜欢
Welcome to the CSDN markdown editor template
vite打包报错[rollup-plugin-dynamic-import-variables] Unexpected token ,竟然是因为console.log
[download attached] the vulnerability scanning tool appscan is easy to install and use
minio文件系统8.0.3
Judge whether the binary tree is symmetric
ArgoCD 用户管理、RBAC 控制、命令行登录、App 同步
移动端基础
Web server
无锡对全市必胜客门店开展食品安全隐患大排查
Basic principles and differences between countdownlatch and cyclicbarrier
随机推荐
[零基础] 减少50%的bug,只需要30分钟...
Import and export of vmvare virtual machine (OVA format)
[dark horse morning post] Suning Zhang Kangyang lost the lawsuit and was "debt recovery" of 1.7 billion; The president of hengchi said that hengchi's big sale was a foregone conclusion; Iphone14promax
快速判断一个文件是否有病毒
[comprehensive pen test] difficulty 3.5/5, multi solution popular binary tree pen test
3.变量的声明提升?
ionic4学习笔记5--自定义公共模块
[Nuxt 3] (七)获取数据
Defineexpose, the parent component gets the attribute value in the child component
How to recover the problems that appear when you first write a blog - use the CSDN markdown editor template
Matlab r2014a help file cannot be copied
【综合笔试题】难度 3.5/5,多解法热门二叉树笔试题
1.typeof查看变量类型?
js如何控制整个页面滚动条的位置
第三方之百度AI使用总结
web服务器
ionic4学习笔记13-某东项目分类列表
yarn的安装与使用
GAN网络的重新学习的一些内容记录
ionic4学习笔记12-某东项目栅格完成商品列表