Modbus ascii模式 规约转换小结

  想要实现规约转换必须先得理解modbus rtu/ascii/tcp 规约. 我吃了这个亏,一开始就专注于小组的代码, 导致看了半天云里雾里, 随开始找资料, modbus规约那份pdf可以看看, 理解三点:(1) 上下行报文的概念 (2) 正常报文和异常报文 (3) RTU/ASCII报文帧之间的差别. 前面一点那份文档一点没提, 对我这种刚入行的人来说看起来不知所云. 关于理解ASCII模式, 有两份资料值得一看:Modbus读线圈命令详解还有ModBus通信规约, 电力行业的几个参数:遥信,遥测,遥控,定值,电度几个概念还有和功能码的关系需要理顺.

  在公司平台上,实现上行报文发送到平台上, 然后编写dll加载到平台程序中, dll程序的主要逻辑就是读取本地数据库sqlite3的表数据作为平台配置, 然后通过各种开发工具,例如sscom, modsim等发送上行报文到平台上, 平台实现接收数据并转发下行报文到工具上.而平台的主要逻辑是接收上行报文,并分析之, 分析方法主要是以下几个:(1)判断报文长度是否合乎规格 (正常报文和错误报文) , 不正确则返回 (2) 判断功能码是否正确(FunctionCode & 0x80 ), 不正确则按照错误报文的方式处理 ,正确按照正常报文分析各数据段 (3) 判断校验码是否正确,  CRC/LRC等 (4) 各种错误信息或者功能码打印出来, 能在平台上直观看到. 

  最重要的还是调试了, 还不是很熟练. 慢慢来....

 下行报文中需要将平台上配置信息组装成ASCII帧发下去就需要函数将一个字节的十六进制数转换成两个字节的ascii值, 实现代码如下:

//将hex转换成ascii报文
HT_UCHAR AsciitoHex(HT_UCHAR iFrame)
{
	HT_CHAR  iDecFrameH[2];
	HT_CHAR  iDecFrameL[2];
	//HT_CHAR cDecFrameH,cDecFrameL;

	HT_UCHAR iDecT,iDecH,iDecL;
	//hex>>ascii
	HT_CHAR iFrameH = (iFrame>>4)&0xF;
	HT_CHAR iFrameL = iFrame&0xF;

	if(iFrameH > 9) iFrameH = iFrameH -10 +65;
	else iFrameH = iFrameH + 48;

	if(iFrameL > 9) iFrameL = iFrameL -10 + 65;
	else iFrameL = iFrameL +48;
	
	sprintf(iDecFrameH,"%x",iFrameH);
	sscanf(iDecFrameH,"%d",&iDecH);
	sprintf(iDecFrameL,"%x",iFrameL);
	sscanf(iDecFrameL,"%d",&iDecL);

	iDecT = ( iDecH << 8 ) | iDecL;
	return iDecT;
}

一个月的总结就这么点, 确实有点丢人啊. 


你可能感兴趣的:(嵌入式开发)