C++串口通信收到的数据有一部分乱码

csdndenglu 2014-10-20 03:34:31
谁能给我个纯C++ API函数(不用MFC框架生成)写的串口通信程序呢?包含把收到的字符正确显示到屏幕上的。我之前写的接收程序,用串口助手发字符,接收后cout输出总是有乱码,不知道中间怎么处理就不会出现乱码了?
#include <iostream>
#include <windows.h>
using namespace std;
HANDLE hMutex;

DWORD WINAPI Read(LPVOID lpParamter)
{
//打开端口
HANDLE hCom = CreateFileA("com7", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
//设置超时
COMMTIMEOUTS timeouts;
GetCommTimeouts(hCom, &timeouts);
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(hCom, &timeouts))
{
cout<<"超时设置失败!重新";
CloseHandle(hCom);
return 0;
}

//取得并设置端口状态
DCB dcb;
GetCommState(hCom, &dcb);
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = 9600;
dcb.Parity = 0;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
cout<<"端口状态设置失败!重新";
CloseHandle(hCom);
return 0;
}


char buffer[1024];
DWORD readsize,dwError;
BOOL bReadStatus;
COMSTAT cs;

WaitForSingleObject(hMutex, INFINITE);
while(1)
{
readsize = 0;
ClearCommError(hCom,&dwError,&cs);//取得状态
//数据是否大于所准备缓冲区
if(cs.cbInQue>sizeof(buffer))
{
PurgeComm(hCom,PURGE_RXCLEAR);//清除通信端口数据
return 0;
}
memset(buffer, 0 , sizeof(buffer));
bReadStatus = ReadFile(hCom, buffer, cs.cbInQue, &readsize, 0);
if(readsize>0)
{
cout<<cs.cbInQue;
buffer[cs.cbInQue]='\0';
std::cout<<buffer;
}
Sleep(5);
}
ReleaseMutex(hMutex);
CloseHandle(hCom);
}

void main()
{
HANDLE hThread = CreateThread(NULL, 0, Read, NULL, 0, NULL);
hMutex = CreateMutex(NULL, FALSE, NULL);
CloseHandle(hThread);
while(1)
Sleep(1000);
}
...全文
744 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
同问! 我现在也是这样的问题! 部分乱码!
kingsley1992 2016-10-04
  • 打赏
  • 举报
回复
楼主,你的问题解决了吗
csdndenglu 2014-10-28
  • 打赏
  • 举报
回复
引用 18 楼 zhao4zhong1 的回复:
乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单,不用格式控制符! 但是不用格式控制符,输入输出恰好是你期望的格式的时候好说;等到输入输出不是你期望的格式的时候,你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout! 使用scanf、printf。
使用scanf、printf也不行呀
csdndenglu 2014-10-28
  • 打赏
  • 举报
回复
引用 19 楼 kuenking111 的回复:
用字母代替文字
这是什么意思?没明白。
爱喝雪花啤酒 2014-10-27
  • 打赏
  • 举报
回复
用字母代替文字
赵4老师 2014-10-27
  • 打赏
  • 举报
回复
乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单,不用格式控制符! 但是不用格式控制符,输入输出恰好是你期望的格式的时候好说;等到输入输出不是你期望的格式的时候,你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout! 使用scanf、printf。
赵4老师 2014-10-27
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… 推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
赵4老师 2014-10-26
  • 打赏
  • 举报
回复
推荐使用portmon软件辅助调试串口通讯程序。
csdndenglu 2014-10-26
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
推荐使用portmon软件辅助调试串口通讯程序。
[\\PC-20140805GLML] 这是portmon监测到发送口的: 6719 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6719 0.00000444 SUCCESS 6720 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6720 0.00000047 SUCCESS 6721 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6721 0.00000034 SUCCESS 6722 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6722 0.00000034 SUCCESS 6729 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 5: ..... 6729 0.00040302 SUCCESS 6730 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 22: ...http://emouze.com.. 6730 0.00072859 SUCCESS 6745 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6745 0.00000385 SUCCESS 6746 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6746 0.00000043 SUCCESS 6747 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6747 0.00000050 SUCCESS 6748 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6748 0.00000052 SUCCESS 6757 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 6: ...... 6757 0.00126268 SUCCESS 6758 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 21: ..http://emouze.com.. 6758 0.00098175 SUCCESS 6771 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6771 0.00000371 SUCCESS 6772 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6772 0.00000040 SUCCESS 6773 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6773 0.00000037 SUCCESS 6774 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6774 0.00000038 SUCCESS 6783 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 1: . 6783 0.00049635 SUCCESS 6784 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 26: .......http://emouze.com.. 6784 0.00100803 SUCCESS 6797 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6797 0.00000790 SUCCESS 6798 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6798 0.00000058 SUCCESS 6799 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6799 0.00000036 SUCCESS 6800 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6800 0.00000041 SUCCESS 6809 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 27: ........http://emouze.com.. 6809 0.00058879 SUCCESS 6822 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6822 0.00000482 SUCCESS 6823 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6823 0.00000039 SUCCESS 6824 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6824 0.00000036 SUCCESS 6825 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6825 0.00000037 SUCCESS 6834 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 6: ...... 6834 0.00052878 SUCCESS 6835 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 21: ..http://emouze.com.. 6835 0.00096358 SUCCESS 6846 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6846 0.00000543 SUCCESS 6847 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6847 0.00000081 SUCCESS 6848 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6848 0.00000060 SUCCESS 6849 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6849 0.00000043 SUCCESS 6858 0.00000000 comdebug.exe IRP_MJ_WRITE VCP1 Length 27: ........http://emouze.com.. 6858 0.00054741 SUCCESS 6871 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6871 0.00000381 SUCCESS 6872 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6872 0.00000050 SUCCESS 6873 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6873 0.00000045 SUCCESS 6874 0.00000000 comdebug.exe IOCTL_SERIAL_GET_MODEMSTATUS VCP1 6874 0.00000071 SUCCESS
csdndenglu 2014-10-26
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
推荐使用portmon软件辅助调试串口通讯程序。
用portmon软件看到的接收口的数据也是乱码,为什么呢大神,求指教?我是新手,不懂了
csdndenglu 2014-10-25
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
是否奇偶校验
这个是没有校验的,可是试过加上校验也还是一样乱码,线也没问题
赵4老师 2014-10-25
  • 打赏
  • 举报
回复
是否奇偶校验
csdndenglu 2014-10-25
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
[quote=引用 7 楼 csdndenglu 的回复:] 波特率够低了,是9600的。。。。。。用十六进制将数据打出来?就是cout<<hex<<a或printf(“%x",a)么???
void HexDump(char *buf,int len,int addr) { int i,j,k; char binstr[80]; for (i=0;i<len;i++) { if (0==(i%16)) { sprintf(binstr,"%08x -",i+addr); sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); } else if (15==(i%16)) { sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); sprintf(binstr,"%s ",binstr); for (j=i-15;j<=i;j++) { sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.'); } printf("%s\n",binstr); } else { sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); } } if (0!=(i%16)) { k=16-(i%16); for (j=0;j<k;j++) { sprintf(binstr,"%s ",binstr); } sprintf(binstr,"%s ",binstr); k=16-k; for (j=i-k;j<i;j++) { sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.'); } printf("%s\n",binstr); } } [/quote]麻烦您能详细说一下这个程序么?还有我写的那个为什么乱码呢?
csdndenglu 2014-10-24
  • 打赏
  • 举报
回复
改成Sleep(100),跟Sleep(1000)都还是一样的
csdndenglu 2014-10-24
  • 打赏
  • 举报
回复
波特率够低了,是9600的。。。。。。用十六进制将数据打出来?就是cout<<hex<<a或printf(“%x",a)么???
赵4老师 2014-10-24
  • 打赏
  • 举报
回复
先搜索下载MSDN98,然后 参考MSDN98\SAMPLES\VC98\SDK\WINBASE\IO\SERIAL\*.*
赵4老师 2014-10-24
  • 打赏
  • 举报
回复
引用 7 楼 csdndenglu 的回复:
波特率够低了,是9600的。。。。。。用十六进制将数据打出来?就是cout<<hex<<a或printf(“%x",a)么???
void HexDump(char *buf,int len,int addr) { int i,j,k; char binstr[80]; for (i=0;i<len;i++) { if (0==(i%16)) { sprintf(binstr,"%08x -",i+addr); sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); } else if (15==(i%16)) { sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); sprintf(binstr,"%s ",binstr); for (j=i-15;j<=i;j++) { sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.'); } printf("%s\n",binstr); } else { sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]); } } if (0!=(i%16)) { k=16-(i%16); for (j=0;j<k;j++) { sprintf(binstr,"%s ",binstr); } sprintf(binstr,"%s ",binstr); k=16-k; for (j=i-k;j<i;j++) { sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.'); } printf("%s\n",binstr); } }
碼上道 2014-10-23
  • 打赏
  • 举报
回复
应该不是波特率的问题,按16进制方式将数据打出来看看
X MAN 2014-10-23
  • 打赏
  • 举报
回复
是不是进制转化的问题。
gogiqp_jyh 2014-10-23
  • 打赏
  • 举报
回复
http://blog.127n.com/post/6.html
加载更多回复(3)

64,691

社区成员

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

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