Anemoia-ESP32 串口手柄代码

Anemoia-ESP32 串口手柄代码 利用电脑串口进行控制// UartStickDlg.cpp: 实现文件 // #include stdafx.h #include UartStick.h #include UartStickDlg.h #include afxdialogex.h // CUartStickDlg 对话框 CUartStickDlg::CUartStickDlg(CWnd* pParent /*nullptr*/) : CDialog(IDD_UARTSTICK_DIALOG, pParent) , m_strComPort(_T()) { m_hIcon AfxGetApp()-LoadIcon(IDR_MAINFRAME); } void CUartStickDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_strComPort); } BEGIN_MESSAGE_MAP(CUartStickDlg, CDialog) ON_WM_KEYDOWN() ON_WM_KEYUP() ON_BN_CLICKED(IDC_B_UP, CUartStickDlg::OnBnClickedBUp) ON_BN_CLICKED(IDC_B_DN, CUartStickDlg::OnBnClickedBDn) ON_BN_CLICKED(IDC_B_LEFT, CUartStickDlg::OnBnClickedBLeft) ON_BN_CLICKED(IDC_B_RIGHT, CUartStickDlg::OnBnClickedBRight) ON_BN_CLICKED(IDC_B_B, CUartStickDlg::OnBnClickedBB) ON_BN_CLICKED(IDC_B_A, CUartStickDlg::OnBnClickedBA) ON_BN_CLICKED(IDC_B_OPEN, CUartStickDlg::OnBnClickedBOpen) ON_BN_CLICKED(IDC_B_SELECT, CUartStickDlg::OnBnClickedBSelect) ON_BN_CLICKED(IDC_B_START, CUartStickDlg::OnBnClickedBStart) END_MESSAGE_MAP() // CUartStickDlg 消息处理程序 BOOL CUartStickDlg::OnInitDialog() { return TRUE; // 除非将焦点设置到控件否则返回 TRUE } void CUartStickDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { DoKeyDownOrUp(nChar, TRUE); } void CUartStickDlg::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { DoKeyDownOrUp(nChar, FALSE); } BOOL CUartStickDlg::PreTranslateMessage(MSG * pMsg) { bool bFilter false; if (pMsg-message WM_KEYDOWN) { switch (pMsg-wParam) { case W: case A: case S: case D: case J: case K: case G: case H: bFilter TRUE; DoKeyDownOrUp(pMsg-wParam, TRUE); } if (bFilter) return TRUE; } else if (pMsg-message WM_KEYUP)// 处理WM_KEYUP消息 { switch (pMsg-wParam) { case W: case A: case S: case D: case J: case K: case G: case H: bFilter TRUE; DoKeyDownOrUp(pMsg-wParam, FALSE); } if (bFilter) return TRUE; } return FALSE; } void CUartStickDlg::OnBnClickedBUp() { UINT n W; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBDn() { UINT n S; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBLeft() { UINT n A; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBRight() { UINT n D; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBB() { UINT n J; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBA() { UINT n K; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBSelect() { UINT n G; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } void CUartStickDlg::OnBnClickedBStart() { UINT n H; DoKeyDownOrUp(n, TRUE); ::Sleep(100); DoKeyDownOrUp(n, FALSE); } DWORD __stdcall CUartStickDlg::__RecvThread(void * lpp) { CUartStickDlg* pThis (CUartStickDlg*)lpp; if (pThis) { pThis-RecvThread(); } return 0; } void CUartStickDlg::RecvThread() { char buffer[12560] {}; DWORD bytesRead; OVERLAPPED ovlp {}; ovlp.hEvent CreateEvent(0, TRUE, FALSE, NULL); while (true) { if (m_hSerial ! INVALID_HANDLE_VALUE /* WaitCommEvent(m_hSerial, NULL, NULL)*/) { //与发送之间进行锁定 //CAutoLock lock(m_lockRW); BOOL bRead ReadFile(m_hSerial, buffer, sizeof(buffer) - 1, bytesRead, ovlp); if (!bRead GetLastError() ERROR_IO_PENDING) { // 等待读取完成 WaitForSingleObject(ovlp.hEvent, INFINITE); GetOverlappedResult(m_hSerial, ovlp, bytesRead, FALSE); bRead TRUE; } if (bRead bytesRead 0) { buffer[bytesRead] \0; // 打印ESP32发送的调试信息 printf(\n[ESP32]%s, buffer); } ResetEvent(ovlp.hEvent); } Sleep(10); } } void CUartStickDlg::SendThread() { OVERLAPPED ovlp {}; ovlp.hEvent CreateEvent(0, TRUE, FALSE, NULL); while (true) { uint8_t currentState (uint8_t)m_Kstate; // 只在状态变化时发送,如果方向键按下也需发送 if (currentState/* || currentState ! previousState || direct_key_down(currentState)*/) { previousState currentState; // 构建数据包 uint8_t packet[] { START_BYTE, currentState, currentState }; DWORD bytesWritten; if (m_hSerial ! INVALID_HANDLE_VALUE) { //与发送之间进行锁定 //CAutoLock lock(m_lockRW); BOOL bWrWriteFile(m_hSerial, packet, sizeof(packet), bytesWritten, ovlp); if (!bWr GetLastError() ERROR_IO_PENDING) { // 等待读取完成 WaitForSingleObject(ovlp.hEvent, INFINITE); GetOverlappedResult(m_hSerial, ovlp, bytesWritten, FALSE); bWr TRUE; } ResetEvent(ovlp.hEvent); } } Sleep(25); // 控制发送频率 40次/s } } DWORD __stdcall CUartStickDlg::__SendThread(void * lpp) { CUartStickDlg* pThis (CUartStickDlg*)lpp; if (pThis) { pThis-SendThread(); } return 0; } bool direct_key_down(uint8_t st) { if (st(uint8_t)CONTROLLER::Up || st (uint8_t)CONTROLLER::Down || st (uint8_t)CONTROLLER::Left || st (uint8_t)CONTROLLER::Right ) { return true; } return false; } // 打开串口 bool CUartStickDlg::OpenSerialPort(CString portName, int baudRate) { CString Full L\\\\.\\ portName; m_hSerial CreateFileW(Full, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, NULL); if (m_hSerial INVALID_HANDLE_VALUE) { return false; } DCB dcbSerialParams { 0 }; dcbSerialParams.DCBlength sizeof(dcbSerialParams); if (!GetCommState(m_hSerial, dcbSerialParams)) { CloseHandle(m_hSerial); m_hSerial INVALID_HANDLE_VALUE; return false; } dcbSerialParams.BaudRate baudRate; dcbSerialParams.ByteSize 8; dcbSerialParams.StopBits ONESTOPBIT; dcbSerialParams.Parity NOPARITY; if (!SetCommState(m_hSerial, dcbSerialParams)) { CloseHandle(m_hSerial); m_hSerial INVALID_HANDLE_VALUE; return false; } COMMTIMEOUTS timeouts { 0 }; timeouts.ReadIntervalTimeout 50; timeouts.ReadTotalTimeoutConstant 50; timeouts.ReadTotalTimeoutMultiplier 10; timeouts.WriteTotalTimeoutConstant 50; timeouts.WriteTotalTimeoutMultiplier 10; if (!SetCommTimeouts(m_hSerial, timeouts)) { CloseHandle(m_hSerial); m_hSerial INVALID_HANDLE_VALUE; return false; } return true; } void CUartStickDlg::OnBnClickedBOpen() { if (m_hRecv) return; //打开串口 UpdateData(TRUE); //打开串口 redo: DWORD dwTick GetTickCount(); if (!OpenSerialPort(m_strComPort, 115200)) { if (GetTickCount() - dwTick 10000) { Sleep(1); goto redo; } MessageBox(L错误: 无法打开串口); return; } if (!AllocConsole()) { AfxMessageBox(L控制台窗口创建失败); return; } // 2. 重定向标准输入输出 FILE* pFile nullptr; freopen_s(pFile, CONOUT$, w, stdout); freopen_s(pFile, CONOUT$, w, stderr); freopen_s(pFile, CONIN$, r, stdin); // 3. 设置控制台标题 SetConsoleTitle(LUartStick对话框控制台输出); printf(使用printf输出测试\n); //收发线程 m_hRecv CreateThread(0, 0, __RecvThread, this, 0, 0); m_hSend CreateThread(0, 0, __SendThread, this, 0, 0); } __declspec(noinline) CONTROLLER _key_down_up(CONTROLLER kstate, CONTROLLER flagm, bool bDownOrUp) { if (bDownOrUp) kstate (CONTROLLER)((uint8_t)kstate | (uint8_t)flagm); else kstate (CONTROLLER)((uint8_t)kstate (~(uint8_t)flagm)); return kstate; } void CUartStickDlg::DoKeyDownOrUp(UINT nChar, BOOL bDownOrUp) { switch (nChar) { case W: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Up, bDownOrUp); break; case S: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Down, bDownOrUp); break; case A: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Left, bDownOrUp); break; case D: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Right, bDownOrUp); break; case J: m_Kstate _key_down_up(m_Kstate, CONTROLLER::B, bDownOrUp); break; case K: m_Kstate _key_down_up(m_Kstate, CONTROLLER::A, bDownOrUp); break; case G: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Select, bDownOrUp); break; case H: m_Kstate _key_down_up(m_Kstate, CONTROLLER::Start, bDownOrUp); break; default: break; } //发送状态 CString strKeyStl; strKeyStl.Format(L[KeySt]0x%02X\n, m_Kstate); OutputDebugStringW(strKeyStl); }