C++串口通信 WriteFile函数疑惑

qq_38382826 2017-09-03 09:04:42
小子是C++小白,最近要实现一个随动机械臂的项目,实现的框架是kinect+VS2015+opencv+arduino
苦于C++与arduino的通信难以实现,尝试学习串口通信,对WriteFile函数的疑惑困扰小子不短时间,急求解惑。

//代码如下

/ chuankouxuexi.cpp : Defines the entry point for the console application.
//
#include <afx.h>
#include "stdafx.h"
#include "windows.h"
#include "iostream"
#include "stdio.h"

using namespace std;

DWORD WINAPI ThreadOne(LPVOID lpParameter)
{
/**int i = 0;
for (i = 0; i < 10; i++)
{**/
cout << "thread one is running " << (char *)lpParameter << endl;

/**if (i == 5)
{
//关闭线程自己
ExitThread(300);
}
}**/
return 0;
}

int main()
{
HANDLE FILE;
DWORD dwerror;


FILE = CreateFile(_T("COM4"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);//FILE_FLAG_OVERLAPPED 异步通信
if (FILE == (HANDLE)0xFFFFFFFF);
{
dwerror = GetLastError();
cout << dwerror << endl;/***************
【0】-操作成功完成。
【1】 - 功能错误。
【2】 - 系统找不到指定的文件。
【3】 - 系统找不到指定的路径。
【4】 - 系统无法打开文件。
【5】 - 拒绝访问。
【6】 - 句柄无效。**********/
//MessageBox(NULL,str,TEXT("错误报告"), MB_OK);//*******************//MB_ICONINFORMATION | MB_YESNO

}
system("pause");

DCB dcb;
dcb.BaudRate = 9600; //波特率为9600 dcb.BaudRate
dcb.ByteSize = 32; //数据位数为32位 dcb.ByteSize
dcb.Parity = EVENPARITY; //偶校验 dcb.Parity
dcb.StopBits = 2; //两个停止位 dcb.StopBits
dcb.fBinary = TRUE;
dcb.fParity = TRUE; //TRUE 不是TRue
if (!SetCommState(FILE, &dcb))
{
cout << "串口设置出错!" << endl;
}
system("pause");
SetupComm(FILE, 1024, 1024); //分配缓存区,输入缓存区,输出缓存区
memset(&FILE, 0, sizeof(FILE));

COMMTIMEOUTS timeout;
memset(&timeout, 0, sizeof(timeout));//void *memset(void *s, int ch, size_t n); [3]memset函数解释:将 s 中后 n 个字节 (typedef unsigned int size_t)用 ch 替换并返回 s 。
//memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。sizeof()
timeout.ReadIntervalTimeout = MAXWORD;
timeout.ReadTotalTimeoutMultiplier = 0;
timeout.ReadTotalTimeoutConstant = 0;
timeout.WriteTotalTimeoutMultiplier = 50;
timeout.WriteTotalTimeoutConstant = 50;
SetCommTimeouts(FILE, &timeout);

HANDLE hCommWatchThread;//建立线程
hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, //安全属性
0,//初始化线程栈的大小,缺省为与主线程大小相同
(LPTHREAD_START_ROUTINE)ThreadOne, //线程的全局函数
"Testone", //此处传入了主框架的句柄
0, NULL);

if (hCommWatchThread == NULL)
{
cout << "open thread fail" << endl;
}
system("pause");

OVERLAPPED overlap;
int x = 100;
DWORD dwWritenSize;
overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //创建读取数据的句柄
WriteFile(FILE, &x, 4, &dwWritenSize, &overlap);
BOOL bRet = ::WriteFile(FILE, &x, 4, &dwWritenSize, &overlap);
if (bRet)
{
cout << "write file successfully" << endl;
}
else
{
DWORD dwError = GetLastError();
cout << dwError << endl; //提示句柄无效
/** 清空串口缓冲区 */
PurgeComm(FILE, PURGE_RXCLEAR | PURGE_RXABORT);
//return false;
}
system("pause");

BOOL ReadData = TRUE;
ReadData = ReadFile(FILE, &x, 1, &dwWritenSize, NULL);
cout << ReadData << endl;
system("pause");
return 0;
}


运行结果,错误:句柄无效,还有建立的线程怎么用?急求解惑
...全文
504 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
倚栏|听风 2017-09-06
  • 打赏
  • 举报
回复
句柄无效是不是因为要打开的串口不存在,打开错误 建立的线程在创建的时候如果如果指定创建之后立即运行,应该已经是在运行得了.实在不放心 就在main函数里面加个Sleep(10);
Really_want 2017-09-04
  • 打赏
  • 举报
回复
抱歉!学艺不精,不能快速定位问题。提个建议,下次发贴时,先排查、定位到具体问题,比如“WriteFile函数怎么返回值是0”,然后提供参考的代码;代码用对应语言的代码格式,比如缩进,这样有助于代码阅读者快速理解代码。
northwesternwind 2017-09-03
  • 打赏
  • 举报
回复
线程只是提示正在运行,没有和Io动作紧密配合,不过不要紧也能用。 串口操作代码大概3个问题: 1. overlap变量赋值不完整, 试着先全部清零怎么样:
引用
OVERLAPPED overlap; int x = 100; DWORD dwWritenSize; overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //创建读取数据的句柄
2. 写操作之后立即调用PUrgeComm时有问题的,因为writefile使用了overlap, 所以写入是异步操作,必须等待写入完成。否则 PurgeComm会让数据输出丢失。 3. FILE这个变量名字好像有冲突,改下名字试试。
qq_38382826 2017-09-03
  • 打赏
  • 举报
回复
按三楼大大的建议改了: 1.overlap定以后,清零; 2.FILE改了变量名; 但运行结果还是不变 3.purgecomm是写入无效后后清零的

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧