关于windows api操作串口,数据读取的问题

hh717744509 2012-05-21 05:23:48
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>


//函数原型
void init_com(void); //定义串口初始化函数
DWORD WINAPI Thread1Proc(LPVOID lParam); //定义子线程函数


//结构定义
struct Thread_Data //定义一个结构类型,用于传参数给子线程
{
HANDLE hcom;
OVERLAPPED vcc;
};

//变量定义
unsigned char receive_data[50]; //定义接收数据缓存
HANDLE m_hCom = NULL; //定义一个句柄,用于打开串口
CRITICAL_SECTION com_cs; //定义临界变量对象


//=======================================================================================
int main(int argc, char* argv[])
{
InitializeCriticalSection(&com_cs); //初始化临界变量

init_com(); //初始化串口
while(1)
{
Sleep(200);//使主线程挂起
}
// CloseHandle(m_hCom);
return 0;
}

void init_com()
{
EnterCriticalSection(&com_cs);//进入临界段
HANDLE hThread1 = NULL;//子线程句柄;
COMMTIMEOUTS TimeOuts;//定义超时结构
DCB dcb; //定义串口设备控制结构
OVERLAPPED wrOverlapped;//定义异步结构
static struct Thread_Data thread_data;//定义一个结构对象,用于给子线程传递参数

//1. 打开串口文件
m_hCom = CreateFile("\\\\.\\com80",GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hCom == INVALID_HANDLE_VALUE)
{
printf("CreateFile fail\n");
}
else
{
printf("CreateFile ok\n");
}

//2. 设置读写缓冲区
if(SetupComm(m_hCom,2048,2048))
{
printf("buffer ok\n");
}
else
{
printf("buffer fail\n");
}

//3. 设置串口操作超时
//memset(&TimeOuts,0,sizeof(TimeOuts));
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutConstant = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 1000;
TimeOuts.WriteTotalTimeoutConstant = 1000;
TimeOuts.WriteTotalTimeoutMultiplier = 1000;
if(SetCommTimeouts(m_hCom,&TimeOuts))
{
printf("comm time_out ok!\n");
}

//4. 设置串口参数
if (GetCommState(m_hCom,&dcb))
{
printf("getcommstate ok\n");
}
else
{
printf("getcommstate fail\n");
}
dcb.DCBlength = sizeof(dcb);
if (BuildCommDCB("9600,n,8,1",&dcb))//填充DCB的数据传输率、奇偶校验类型、数据位、停止位
{
printf("buildcommdcb ok\n");
}
else
{
printf("buildcommdcb fail\n");
}
if(SetCommState(m_hCom,&dcb))
{
printf("setcommstate ok\n");
}
else
{
printf("setcommstate fail\n");
}

//5.初始化异步结构
ZeroMemory(&wrOverlapped,sizeof(wrOverlapped));
wrOverlapped.Offset = 0;
wrOverlapped.OffsetHigh = 0;

if (wrOverlapped.hEvent != NULL)
{ ResetEvent(wrOverlapped.hEvent);
}
wrOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建手工复位事件

//创建一个线程
thread_data.vcc = wrOverlapped;
thread_data.hcom = m_hCom;
hThread1=CreateThread(NULL,0,Thread1Proc,(LPVOID)&thread_data,0,NULL); //『注意』创建线程

LeaveCriticalSection(&com_cs);//推出临界段
}

DWORD WINAPI Thread1Proc(LPVOID lParam) //线程的执行函数
{

Thread_Data* pThread_Data = (Thread_Data*)lParam; //将线程函数参数给新定义的结构指针
HANDLE com= pThread_Data->hcom; //通过新定义的结构指针使用原结构的成员
OVERLAPPED wrOverlapped1 = pThread_Data->vcc; //通过新定义的结构指针使用原结构的成员
COMSTAT ComStat ; //定义一个串口状态结构对象,给结构有10个参数,第九个参数
//DWORD cbInQue; //表示出入缓冲区有多少字节的数据到达,
DWORD word_count; //存放实际读到的数据字节数存放
DWORD Event = 0;
DWORD CommEvtMask=0 ;
DWORD result;
DWORD error;
unsigned int k;

SetCommMask(com,EV_RXCHAR);//设置串口等待事件

while(1)
{ result = WaitCommEvent(com,&CommEvtMask,&wrOverlapped1);//等待事件函数
if(!result)
{ switch(error = GetLastError())
{ case ERROR_IO_PENDING :
break;
case 87:
break;
default:
break;
}
}
else
{ result = ClearCommError(com,&error,&ComStat);
if(ComStat.cbInQue == 0)
{ continue;
}
}

Event = WaitForSingleObject(wrOverlapped1.hEvent,INFINITE);//异步结果等待函数
EnterCriticalSection(&com_cs);
result = ClearCommError(com,&error,&ComStat);
if(ComStat.cbInQue == 0)
{ continue;
}

ReadFile(com,receive_data,ComStat.cbInQue,&word_count,&wrOverlapped1);//从系统接收缓冲区读出接收到得所有数据
LeaveCriticalSection(&com_cs);//推出临界段
printf("%s\n",receive_data);
for(k=0;k<50;k++)
{ receive_data[k] = 0x00;
}
}
return 0;
}


这个是网上的串口读取程序
使用串口助手试验,十进制输入的时候读取正常,但是16进制输入时,发现很多时候读到的都是乱码,就算不是乱码,也是转为ascii码输出的,怎样直接读取串口的16进制数据呢。。。求教
...全文
655 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿粥王 2014-12-23
  • 打赏
  • 举报
回复
可能是没有及时清除上次的内容吧。
hh717744509 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
引用 5 楼 的回复:
引用 4 楼 的回复:
输出16进制格式字符串
printf("%X", num);



不能显示额,无论输入什么都只输F7B168


怎么会呢,你ReadFile得到的数据都是二进制数据吧,那么"%X"就是用16进制表示你的二进制数据啊,如果要输出多个字节那么"%X"变成"%nX"(n是整数,表示要输出几个字节的二进制)就能输指定字节数的二进制
[/Quote]



不懂啊,比如我用串口助手输入33它就输出F0B168 第二位没次运行程序都会变化,然后随便输入什么都是输出F0B168.....WINDOWS API 难道得到的还不是二进制数据么,然后如果是 %s输出就是 33对应3,ascii码。。。。。搞不懂啊
sl51314240 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
引用 4 楼 的回复:
输出16进制格式字符串
printf("%X", num);



不能显示额,无论输入什么都只输F7B168
[/Quote]

怎么会呢,你ReadFile得到的数据都是二进制数据吧,那么"%X"就是用16进制表示你的二进制数据啊,如果要输出多个字节那么"%X"变成"%nX"(n是整数,表示要输出几个字节的二进制)就能输指定字节数的二进制
hh717744509 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
输出16进制格式字符串
printf("%X", num);
[/Quote]


不能显示额,无论输入什么都只输F7B168
sl51314240 2012-05-22
  • 打赏
  • 举报
回复
输出16进制格式字符串
printf("%X", num);
hh717744509 2012-05-22
  • 打赏
  • 举报
回复
就是想问一下,我要将8位ascii转为16进制显示,应该怎么搞额,查了一下资料发现没得给力的呢
hh717744509 2012-05-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
貌似串口中的数据都是ascii码值的形式纯在,要是用串口工具测试,你用十六进制发,你也让他十六进制显示看看。
[/Quote]
我查了一些资料了,怎么让他转为16进制呢,网上都感觉好麻烦额,thankyou
星星x 2012-05-22
  • 打赏
  • 举报
回复
貌似串口中的数据都是ascii码值的形式纯在,要是用串口工具测试,你用十六进制发,你也让他十六进制显示看看。

65,190

社区成员

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

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