在工业控制场合,rs485总线因其接口简单,组网方便,传输距离远等特点而得到广泛应用。rs485和rs232一样都是基于串口的通讯接口,数据收发的操作是一致的,所以使用的是同样wince的底层驱动程序。但是它们在实际应用中通讯模式却有着很大的区别,rs232接口为全双工数据通讯模式,而rs485接口为半双工数据通讯模式,数据的收发不能同时进行,为了保证数据收发的不冲突,硬件上是通过方向切换来实现的,相应也要求软件上必须将收发的过程严格地分开。wince是一个多线程实时操作系统,rs232通信数据收发可在不同线程中同时进行,而对于rs485就不能采用这种方式,必须按照一定的流程来实现rs485所要求的通讯过程。大多数的rs485通讯采用主从通讯方式,在本文中将以电力系统中常用的dl/t 645多功能电能表通信规约为例,来说明rs485半双工通讯的wince编程要点。
本例通过封装两个类来实现dl645通信规约,一、用于串口通信的ceserial类,完成打开、关闭串口,收发串口数据等功能。二、实现dl645规约链路层的类dl645_lcp,它提供设置通信地址,超时时间等信息,并完成通信帧的打包、解包、错误较验、数据帧收发的功能。
基于485半双工通信的特点,使用一个函数transmit()来完成数据收发。在调用transmit()函数发送数据后,程序并不立即返回,而是等待数据接收。一个完整的数据发送\接收过程如下:
·应用层调用dl645_lcp类的transmit()方法,并将发送的数据传递给transmit()。
·在transmit()方法中对数据打包,增加帧起始符,帧结束符,校验码等信息,使其符合dl645规约。
·调用串口通信ceserial类的writeport()方法函数,发送一帧数据。
·等待数据接收。遇下列情况之一时,函数返回: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_ndaterrflg = 0;
m_nuserdatlen = 0;
m_state = revstateidle;
// 发送一帧数据
ceser.writeport( (lpstr)wbuf, i1 );
settimeout( m_dwtimeout );
// 等待数据接收
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++;
if( m_ndatlen==7 ) m_state = revstateaddr;
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通信规约。
中天科技5G天线产品开始小批量试制
可以检测和连续测量的电容式接近开关优缺点
未来10年 边境与海上安全市场将从192.2亿美元增长到352.2亿美元
“618真香机” realme X系列产品6月1日0点全面开售
御芯微WIoTa通信协议助力物联网行业新发展
英创信息技术RS485接口通讯的WinCE编程介绍
OPPO在法国正式发布传闻已久的旗舰新机Find X
以太坊的未来发展之路探讨
一文解读can总线技术的发展现状与应用
MWC|全球首个!5G智慧码头将在青岛首次建成亮相!
芯驰科技助力车企及Tier1智能驾驶相关项目的快速落地量产
首次!中国科学家斩获2020世界航天奖
小米发布无线充电宝,颜值高且支持双向18W快充
苹果发布会:iPhone 13的价格是真的香
ARM安全架构之Trustzone-TEE
有哪些Python编辑器可以在平板电脑上使用
中国移动5G联合创新中心已经发展超过200家合作伙伴
活动邀请|2021研华嵌入式设计论坛报名开启中,诚邀您参加!
Marvell与Cree推出60瓦可调光A19 LED灯参考设计
蔚来ET9于2023 NIO DAY盛典亮相,定位高端行政四座轿车