英创信息技术RS485接口通讯的WinCE编程介绍

网友投稿 290 2022-11-04

英创信息技术RS485接口通讯的WinCE编程介绍

本例通过封装两个类来实现DL645通信规约,一、用于串口通信的CESerial类,完成打开、关闭串口,收发串口数据等功能。二、实现DL645规约链路层的类DL645_LCP,它提供设置通信地址,超时时间等信息,并完成通信帧的打包、解包、错误较验、数据帧收发的功能。

基于485半双工通信的特点,使用一个函数Transmit()来完成数据收发。在调用Transmit()函数发送数据后,程序并不立即返回,而是等待数据接收。一个完整的数据发送\接收过程如下:

·应用层调用DL645_LCP类的Transmit()方法,并将发送的数据传递给Transmit()。

·在Transmit()方法中对数据打包,增加帧起始符,帧结束符,校验码等信息,使其符合DL645规约。

·等待数据接收。遇下列情况之一时,函数返回:1、接收到一帧完整数据,2、接收超时,3、较验出错,4、通信出错。

下面是Transmit()函数的源代码:

int DL645_LCP::Transmit( LPSTR pDat, int DLen )

{

int i1, i2;

UCHAR WBuf[MaxWDatLen];

// fill write data

for( i1=0; i1《4; i1++ )

WBuf[i1] = 0xFE;

WBuf[i1] = 0x68;

i1++;

memcpy( &WBuf[i1], &m_LAddr, 6 );

i1 += 6;

WBuf[i1] = 0x68;

i1++;

memcpy( &WBuf[i1], pDat, 2 );

i1 += 2;

for( i2=2; i2 《 Dlen; i2++)

{

WBuf[i1] = pDat[i2] + 0x33;

i1++;

}

WBuf[i1] = GetCS( &WBuf[4], i1-4 );

i1++;

WBuf[i1] = 0x16;

i1++;

// write data

m_nDatLen = 0;

m_nUserDatLen = 0;

m_state = RevStateIDLE;

// 发送一帧数据

ceSer.WritePort( (LPSTR)WBuf, i1 );

// 等待数据接收

for(;;)

{

if( IsTimeOut() )

return ErrTimeout; // 接收超时返回

else if( m_nDatErrFlg == 1 )

return -2; // 数据出错返回

else if( m_state == RevStateEND ) // 数据接收完成返回

{

memcpy( pDat, &RBuf[8], m_nDatLen-8-2 );

return m_nUserDatLen;

}

else

{

Sleep( 5 );

}

}

}

数据接收时,CESerial类的中断处理函数收到数据,直接调用DL645_LCP类中的Receive()方法,在Receive()函数中完成一帧数据的解包工作。

void DL645_LCP::Receive( )

{

UINT i, i1;

if( m_nDatLen 《= MaxRDatLen )

{

for( i=0; i

{

SetTimeOut( m_dwTimeOut );

RBuf[m_nDatLen] = (unsigned char)ceSer.DatBuf[i];

switch( m_state )

{

case RevStateIDLE:

if( RBuf[m_nDatLen]==0x68 )

{

m_state = RevStateSTART;

m_nDatLen++;

}

break;

case RevStateSTART:

m_nDatLen++;

break;

case RevStateADDR:

if( RBuf[m_nDatLen]==0x68 )

{

m_state = RevStateSTART1;

m_nDatLen++;

}

break;

case RevStateSTART1:

m_nDatLen++;

m_state = RevStateCTRL;

break;

case RevStateCTRL:

m_nUserDatLen = RBuf[m_nDatLen];

if( m_nUserDatLen==0 ) m_state = RevStateDATA;

else m_state = RevStateDLEN;

m_nDatLen++;

break;

case RevStateDLEN:

m_nDatLen++;

if( m_nDatLen==(10+m_nUserDatLen) )

m_state = RevStateDATA;

break;

case RevStateDATA:

m_state = RevStateSUM;

if( GetCS( RBuf, m_nDatLen)!= RBuf[m_nDatLen] )

m_nDatErrFlg = 1;

m_nDatLen++;

break;

case RevStateSUM:

if( RBuf[m_nDatLen]==0x16 )

{

m_nDatLen++;

for( i1=0; i1RBuf[10+i1] -= 0x33;

m_state = RevStateEND;

}

break;

default:;

}

}

}

else m_nDatErrFlg = 1;

}

利用本文提供的例程,在DL645_LCD类上做相应的修改,可方便的实现其它的485通信规约。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:web服务之源码编译安装LAMP(编译安装PHP 解析环境)
下一篇:web服务之源码编译安装LAMP(编译安装mysqld 服务)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~