项目需要 摇杆 控制机器,但是在家里调试 摇杆机构不方便,所以采用了 串口 加 电脑键盘按键
=单片机接收串口消息,生成摇杆信息
监控窗体按键信息的代码如下,本来打算用keyup keydown 事件的,发现不行,必须重写 PreTranslateMessage 函数
BOOL Ckey2comDlg::PreTranslateMessage(MSG* pMSG)
{
if (pMSG ->message == WM_KEYDOWN) // If a keydown message
{
unsigned char sndkey;
switch(pMSG ->wParam)
{
case 'A':
case 'S':
case 'D':
case 'W':
case 'O':
case 'M':
case 'B':
sndkey=pMSG ->wParam+'a'-'A';
myCom.SendData(&sndkey,1);
break;
}
}
else if (pMSG ->message == WM_KEYUP) // If a keydown message
{
unsigned char sndkey;
switch(pMSG ->wParam)
{
case 'A':
case 'S':
case 'D':
case 'W':
sndkey=pMSG ->wParam;
myCom.SendData(&sndkey,1);
break;
}
}
return CDialogEx::PreTranslateMessage(pMSG);
}
串口代码如下
// Com.cpp: implementation of the CCom class.
//
//
//#include "includes.h"
//#include "stdio.h"
#include "stdafx.h"
//#include "windows.h"
#include "string.h"
#include "com.h"
#pragma warning(disable:4996)
//
// Construction/Destruction
//
CCom::CCom()
{
//h_Semaphore=CreateSemaphore(NULL,1,1,NULL);
}
CCom::~CCom()
{
CloseCom();
}
DWORD WINAPI CCom::ReadThread(LPVOID lpParam)
{
BYTE *pReadData=NULL;
DWORD dwRead=0; //,dwErr;
CCom *pCom=(CCom*)lpParam;
BOOL ReadState;
pCom->m_running=TRUE;
pReadData=new BYTE[256];
while(pCom->m_running==TRUE)
{
//系统读出数据
ReadState=ReadFile(pCom->m_hcom,pReadData,256,&dwRead,&pCom->m_osReader);
if(!ReadState)
{
if(GetLastError()==ERROR_IO_PENDING)
{
//等待串口接收结果
GetOverlappedResult(pCom->m_hcom,&pCom->m_osReader,&dwRead,TRUE);
ReadState=TRUE;
}
}
if(ReadState && dwRead)
{
if(pCom->fnc!=NULL)
pCom->fnc(pReadData,dwRead);
}
else Sleep(1);
}
delete pReadData;
return 1;
}
VOID CCom::CloseCom()
{
if(m_running==TRUE)
{
m_running=FALSE;
Sleep(5);
CloseHandle(m_osReader.hEvent);
CloseHandle(m_osWriter.hEvent);
CloseHandle(m_hcom);
}
}
DWORD CCom::SendData(const BYTE *src,DWORD len)
{
DWORD dwWrite;
BOOL bResult;
if(m_running==FALSE) return len;
//WaitForSingleObject(h_Semaphore,INFINITE);
do{
m_osWriter.Offset=0;
m_osWriter.OffsetHigh=0;
dwWrite=0;
bResult=WriteFile(m_hcom,src,len,&dwWrite,&m_osWriter);
if(!bResult)
{
if(GetLastError()==ERROR_IO_PENDING)
{
GetOverlappedResult(m_hcom,&m_osWriter,&dwWrite,TRUE); //等待异步写完成
bResult=TRUE;
}
}
len-=dwWrite;
src+=dwWrite;
}while(len && bResult==TRUE);
//ReleaseSemaphore(h_Semaphore,1,NULL); //释放信号量
return len;
}
BOOL CCom::OpenCom(LPCTSTR lpName, DWORD boud,VFNC recdeal)
{
TCHAR portName[128];
BOOL UsbMode=FALSE;
portName[0]=0;
strcat(portName,lpName);
if(strlen(portName)==5)
{
TCHAR tmp[128]="\\\\.\\";
strcat(tmp,portName);
strcpy(portName,tmp);
}
m_hcom=CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL , OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hcom == INVALID_HANDLE_VALUE)
{
return FALSE;
}
else
{
DCB wdcb = {0};
GetCommState(m_hcom, &wdcb);
wdcb.BaudRate = boud;
wdcb.ByteSize = 8;
//设置串口参数
SetCommState(m_hcom, &wdcb);
//设置串口超时参数
COMMTIMEOUTS toUsb =// 串口超时控制参数
{
1, // 读字符间隔超时时间
1, // 读操作时每字符的时间
100, // 基本的(额外的)读超时时间
0, // 写操作时每字符的时间
0 // 基本的(额外的)写超时时间
};
COMMTIMEOUTS toNormal =// 串口超时控制参数
{
50, // 读字符间隔超时时间
1, // 读操作时每字符的时间
50, // 基本的(额外的)读超时时间
2, // 写操作时每字符的时间
100 // 基本的(额外的)写超时时间
};
if(UsbMode==TRUE) SetCommTimeouts(m_hcom, &toUsb);
else SetCommTimeouts(m_hcom, &toNormal);
//设置串口缓冲队列
SetupComm(m_hcom, 1024, 1024);
//清空并结束串口当前动作
PurgeComm(m_hcom, PURGE_TXCLEAR | PURGE_RXCLEAR);
fnc=recdeal;
FillMemory(&m_osReader, sizeof(OVERLAPPED),0);
FillMemory(&m_osWriter, sizeof(OVERLAPPED),0);
m_osReader.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_osWriter.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
HANDLE hThread =CreateThread(NULL, 0, ReadThread, this, 0, &dwThreadID);
CloseHandle(hThread);
}
return TRUE;
}