c语言写串口数据0a变成0d 0a问题

afdlig 2017-07-12 09:41:42
问题描述:
PortWrite:02 0A 50 00 00 00 00 00 00 00 00 00 00 03
PortRead:接收数据超时
经PC端调试工具调试发现接受到的数据为:02 0D 0A 50 00 00 00 00 00 00 00 00 00 00 03。故ICT板没响应(接收数据与预期不符),而终端发送数据与预期一致(aucSend,aucSend1为写入数据)。
该现象为偶现。有时候调试1天也没有出现该问题。
以下为定位该问题
源码如下:(PortWrite这类函数已封装好,用了几十年。基本可以排除底层问题)
int SP80_ICT_Commu(int nLevel)
{
char aucRead[20] = {0}, aucSend[20] = {0}, aucSend1[20] = {0};
int nLen = 0,nRet = 0, nErrFlag = 0;

//SP80与ICT通讯指令
tICTStatus.acStatus50[0] = 0x50;
memcpy(aucSend1,"\x02\x0A\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03",14);
//发送数据
memcpy(aucSend,"\x02\x0A",2);
memcpy(aucSend+2,tICTStatus.acStatus50,10);//tICTStatus.acStatus50:50 01 00 00 00 00 00 00 00 00 00
memcpy(aucSend+12,"\x00\x03",2);

SP80_ICT_COMMUM:
if((nRet = PortClrBuf(PORT_NUM_COM1)) != NDK_OK) /*清接收缓冲*/
{
cls_show_msg("line %d,nRet=%d", __LINE__, nRet);
return NDK_ERR;
}
if((nRet = PortWrite(PORT_NUM_COM1, 14, (nLevel == 1) ? aucSend : aucSend1)) != NDK_OK) /*往串口发送测试数据*/
{
cls_show_msg("line %d,nRet=%d", __LINE__, nRet);
return NDK_ERR;
}
//接收数据,2秒超时
if(((nRet = PortRead(PORT_NUM_COM1, 14, aucRead, 10*1000,&nLen)) != NDK_OK) || (nLen != 14))
{
cls_show_msg("line %d,(ret=%d)(实际%d, 预期%d)", __LINE__, nRet, nLen, 14);
cls_show_msg("nLevel = %d\n"
"aucSend=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
"aucSend1=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
"acStatus50=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
nLevel, aucSend[0],aucSend[1],aucSend[2],aucSend[3],aucSend[4],aucSend[5],aucSend[6],aucSend[7],aucSend[8],aucSend[9],aucSend[10],aucSend[11],aucSend[12],aucSend[13],
aucSend1[0],aucSend1[1],aucSend1[2],aucSend1[3],aucSend1[4],aucSend1[5],aucSend1[6],aucSend1[7],aucSend1[8],aucSend1[9],aucSend1[10],aucSend1[11],aucSend1[12],aucSend1[13],
tICTStatus.acStatus50[0],tICTStatus.acStatus50[1],tICTStatus.acStatus50[2],tICTStatus.acStatus50[3],tICTStatus.acStatus50[4],tICTStatus.acStatus50[5],tICTStatus.acStatus50[6],tICTStatus.acStatus50[7],tICTStatus.acStatus50[8],tICTStatus.acStatus50[9]);
goto SP80_ICT_COMMUM;
return NDK_ERR;
}
return NDK_OK;
}
求指教,感激不尽!!!
...全文
1242 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-07-12
  • 打赏
  • 举报
回复
不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
afdlig 2017-07-12
  • 打赏
  • 举报
回复
引用 7 楼 jha334201553 的回复:
PC端看见数据0a变成0d0a,这个怎么看见的?用串口调试工具?还是自己处理了,相信POS数据是正确的,是PC处理问题
出现超时现象再使用串口调试工具。出现超时现象代码goto回去再写入数据,只要超时就会一直循环。没出现超时现象POS与PC调试发送相同的数据就没有多出来0D
afdlig 2017-07-12
  • 打赏
  • 举报
回复
引用 5 楼 jha334201553 的回复:
打开串口是怎么打开的,打开以后数据接收到你从哪里看到数据0A变成0D0A的(是写了日志吗)?
POS与PC直接相连,发送的数据与PC上调试工具收到的数据是一致的。
「已注销」 2017-07-12
  • 打赏
  • 举报
回复
PC端看见数据0a变成0d0a,这个怎么看见的?用串口调试工具?还是自己处理了,相信POS数据是正确的,是PC处理问题
afdlig 2017-07-12
  • 打赏
  • 举报
回复
引用 5 楼 jha334201553 的回复:
打开串口是怎么打开的,打开以后数据接收到你从哪里看到数据0A变成0D0A的(是写了日志吗)?
调用NDK:int PortOpen(EM_PORT_NUM emPort, const char *pszAttr); /** *@brief 关闭串口 *@param emPort 指定的串口 *@return *@li NDK_OK 操作成功 *@li 其它EM_NDK_ERR 操作失败 硬件那边按照我们的要求做了块板子,POS终端与板子通过串口通信(压力测试)。POS写串口数据之后,每次读串口数据超时了,便把POS与PC相连接在PC端看见数据0a变成0d0a,而在POS上显示的发送数据还是0a...
「已注销」 2017-07-12
  • 打赏
  • 举报
回复
打开串口是怎么打开的,打开以后数据接收到你从哪里看到数据0A变成0D0A的(是写了日志吗)?
afdlig 2017-07-12
  • 打赏
  • 举报
回复
引用 1 楼 jha334201553 的回复:
又碰到一个,是C函数库问题,你用fopen,open等函数的之后指定b、_O_BINARY 操作不就没事了
我是做应用层的,写串口数据之后然后就读串口数据了。“你用fopen,open等函数的之后指定b、_O_BINARY 操作不就没事了”这个能麻烦解释一下吗?如何操作。我这现象是偶尔出现。求指教~~~
「已注销」 2017-07-12
  • 打赏
  • 举报
回复
\n 在windows上变成 \r\n , 在Linux下还是 \n ,在macOS 上编程 \r 写错了
「已注销」 2017-07-12
  • 打赏
  • 举报
回复
\n 在windows上变成 \r\n , 在Linux下还是 \r ,在macOS 上编程 \n 因为C语言只是说\n是换行,并没有说\n一定是 0A,然后不同系统对换行概念定义不一致
「已注销」 2017-07-12
  • 打赏
  • 举报
回复
又碰到一个,是C函数库问题,你用fopen,open等函数的之后指定b、_O_BINARY 操作不就没事了
赵4老师 2017-07-12
  • 打赏
  • 举报
回复
推荐使用portmon软件辅助调试串口通讯程序。
赵4老师 2017-07-12
  • 打赏
  • 举报
回复
他山之石,可以攻玉。
lonelyhacker 2017-07-12
  • 打赏
  • 举报
回复
串口读写问题跟fopen,open有关系吗?? POS和PC通信的时候,开个串口监控软件,监控一下就可以看到到底是哪边出的问题。 如果监控软件看到POS上发的数据是对的,那就是PC出现的问题。 如果监控软件看到POS上发的数据是不对的,那就是POS出现的问题。
afdlig 2017-07-12
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了
我是应用层的,底层的东西我也看不到。而且这套NDK用了好多年了,应该不会犯这种错误的吧。我的源码已贴出,凭着经验能看出问题来?还是说着就是底层的问题?
首先简单的说明以下I2C总线,I2C总线是一种串行数据总线,只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。在 I2C总线上传送的一个数据字节由八位组成。总线对每次传送的字节数没有限制,但每个字节后必须跟一位应答位。数据传送首先传送最高位(MSB),数据传送按图1所示格式进行。首先由主机发出启动信号“S”(SDA在SCL高电平期间由高电平跳变为低电平),然后由主机发送一个字节的数据。启动信号后的第一个字节数据具有特殊含义:高七位是从机的地址,第八位是传送方向位,0表示主机发送数据(),1表示主机接收数据(读)。被寻址到的从机设备按传送方向位设置为对应工作方式。标准I2C总线的设备都有一个七位地址,所有连接在I2C总线上的设备都接收启动信号后的第一个字节,并将接收到的地址与自己的地址进行比较,如果地址相符则为主机要寻访的从机,应在第九位答时钟脉冲时向SDA线送出低电平作为应答。除了第一字节是通用呼叫地址或十位从机地址之外第二字节开始即数据字节。数据传送完毕,由主机发出停止信号“P”(SDA在SCL高电平期间由低电平跳变为高电平)。   AT24C系列串行E2PROM具有I2C总线接口功能,功耗小,宽电源电压(根据不同型号2.5V~6.0V),工作电流约为3mA,静态电流随电源电压不同为30μA~110μA,AT24C系列串行E2PROM参数如下 型 号 容 量 器件寻址字节(8位) 一次装载字节数 AT24C01 128×8 1010A2A1A0 R/W 4 AT24C02 256×8 1010A2A1A0 R/W 8 AT24C04 512×8 1010A2A1P0 R/W 16 AT24C08 1024×8 1010A2P1P0 R/W 16 AT24C16 2048×8 1010P2P1P0 R/W 16   由于I2C总线可挂接多个串行接口器件,在I2C总线中每个器件应有唯一的器件地址,按I2C总线规则,器件地址为7位数据(即一个I2C总线系统中理论上可挂接128个不同地址的器件),它和1位数据方向位构成一个器件寻址字节,最低位D0为方向位(读/)。器件寻址字节中的最高4位(D7~D4)为器件型号地址,不同的I2C总线接口器件的型号地址是厂家给定的,如AT24C系列E2PROM的型号地址皆为1010,器件地址中的低3位为引脚地址A2 A1 A0,对应器件寻址字节中的D3、D2、D1位,在硬件设计时由连接的引脚电平给定。   对AT24C系列 E2PROM的读操作完全遵守I2C总线的主收从发和主发从收的规则。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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